>dump() function Chrono() { this.reset(); } Chrono.prototype.reset = function () { this.nleaps=0; this.duration=0; this.notMeasuredStart=getTime(); this.durationNotMeasured=0; }; Chrono.prototype.start = function () { this.startTime= getTime(); this.durationNotMeasured+=this.startTime-this.notMeasuredStart; }; Chrono.prototype.leap = function () { this.nleaps++; }; Chrono.prototype.stop = function () { this.notMeasuredStart=getTime(); this.duration+=this.notMeasuredStart-this.startTime; }; Chrono.prototype.meanLeap = function () { return this.duration/this.nleaps; }; Chrono.prototype.info = function () { console.log( this.nleaps+" leaps (mean time "+this.meanLeap()+" s). Measured duration/Total duration "+(100*this.duration/(this.duration+this.durationNotMeasured)).toFixed(2)+"%"); }; Chrono.prototype.toString = function () { return "Chronometer analysed "+this.nleaps+" leaps with a duration of "+this.duration+" (mean leap time "+this.meanLeap()+" s). Measured time/Total time "+(100*this.duration/(this.duration+this.durationNotMeasured)).toFixed(2)+"%"; }; function nmea_checksum(s) { try { var n=s.split('$').pop(); // remove leading uncomplete sentences AND the no more usefull leading $ n=n.split('*'); // separate checksum from line var cksum = parseInt(n.pop(),16); // make checksum a number and remove it from n n=n.pop(); // keep content alone if (cksum===cks7(n)) // mean leap 0.02532994300 s return n.split(','); // mean leap 0.01426320198 s else { throw "different checksums "+cks7.toString(16)+" versus "+cks7(n).toString(16)+" in line "+s ; } } catch(x) { throw "Checksum error "+x+' in sentence '+s; } } function start_stop_nmea(serial,nmea_msg_list,keep_serial,keep_usb) { // so GLL, ZDA etc... if (nmea_msg_list===undefined) return; serial.print(0xff); // force wake up of the module console.log('Now stopping the GPS from sending the following messages '); var timeout= setTimeout(function (s, lst, ks, ku) { var msg_pref="PUBX,40,"; var msg_suff=((ks) ? "1" : "0")+",0,0,"+((ku) ? "1" : "0")+",0,0"; for (var i in lst) { var m=lst[i]; if (m.length===5) m=m.substr(2,3); else // special case for PUBX m=m.substr(4,2); m=msg_pref+m+","+msg_suff; m="$"+m+"*"+("0"+(cks7(m)).toString(16)).substr(-2).toUpperCase(); console.log((ks ? 'Starting' : 'Stopping' ),lst[i],'nmea sentence send by ublox gps with', m); s.println(m); } }, 500, serial, nmea_msg_list, keep_serial, keep_usb); // send command after half a second to allow for module wakeup } var fieldsOfInterest = [ "latitude", "longitude", "hhmmss.ss", "ddmmyy", "mslAlt", "sogKn", "status", "std_lat", "std_long", "std_alt" ]; function codeFieldOfInterest(n) { var c="this['"+n.field+"']="; var i=n.position; switch(n.field) { case 'latitude' : return c+"lln(d["+i+"],d["+(i+1)+"],'S')"; case 'longitude' : return c+"lln(d["+i+"],d["+(i+1)+"],'E')"; case 'ddmmyy' : return c+"ddmmyy(d["+i+"])"; case 'hhmmss.ss' : return c+"secn(d["+i+"])"; case 'status' : case 'NavStat': case 'Valid': return c+"d["+i+"]"; default: return c+"Number(d["+i+"])"; } } function posFieldsOfInterest(p,c,i) { try { if (fieldsOfInterest.indexOf(c)>=0) { try { p.push({ field: c, position: i}); } catch (e) { console.log(e); console.log(p,c,i); } } } catch(x) { console.log(x); } return p; } function getFieldsPos(n) { this[n.field]=n.position; } function parseHandlers(handling,serial,fieldsOfInterest) { var handlers = {}; handlers.serial=serial; var discarded=[]; var fieldsFoundInNMEA=[]; for (var k in handling) { var template=handling[k].split(','); if (template[0]==="PUBX") { // special case: we have to add to s[1] field template[0]=template[0]+template[1]; template[1]="NumUBX"; } if (handlers[template[0]]) { console.log("ERROR Handler of "+handling[k][0]+" defined twice with sumindex "+template[0]+"..."); } else { // now extract particular fields of interest var posi=template.reduce(posFieldsOfInterest ,[]); if (posi.length>0) { // now note which field is found in which nmea sentence and at which position by field order //var fieldsFoundInTemplate={}; //posi.forEach(getFieldsPos ,fieldsFoundInTemplate); posi=posi.map(codeFieldOfInterest).join(';'); handlers[template[0]]= eval("(function(d) {"+posi+"})"); // function to handle just what we need console.log('Handler of '+template[0]+' defined as '+handlers[template[0]]); } else discarded.push(template[0]); } } // now we now we have just the messages containing pertinent data // however, we could have redundant messages and need to identify them all var retained=[]; // so far nithing retained start_stop_nmea(serial,discarded,0,1); return handlers; } function estimate_dist(lat1,long1,lat2,long2) { var R=6378137.0; var dera = Math.PI/180.0; var x = dera*(lat2-lat1) * Math.cos(dera*(long1+long2)/2); var y = dera*(long2-long1); return Math.sqrt(x*x + y*y) * R; } var tfTimeout = 2; function tf(d) { console.log('Received a TimeFix event with parameter '+d); gps.epoch=gps.ddmmyy+gps['hhmmss.ss']*1000; var deltat=getTime()*1000-gps.epoch; if ((deltat<0-1000) || (deltat>1000)) { setTime(gps.epoch/1000); // Now setup system time to gps time (there is a lag) console.log('Internal clock set to gps time '+new Date().toString()+' with a delta time of '+deltat+' ms'); } else { console.log('Internal clock was only '+deltat+' ms from GPS epoch '+new Date(gps.epoch).toString()+' so no changes were made.'); } // Remove this listener for some time, say 1 hour gps.removeAllListeners('TimeFix'); tfTimeout=setTimeout(function (){ gps.on('TimeFix',tf); // reconnect after on hour },3600000); } function connect(serial,handling,chrono) { // replace with next line for module // exports.connect = function(serial, handling) { var gps = parseHandlers(handling,serial); gps.line=""; gps.enabled=true; gps.log=false; gps.debug=false; gps.chrono=chrono; gps.lagTime = 0; gps.status="?"; gps['hhmmss.ss']=NaN; // user callback for gps position fix gps.on('GPSFix', function(d){ console.log("We have a GPS position fix!"); }); // user callback for gps data received and analysed gps.on('gpsdata', function(d) { try { gps.lagTime=getTime()-d; if (gps.log) { console.log('Data received from GPS, receive treatement ended at '+d+" and user's treatement starting after ",gps.lagTime+' s'); } } catch(x) { console.log(x); } }); gps.on('TimeFix',tf); serial.on('data', function(data) { if (gps.enabled) { gps.chrono.start(); var sots = false; var noTimeFix= isNaN(gps['hhmmss.ss']); var noPosFix= (gps.status!=="A"); gps.line += data; var idx = gps.line.indexOf("\n"); while (idx>=0) { var line = gps.line.substr(0, idx); gps.line = gps.line.substr(idx+1); if (gps.log) console.log("Handling:"+line); try { var n=nmea_checksum(line); gps[n[0] + ((n[0]==="PUBX") ? n[1] : "")](n); sots = true; if (noTimeFix != isNaN(gps['hhmmss.ss'])) { console.log('Time fix from serial at '+getTime()); gps.emit('TimeFix',n); noTimeFix= isNaN(gps['hhmmss.ss']); } if (noPosFix != (gps.status!=="A")) { console.log('GPS position fix from serial at '+getTime()); gps.emit('GPSFix',n); noPosFix= (gps.status!=="A"); } gps.chrono.leap(); } catch(x) { if (gps.debug) console.log("Failed "+x+" to handle:"+line); //throw x; } idx = gps.line.indexOf("\n"); } if (sots) { gps.emit('gpsdata',getTime()); } gps.chrono.stop(); } else { gps.line=""; } }); return gps; } var gps = { "serial": Serial4, "GPGGA": function (d) {this['hhmmss.ss']=secn(d[1]);this['latitude']=lln(d[2],d[3],'S');this['longitude']=lln(d[4],d[5],'E');this['mslAlt']=Number(d[9])}, "GPRMC": function (d) {this['hhmmss.ss']=secn(d[1]);this['status']=d[2];this['latitude']=lln(d[3],d[4],'S');this['longitude']=lln(d[5],d[6],'E');this['sogKn']=Number(d[7]);this['ddmmyy']=ddmmyy(d[9])}, "GPGBS": function (d) {this['hhmmss.ss']=secn(d[1]);this['std_lat']=Number(d[2]);this['std_alt']=Number(d[4])}, "line": "", "enabled": true, "log": true, "debug": false, "chrono": { "nleaps": 76114, "duration": 1404.92071819305, "notMeasuredStart": 1442595816.00444412231, "durationNotMeasured": 24096.32186126708, "startTime": 1442595815.99214839935 }, "lagTime": 0.04415130615, "status": "V", "hhmmss.ss": 61374.04, "#onGPSFix": function (d) { console.log("We have a GPS position fix!"); }, "#ongpsdata": function (d) { try { gps.lagTime=getTime()-d; if (gps.log) { console.log('Data received from GPS, receive treatement ended at '+d+" and user's treatement starting after ",gps.lagTime+' s'); } } catch(x) { console.log(x); } }, "latitude": NaN, "longitude": NaN, "sogKn": 0, "ddmmyy": 1442534400000, "mslAlt": 0, "std_lat": 0, "std_alt": 0, "epoch": 1442570315000, "#onTimeFix": function (d) { console.log('Received a TimeFix event with parameter '+d); gps.epoch=gps.ddmmyy+gps['hhmmss.ss']*1000; var deltat=getTime()*1000-gps.epoch; if ((deltat<0-1000) || (deltat>1000)) { setTime(gps.epoch/1000); // Now setup system time to gps time (there is a lag) console.log('Internal clock set to gps time '+new Date().toString()+' with a delta time of '+deltat+' ms'); } else { console.log('Internal clock was only '+deltat+' ms from GPS epoch '+new Date(gps.epoch).toString()+' so no changes were made.'); } // Remove this listener for some time, say 1 hour gps.removeAllListeners('TimeFix'); tfTimeout=setTimeout(function (){ gps.on('TimeFix',tf); // reconnect after on hour },3600000); } }; var seconds = 240; var i = "JSON"; var myInterval = 3; function show(d) { for (var i in d) print(i+" : "+E.getSizeOf(d[i])) } setInterval(function () { if (process.memory().free<500) debugger; }, 10000); setDeepSleep(1); Serial4.on('data', function (data) { if (gps.enabled) { gps.chrono.start(); var sots = false; var noTimeFix= isNaN(gps['hhmmss.ss']); var noPosFix= (gps.status!=="A"); gps.line += data; var idx = gps.line.indexOf("\n"); while (idx>=0) { var line = gps.line.substr(0, idx); gps.line = gps.line.substr(idx+1); if (gps.log) console.log("Handling:"+line); try { var n=nmea_checksum(line); gps[n[0] + ((n[0]==="PUBX") ? n[1] : "")](n); sots = true; if (noTimeFix != isNaN(gps['hhmmss.ss'])) { console.log('Time fix from serial at '+getTime()); gps.emit('TimeFix',n); noTimeFix= isNaN(gps['hhmmss.ss']); } if (noPosFix != (gps.status!=="A")) { console.log('GPS position fix from serial at '+getTime()); gps.emit('GPSFix',n); noPosFix= (gps.status!=="A"); } gps.chrono.leap(); } catch(x) { if (gps.debug) console.log("Failed "+x+" to handle:"+line); //throw x; } idx = gps.line.indexOf("\n"); } if (sots) { gps.emit('gpsdata',getTime()); } gps.chrono.stop(); } else { gps.line=""; } }); Serial4.setup(115200, {"tx":C10,"rx":C11}); pinMode(C11,"input_pullup"); =undefined