Most recent activity
-
-
-
File not uploaded, so I copied the code here.
Please find here the example firmware//================================================================================== // Copyright (c) 2014 Giovanni Varasano. // v4 - last update 06/06/2014 // ================================================================================== var fs = require("fs"); var ST = { IDLE: 0, FIX:1, RUN:2 }; tmrId=0; file_ok=0, gps_ok = 0; gps_path=""; gps_date= "", gps_time=""; gps_msec=0; gps_lat=0, gps_lon=0, gps_speed =0; gps_course=0; ir_red=0.0,ir_nir=0.0,irr_edg=0.0,ir_ndre=0.0,ir_ndvi=0.0; //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- var WORK = LED2; var FIX = LED3; var STOP = LED4; // --------------------------------------------------------- // --------------------------------------------------------- btn_state = false; var btn_id = setWatch(function(e) { btn_state = !btn_state; } ,B6,{ repeat : true, edge : "both", debounce : 350}); //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function onInit() { setTimeout(function(){ file_ok=0, gps_ok = 0; Serial6.setup(19200, {rx:C7,tx:C6}); Serial6.print("$JBAUD,115200\r\n"); setTimeout(function(){ Serial6.setup(115200, {rx:C7,tx:C6}); Serial4.setup(38400, {rx:C11,tx:C10}); tracking("RMC"); tracking("GGA"); tmrId = go_ahead(); }, 3000 ); }, 2000 ); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function go_ahead() { state=ST.IDLE return setInterval( function() { switch(state) { case ST.IDLE: file_ok=0;STOP.set();FIX.reset();WORK.reset(); if (btn_state ) { STOP.reset(); state=ST.FIX; } break; case ST.FIX: if (!btn_state ) { state=ST.IDLE } FIX.set(); if(file_ok === 1) {FIX.reset();state=ST.RUN;work=WORK.startFlashing(250);} break; case ST.RUN: if (!btn_state ) {state=ST.IDLE; WORK.stopFlashing(work);} save_data(); break; } },50); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function save_data() { if ( gps_ok ) { var s_data = gps_date+","+gps_time+"."+gps_msec+","+gps_speed+","+gps_course+","; s_data += utm.toString()+","+ir_red+","+ir_nir+","+irr_edg+","+ir_ndre+","+ir_ndvi+"\r\n"; fs.appendFileSync(gps_path,s_data); gps_ok=0; } } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function LatLng(lat,lng,alt) { this.lat = lat; this.lng = lng; this.alt = alt; this.toUTMRef = LatLngToUTMRef; this.toString = LatLngToString; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function LatLngToString() { return "(" + this.lat + ", " + this.lng + ")"; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function UTMRef(easting, northing, altitude, latZone, lngZone) { this.easting = Number(easting).toFixed(3); this.northing = Number(northing).toFixed(3); this.altitude = Number(altitude).toFixed(3); this.latZone = latZone; this.lngZone = lngZone; this.toString = UTMRefToString; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function UTMRefToString() { return this.easting + "," + this.northing+ ","+this.altitude+","+this.latZone+this.lngZone+""; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function RefEll(maj, min) { this.maj = maj; this.min = min; this.ecc = ((maj * maj) - (min * min)) / (maj * maj); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function LatLngToUTMRef() { var wgs84 = new RefEll(6378137, 6356752.314); var UTM_F0 = 0.9996; var a = wgs84.maj; var eSquared = wgs84.ecc; var longitude = this.lng; var latitude = this.lat; var altitude = this.alt; var latitudeRad = latitude * (Math.PI / 180.0); var longitudeRad = longitude * (Math.PI / 180.0); var longitudeZone = Math.floor((Number(longitude) + 180.0) / 6.0) + 1; if (latitude >= 56.0 && latitude < 64.0 && longitude >= 3.0 && longitude < 12.0) { longitudeZone = 32; } if (latitude >= 72.0 && latitude < 84.0) { if (longitude >= 0.0 && longitude < 9.0) { longitudeZone = 31; } else if (longitude >= 9.0 && longitude < 21.0) { longitudeZone = 33; } else if (longitude >= 21.0 && longitude < 33.0) { longitudeZone = 35; } else if (longitude >= 33.0 && longitude < 42.0) { longitudeZone = 37; } } var longitudeOrigin = (longitudeZone - 1) * 6 - 180 + 3; var longitudeOriginRad = longitudeOrigin * (Math.PI / 180.0); var UTMZone = getUTMLatitudeZoneLetter(latitude); ePrimeSquared = (eSquared) / (1 - eSquared); var n = a / Math.sqrt(1 - eSquared * Math.sin(latitudeRad) * Math.sin(latitudeRad)); var t = Math.tan(latitudeRad) * Math.tan(latitudeRad); var c = ePrimeSquared * Math.cos(latitudeRad) * Math.cos(latitudeRad); var A = Math.cos(latitudeRad) * (longitudeRad - longitudeOriginRad); var M = a * ( (1 - eSquared / 4 - 3 * eSquared * eSquared / 64 - 5 * eSquared * eSquared * eSquared / 256) * latitudeRad - (3 * eSquared / 8 + 3 * eSquared * eSquared / 32 + 45 * eSquared * eSquared * eSquared / 1024) * Math.sin(2 * latitudeRad) + (15 * eSquared * eSquared / 256 + 45 * eSquared * eSquared * eSquared / 1024) * Math.sin(4 * latitudeRad) - (35 * eSquared * eSquared * eSquared / 3072)* Math.sin(6 * latitudeRad)); var UTMEasting = (UTM_F0 * n * (A + (1 - t + c) * Math.pow(A, 3.0) / 6 + (5 - 18 * t + t * t + 72 * c - 58 * ePrimeSquared) * Math.pow(A, 5.0) / 120) + 500000.0); var UTMNorthing = (UTM_F0 * (M + n * Math.tan(latitudeRad) * (A * A / 2 + (5 - t + (9 * c) + (4 * c * c)) * Math.pow(A, 4.0) / 24 + (61 - (58 * t) + (t * t) + (600 * c) - (330 * ePrimeSquared)) * Math.pow(A, 6.0) / 720)) ); if (latitude < 0) { UTMNorthing += 10000000.0; } return new UTMRef(UTMEasting, UTMNorthing, altitude, UTMZone, longitudeZone); } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- function getUTMLatitudeZoneLetter(latitude) { if ((84 >= latitude) && (latitude >= 72)) return "X"; else if (( 72 > latitude) && (latitude >= 64)) return "W"; else if (( 64 > latitude) && (latitude >= 56)) return "V"; else if (( 56 > latitude) && (latitude >= 48)) return "U"; else if (( 48 > latitude) && (latitude >= 40)) return "T"; else if (( 40 > latitude) && (latitude >= 32)) return "S"; else if (( 32 > latitude) && (latitude >= 24)) return "R"; else if (( 24 > latitude) && (latitude >= 16)) return "Q"; else if (( 16 > latitude) && (latitude >= 8)) return "P"; else if (( 8 > latitude) && (latitude >= 0)) return "N"; else if (( 0 > latitude) && (latitude >= -8)) return "M"; else if (( -8 > latitude) && (latitude >= -16)) return "L"; else if ((-16 > latitude) && (latitude >= -24)) return "K"; else if ((-24 > latitude) && (latitude >= -32)) return "J"; else if ((-32 > latitude) && (latitude >= -40)) return "H"; else if ((-40 > latitude) && (latitude >= -48)) return "G"; else if ((-48 > latitude) && (latitude >= -56)) return "F"; else if ((-56 > latitude) && (latitude >= -64)) return "E"; else if ((-64 > latitude) && (latitude >= -72)) return "D"; else if ((-72 > latitude) && (latitude >= -80)) return "C"; else return 'Z'; } // ----------------------------------------------------------- // -------------------------------------------------- var Checksum = function(sentence, checksum) { var q, c1, c2, i; i = 1; c1 = sentence.charCodeAt(i); for( i = 2; i < sentence.length; ++i) { c1 = c1 ^ sentence.charCodeAt(i); } c2 = parseInt(checksum, 16); return (c1 === c2); }; // ----------------------------------------------------------- // -------------------------------------------------- var m_hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; // ----------------------------------------------------------- // -------------------------------------------------- var toHexString = function(v) { var lsn, msn; msn = (v >> 4) & 0x0f; lsn = (v >> 0) & 0x0f; return m_hex[msn] + m_hex[lsn]; }; // ----------------------------------------------------------- // -------------------------------------------------- var computeChecksum = function(sentence) { var c1; var i; i = 1; c1 = sentence.charCodeAt(i); for( i = 2; i < sentence.length; ++i) { c1 = c1 ^ sentence.charCodeAt(i); } return '*' + toHexString(c1); }; // ----------------------------------------------------------- // ----------------------------------------------------------- function handleGPSLine(line ,callback) { var c = line.split("*"); if ( Checksum(c[0],c[1]) ) { var tag = line.substr(3,3); var d = line.split(","); if (tag=="GGA") { var dlat = d[2].indexOf("."); var dlon = d[4].indexOf("."); callback({ tag : tag, time : d[1].substr(0,2)+":"+d[1].substr(2,2)+":"+d[1].substr(4,2), msec : (parseInt(d[1].substr(7,2),10)*10), lat : ((parseInt(d[2].substr(0,dlat-2),10)+parseFloat(d[2].substr(dlat-2))/60)*(d[3]=="S"?-1:1)).toFixed(9), lon : ((parseInt(d[4].substr(0,dlon-2),10)+parseFloat(d[4].substr(dlon-2))/60)*(d[5]=="W"?-1:1)).toFixed(9), fix : parseInt(d[6],10), alt : parseFloat(d[9]) }); } if (tag=="RMC") { callback({ tag : tag, time : d[1].substr(0,2)+":"+d[1].substr(2,2)+":"+d[1].substr(4,2), valid : d[2], speed : parseFloat(d[7])*1.852, course : parseFloat(d[8]), date : d[9].substr(0,2)+"/"+d[9].substr(2,2)+"/"+d[9].substr(4,2), path : d[9].substr(4,2)+d[9].substr(2,2)+d[9].substr(0,2)+"_"+d[1].substr(0,2)+d[1].substr(2,2)+".txt" }); } } } // ----------------------------------------------------------- // -------------------------------------------------- function fix_gps_data(data) { if ( data.fix > 0 ) { gps_ok = 1; gps_time=data.time; gps_msec=data.msec; gps_lat=data.lat; gps_lon=data.lon; var ll = new LatLng(data.lat,data.lon,data.alt); utm = ll.toUTMRef(); } else { gps_ok = 0; } } // ----------------------------------------------------------- // -------------------------------------------------- function get_gps_data(data) { if(data.tag == "GGA" ) { fix_gps_data(data); } if(data.tag == "RMC" ) { fix_data(data); } } // ----------------------------------------------------------- // ----------------------------------------------------------- function fix_data(data) { if ( data.valid=="A" ) { if ( file_ok === 0) { file_ok=1; gps_date = data.date; gps_path = data.path; var head = "# File: "+gps_path+" created on "+data.date+" "+data.time+"\r\n"; fs.appendFileSync(gps_path,head); } gps_speed = data.speed; gps_course = data.course; } } // ----------------------------------------------------------- // -------------------------------------------------- function fix_irs_data(data) { ir_red = data.red; ir_nir = data.nir; irr_edg = data.red_edg; ir_ndre = data.ndre; ir_ndvi = data.ndvi; } // --------------------------------------------------- // // -------------------------------------------------- function handleIRSLine(line ,callback) { var d = line.split(","); callback({ red : parseFloat(d[0]), nir : parseFloat(d[1]), red_edg : parseFloat(d[2]), ndre : parseFloat(d[3]), ndvi : parseFloat(d[4]) }); } // ----------------------------------------------------------- // -------------------------------------------------- Serial6.onData(function (e) { if (e.data=="\n") { var line = gpsLine; gpsLine=""; handleGPSLine(line ,function(data) { get_gps_data(data); } ); } else gpsLine+=e.data; } ); // ----------------------------------------------------------- // -------------------------------------------------- Serial4.onData(function (e) { if (e.data=="\n") { var line = irsLine; irsLine=""; handleIRSLine(line ,function(data) { fix_irs_data(data); } ); } else irsLine+=e.data; } ); // -------------------------------------- // -------------------------------------- var tracking = function(cmd ) { var str = "$J"; if (cmd =="GGA" ) { str += "ASC,GP"+cmd+",10"; } else if ( cmd == "RMC" ) { str += "ASC,GP"+cmd+",1"; } else { } if (cmd == "OFF") { str += cmd; } str += "\r\n"; Serial6.print(str); }; // ---------------------------------------------- // ---------------------------------------------- Pin.prototype.startFlashing = function(period) { var on = false; var pin = this; return setInterval(function() { on = !on; digitalWrite(pin, on); }, period); }; // ---------------------------------------------- // ---------------------------------------------- Pin.prototype.stopFlashing = function(stop ) { var pin = this; clearInterval(stop);digitalWrite(pin,0); }; onInit();
-
-
-
You can use a moving average with an interval of 8 or 16 samples .
I used the following code to get stable readings from a 10-bit encoder.
Using the dithered noise resolution is in fact improved to 1 1bits.setInterval(function() { enc_deg = sma16(degree(C1).toFixed(1)); // console.log("Encoder Angle[°] = "+enc_deg.toFixed(1)); }, 100 ); function degree( pin ) { var ratio = 4.0; var offset = 0.5; var factor = 0.73333333333; var phys = analogRead(pin) * 3.3; // *E.getAnalogVRef(); var meas = 360.0 * ( phys / factor - offset ) / ratio ; console.log("Input[V] = "+phys.toFixed(3)+" Angle[°] = "+meas.toFixed(1)); return meas; } // ------------------------------------ // simple parametric moving averager // ------------------------------------ function sma(period) { var nums = []; return function(num) { nums.push(num); if (nums.length > period) nums.splice(0,1); var sum = 0; var n = period; function sum_num (n) { sum+=Number(n); }; nums.forEach(sum_num); if (nums.length < period) n = nums.length; return(sum/n); } } var sma16 = sma(16);
Input[V] = 0.494 Angle[°] = 15.6 Next reading = 15.6, SMA = 15.6
Input[V] = 0.496 Angle[°] = 15.9 Next reading = 15.9, SMA = 15.7
Input[V] = 0.495 Angle[°] = 15.8 Next reading = 15.8, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.8 Next reading = 15.8, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.7 Next reading = 15.7, SMA = 15.7
Input[V] = 0.498 Angle[°] = 16.1 Next reading = 16.1, SMA = 15.8
Input[V] = 0.497 Angle[°] = 16.0 Next reading = 16.0, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.7 Next reading = 15.7, SMA = 15.8
Input[V] = 0.496 Angle[°] = 15.9 Next reading = 15.9, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.7 Next reading = 15.7, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.7 Next reading = 15.7, SMA = 15.8
Input[V] = 0.494 Angle[°] = 15.6 Next reading = 15.6, SMA = 15.8
Input[V] = 0.494 Angle[°] = 15.6 Next reading = 15.6, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.8 Next reading = 15.8, SMA = 15.8
Input[V] = 0.495 Angle[°] = 15.7
I did a check executing a same program from ( downloading from the Web IDE ) or from FLASH using the USB console.
I obtained that the version executed after downloading from Flash onInit() runs twice as much as it would.
I set a led flashing at 1 Hz.
It flashed at 1 Hz when executing after a reset() and at 2Hz when executing after onInit()
The same happens for characters received fron an external part and sampled every 100 ms in a state machine loop.
IS there a reason for this behaviour ?
Thanks in advance for the reply.
Please find attached below the profiling.