7 Replies Latest reply on Dec 25, 2015 6:36 AM by KimLorentz

    Read/Write to Serial Port - JavaScript (help)

    KimLorentz

      I got an javascript reading GPS data from an Arduino GPS board.

      Reading the GPS data is ok, I cant send data to the GPS unit to change the data output from the GPS unit.

       

      EdisonTracker.jpg

       

      what can I do?

       

      Here is my code.

       

      var m = require('mraa'); //require mraa
      var fs = require('fs'); // require filesystem
      
      
      u = new m.Uart(0);              // /dev/ttyMFD1
      console.log(u.getDevicePath());
      
      var SerialPort = require("serialport").SerialPort; // npm install serialport
      var serialPort = new SerialPort("/dev/ttyMFD1", {
        baudrate: 9600
      });
      
      
      // Program GPS module
      
      serialPort.on('write', writeData);
      
      function writeData(){
        serialPort.write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28");  // RMC and GGA
      }
      
      // receive GPS (approx every second)
      
      serialPort.on("open", function () {
        console.log('GET GPS data');
        serialPort.on('data', function(data) {
            var data_string = '' + data
            //console.log(data_string);
            if (data_string.substring(0,6) == '$GPGGA') {
                gpgga_string = data_string.split('\n')[0];
                gpgga_string = gpgga_string.replace('\n', '');
                gps_data = gpgga_string.split(',');
                console.log('data received: ' + gps_data);
                var time_string = gps_data[1];
                var gps_time = new Date();
                var gps_time_hours = parseInt(gps_data[1].substring(0,2));
                var gps_time_minutes = parseInt(gps_data[1].substring(2,4));
                var gps_time_seconds = parseInt(gps_data[1].substring(4,6));
                gps_time.setHours(gps_time_hours);
                gps_time.setMinutes(gps_time_minutes);
                gps_time.setSeconds(gps_time_seconds);
              
                gps_lat = gps_data[2];
                gps_lat_ns = gps_data[3];
                gps_lon = gps_data[4];
                gps_lon_ew = gps_data[5];
                gps_pos_fix = gps_data[6];
                gps_satt_qty = gps_data[7];
                gps_hdop = gps_data[8];
                gps_msl_alt = gps_data[9];
                gps_unit = gps_data[10];
                gps_geo = gps_data[11];
                gps_geo_unit = gps_data[12];
              
                if (gps_pos_fix == '1') {
                    console.log('GPS Fixed');
                    console.log('Time: ', gps_time);
                    console.log('Position: ' + gps_lat + gps_lat_ns + ',' + gps_lon + gps_lon_ew);
                    console.log('Altitude: ' + gps_msl_alt + 'M' + ' +/- ' + gps_hdop + 'M');
                    console.log('Satellites Qty: ' + gps_satt_qty + '\n');
                }
              
                if (gps_pos_fix == '0') {
                    console.log('No GPS Fix');
                }
              
              //  console.log('GPS Fix: ' + gps_fix_stat);
              //  console.log('Time: ', gps_time);
              //  console.log('Position: ' + gps_lat + gps_lat_ns + ',' + gps_lon + gps_lon_ew);
              //  console.log('Altitude: ' + gps_geo + 'M' + ' +/- ' + gps_hdop + 'M');
              //  console.log('Satellites Qty: ' + gps_satt_qty + '\n');
      
            }
             
        });
      });
      
      
      // NOTE:
      // such as the awesome http://www.hhhh.org/wiml/proj/nmeaxor.html
      //#define PMTK_SET_NMEA_UPDATE_1HZ  "$PMTK220,1000*1F"
      //#define PMTK_SET_NMEA_UPDATE_5HZ  "$PMTK220,200*2C"
      //#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
      //#define PMTK_SET_BAUD_57600 "$PMTK251,57600*2C"
      //#define PMTK_SET_BAUD_9600 "$PMTK251,9600*17"
      // standby command & boot successful message
      //#define PMTK_STANDBY "$PMTK161,0*28"
      //#define PMTK_STANDBY_SUCCESS "$PMTK001,161,3*36"  // Not needed currently
      
      
      // turn on only the second sentence (GPRMC)
      //#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
      // turn on GPRMC and GGA
      //#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
      // turn on ALL THE DATA
      //#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
      // turn off output
      //#define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
      
      
      //Active Interference Cancellation (AIC) - gives better navigation quality
      //$PMTK286,1*23 - Enable
      //$PMTK286,0*22 - Disable
      
      
      
        • 1. Re: Read/Write to Serial Port
          PabloM_Intel

          Hi KimLorentz,

           

          Could you please tell me which GPS module you are using so I can look for the datasheet? Also, is it ok that the last part of the code is commented out? Is there a reason for this?

           

          Regards,

          PabloM_Intel

          • 2. Re: Read/Write to Serial Port
            KimLorentz

            The last part is only for notes.

            Got the notes from reading the Adafruit Ultimate GPS lib.

            The chips name is MT3339. Datasheet http://www.adafruit.com/datasheets/PMTK_A11.pdf

             

            It communicate true Serial data at baud rate 9600

            • 3. Re: Read/Write to Serial Port - JavaScript (help)
              KimLorentz

              I am gething closer to the end, I am able to read the GGA data, but now I want to read the GGA and RMC data, got any hints??

               

               

              Using an Level shifter did not work, probably wrong connections, sow I programmed the Sparkfun Arduino board.

               

              Sparkfun Arduino Code:

              #include <SoftwareSerial.h>
              
              SoftwareSerial mySerial(10, 11); // TX - GSM, RX - GSM
              
              void setup()  
              {
                // Open serial communications and wait for port to open:
                Serial.begin(9600);
                mySerial.begin(9600);
              }
              
              
              void loop() // run over and over
              {
               if (mySerial.available())
                  Serial.write(mySerial.read());
                  
               if (Serial.available())
                { 
                  while(Serial.available())
                  {
                    mySerial.write(Serial.read());
                  }
                  mySerial.println();
                }
              }
              

               

              JavaScript Code on Intel Edison:

              var m = require('mraa'); //require mraa
              var fs = require('fs'); // require filesystem
              
              
              u = new m.Uart(0);              // /dev/ttyMFD1 
              console.log(u.getDevicePath());
              
              
              var SerialPort = require("serialport").SerialPort; // npm install serialport
              var serialPort = new SerialPort("/dev/ttyMFD1", {
                baudrate: 9600
              });
              
              
              // receive GPS (data)
              var PMTK_SET_NMEA_UPDATE_1HZ = "$PMTK220,1000*1F"
              var PMTK_SET_NMEA_UPDATE_5HZ = "$PMTK220,200*2C"
              var PMTK_SET_NMEA_UPDATE_10HZ = "$PMTK220,100*2F"
              
              
              // turn on only the second sentence (GPRMC)
              var PMTK_SET_NMEA_OUTPUT_RMCONLY = "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
              // turn on RMC and GGA
              var PMTK_SET_NMEA_OUTPUT_RMCGGA = "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
              // turn on RMC, GGA and GSA
              var PMTK_SET_NMEA_OUTPUT_RMCGGAGSA = "$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
              // turn on ALL THE DATA
              var PMTK_SET_NMEA_OUTPUT_ALLDATA = "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
              // turn off output
              var PMTK_SET_NMEA_OUTPUT_OFF = "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
              // Standby
              var PMTK_STANDBY = "$PMTK161,0*28"
              //
              var PMTK_Q_RELEASE = "$PMTK605*31"
              // Ant off
              var PMTK_ANT_OFF = "$PGCMD,33,0*6D"
              // Active Interference Cancellation (AIC) Disable
              var PMTK_AIC_OFF = "$PMTK286,0*22"
              // Active Interference Cancellation (AIC) Enable
              var PMTK_AIC_ON = "$PMTK286,1*23"
              
              
              serialPort.on("open", function () {
                console.log('GET GPS data');
                  serialPort.write(PMTK_SET_NMEA_OUTPUT_RMCGGA + "\r\n");     // RMC and GGA
                  serialPort.write(PMTK_SET_NMEA_UPDATE_1HZ + "\r\n");        // 5Hz
                  serialPort.write(PMTK_AIC_ON + "\r\n");                     // AIC ON
                serialPort.on('data', function(data) {
                    var data_string = '' + data
                    //console.log(data_string);
                    if (data_string.substring(0,6) == '$GPGGA') {
                        gpgga_string = data_string.split('\n')[0];
                        gpgga_string = gpgga_string.replace('\n', '');
                        gps_data = gpgga_string.split(',');
                        console.log('data received: ' + gps_data);
                        var time_string = gps_data[1];
                        var gps_time = new Date();
                        var gps_time_hours = parseInt(gps_data[1].substring(0,2));
                        var gps_time_minutes = parseInt(gps_data[1].substring(2,4));
                        var gps_time_seconds = parseInt(gps_data[1].substring(4,6));
                        gps_time.setHours(gps_time_hours);
                        gps_time.setMinutes(gps_time_minutes);
                        gps_time.setSeconds(gps_time_seconds);
                        
                        gps_lat = gps_data[2];
                        gps_lat_ns = gps_data[3];
                        gps_lon = gps_data[4];
                        gps_lon_ew = gps_data[5];
                        gps_pos_fix = gps_data[6];
                        gps_satt_qty = gps_data[7];
                        gps_hdop = gps_data[8];
                        gps_msl_alt = gps_data[9];
                        gps_unit = gps_data[10];
                        gps_geo = gps_data[11];
                        gps_geo_unit = gps_data[12];
                        
                        if (gps_pos_fix == '1') {
                            console.log('GPS Fixed');
                            console.log('Time: ', gps_time);
                            console.log('Position: ' + gps_lat + gps_lat_ns + ',' + gps_lon + gps_lon_ew);
                            console.log('Altitude: ' + gps_msl_alt + 'M' + ' +/- ' + gps_hdop + 'M');
                            console.log('Satellites Qty: ' + gps_satt_qty + '\n');
                        }
                        
                        if (gps_pos_fix == '0') {
                            console.log('No GPS Fix');
                        }
              
                    } 
                    
                });
              });
              
              • 4. Re: Read/Write to Serial Port - JavaScript (help)
                PabloM_Intel

                Hi KimLorentz,

                 

                To read RMC you can use the same procedure that you used for GGA. When you read the $GPRMC on the first 6 characters of the string you can split the string into a list. That list would have 13 (0-12) values. Check the format below:

                [0] = Recommended Minimum Sentence C
                [1] = Time in hhmmss format
                [2] = Status, could be A=active or V=void
                [3] = Latitude
                [4] = Latitude direction
                [5] = Longitude
                [6] = Longitude direction
                [7] = speed over the ground in knots
                [8] = angle in degrees
                [9] = date ddMMYY
                [10] = Magnetic variation
                [11] = Magnetic variation direction
                [12] = Checksum data, always begin with *

                 

                You can check these two links for more information on how GGA and RMC are distributed.

                GGA: http://www.gpsinformation.org/dale/nmea.htm#GGA

                RMC: http://www.gpsinformation.org/dale/nmea.htm#RMC

                 

                Regards,

                PabloM_Intel

                • 5. Re: Read/Write to Serial Port - JavaScript (help)
                  KimLorentz

                  How do I add 100-200 ms delay to the serialPort.write commands?

                  The write goes to fast for the GPS like it is now.

                   

                  serialPort.write(PMTK_SET_NMEA_OUTPUT_RMCGGA + "\r\n");     // RMC and GGA

                  ADD DELAY HERE.

                  serialPort.write(PMTK_SET_NMEA_UPDATE_1HZ + "\r\n");        // 5Hz

                  ADD DELAY HERE.

                  serialPort.write(PMTK_AIC_ON + "\r\n");                     // AIC ON

                  ADD DELAY HERE.

                  • 6. Re: Read/Write to Serial Port - JavaScript (help)
                    PabloM_Intel

                    Hi KimLorentz,

                     

                    I believe that there’s no a specific “delay” or “sleep” function in JavaScript, like there is for C, Python and some other programming languages.

                    However, you can use the setTimeout event.

                     

                    If I’m not mistaken it goes like this:

                     

                    setTimeout (function(){
                         //your code
                    }, 1000);                //where 1000 is in ms
                    

                     

                    In the example above, your code will be paused by 1000ms.

                     

                    Regards,

                    PabloM_Intel

                    • 7. Re: Read/Write to Serial Port - JavaScript (help)
                      KimLorentz

                      I got the delay function to work.

                       

                      I added this code to the js.

                       

                      function delay(milliseconds) 
                      { 
                          var startTime = Date.now(); 
                          while (Date.now() - startTime < milliseconds); 
                      } 
                      

                       

                      At start of SerialPort.on open I added.

                      serialPort.write(PMTK_SET_NMEA_OUTPUT_RMCGGA + "\r\n");  // RMC and GGA   
                      delay(200);                                        // 200ms 
                      serialPort.write(PMTK_DT_DGPS_MODE + "\r\n");            // DGPS   
                      delay(200);                                        // 200ms 
                      serialPort.write(PMTK_SET_NMEA_UPDATE_5HZ + "\r\n");    // 5Hz   
                      delay(200);                                        // 200ms 
                      serialPort.write(PMTK_AIC_ON + "\r\n");                  // AIC ON   
                      delay(200);                                        // 200ms 
                      

                       

                      The new code is:

                       

                      var m = require('mraa'); //require mraa 
                      var fs = require('fs'); // require filesystem 
                      
                      
                      u = new m.Uart(0);              // /dev/ttyMFD1 
                      console.log(u.getDevicePath()); 
                      
                      
                      var SerialPort = require("serialport").SerialPort; // npm install serialport 
                      var serialPort = new SerialPort("/dev/ttyMFD1", { 
                        baudrate: 9600 
                      }); 
                      
                      
                      function delay(milliseconds) 
                      { 
                          var startTime = Date.now(); 
                          while (Date.now() - startTime < milliseconds); 
                      } 
                      
                      
                      // Create .txt file 
                      var fs = require('fs'); 
                      var ws = fs.createWriteStream('/media/sdcard/GPS.txt'); 
                      
                      // receive GPS (data) 
                      var PMTK_SET_NMEA_UPDATE_1HZ = "$PMTK220,1000*1F"; 
                      var PMTK_SET_NMEA_UPDATE_5HZ = "$PMTK220,200*2C"; 
                      var PMTK_SET_NMEA_UPDATE_10HZ = "$PMTK220,100*2F"; 
                      
                      // Baud Rate 0(default = 9600) - 115200 
                      var PMTK_SET_NMEA_BAUDRATE_0 = "$PMTK251,0*28"; 
                      var PMTK_SET_NMEA_BAUDRATE_4800 = "$PMTK251,4800*14"; 
                      var PMTK_SET_NMEA_BAUDRATE_9600 = "$PMTK251,9600*17"; 
                      var PMTK_SET_NMEA_BAUDRATE_14400 = "$PMTK251,14400*29"; 
                      var PMTK_SET_NMEA_BAUDRATE_19200 = "$PMTK251,19200*22"; 
                      var PMTK_SET_NMEA_BAUDRATE_38400 = "$PMTK251,38400*27"; 
                      var PMTK_SET_NMEA_BAUDRATE_57600 = "$PMTK251,57600*2C"; 
                      var PMTK_SET_NMEA_BAUDRATE_115200 = "$PMTK251,115200*1F"; 
                      
                      // turn on only the second sentence (GPRMC) 
                      var PMTK_SET_NMEA_OUTPUT_RMC = "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"; 
                      // GGA only 
                      var PMTK_SET_NMEA_OUTPUT_GGA = "$PMTK314,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"; 
                      // turn on RMC and GGA 
                      var PMTK_SET_NMEA_OUTPUT_RMCGGA = "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"; 
                      // turn on RMC, GGA and GSA 
                      var PMTK_SET_NMEA_OUTPUT_RMCGGAGSA = "$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"; 
                      // turn on ALL THE DATA 
                      var PMTK_SET_NMEA_OUTPUT_ALLDATA = "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"; 
                      // turn off output 
                      var PMTK_SET_NMEA_OUTPUT_OFF = "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"; 
                      // Standby 
                      var PMTK_STANDBY = "$PMTK161,0*28"; 
                      // 
                      var PMTK_Q_RELEASE = "$PMTK605*31"; 
                      // Ant off 
                      var PMTK_ANT_OFF = "$PGCMD,33,0*6D"; 
                      // Active Interference Cancellation (AIC) Disable 
                      var PMTK_AIC_OFF = "$PMTK286,0*22"; 
                      // Active Interference Cancellation (AIC) Enable 
                      var PMTK_AIC_ON = "$PMTK286,1*23"; 
                      // DGPS Mode 
                      var PMTK_DT_DGPS_MODE = "$PMTK401*37"; 
                      
                      
                      serialPort.on("open", function () { 
                        console.log('GET GPS data'); 
                          serialPort.write(PMTK_SET_NMEA_OUTPUT_RMCGGA + "\r\n");  // RMC and GGA 
                          console.log(PMTK_SET_NMEA_OUTPUT_RMCGGA); 
                          delay(200); 
                          serialPort.write(PMTK_DT_DGPS_MODE + "\r\n");            // DGPS 
                          console.log(PMTK_DT_DGPS_MODE); 
                          delay(200); 
                          serialPort.write(PMTK_SET_NMEA_UPDATE_5HZ + "\r\n");    // 5Hz 
                          console.log(PMTK_SET_NMEA_UPDATE_5HZ); 
                          delay(200); 
                          serialPort.write(PMTK_AIC_ON + "\r\n");                  // AIC ON 
                          console.log(PMTK_AIC_ON); 
                          delay(200); 
                           
                        serialPort.on('data', function(data) { 
                            var data_string = '' + data; 
                            console.log(data_string); 
                            ws.write(data_string); 
                            if (data_string.substring(0,6) == '$GPGGA') { 
                                gpgga_string = data_string.split('\n')[0]; 
                                gpgga_string = gpgga_string.replace('\n', ''); 
                                gps_data = gpgga_string.split(','); 
                                console.log('data received: ' + gps_data); 
                                var time_string = gps_data[1]; 
                                var gps_time = new Date(); 
                                var gps_time_hours = parseInt(gps_data[1].substring(0,2)); 
                                var gps_time_minutes = parseInt(gps_data[1].substring(2,4)); 
                                var gps_time_seconds = parseInt(gps_data[1].substring(4,6)); 
                                gps_time.setHours(gps_time_hours); 
                                gps_time.setMinutes(gps_time_minutes); 
                                gps_time.setSeconds(gps_time_seconds); 
                                 
                                gps_lat = gps_data[2]; 
                                gps_lat_ns = gps_data[3]; 
                                gps_lon = gps_data[4]; 
                                gps_lon_ew = gps_data[5]; 
                                gps_pos_fix = gps_data[6]; 
                                gps_satt_qty = gps_data[7]; 
                                gps_hdop = gps_data[8]; 
                                gps_msl_alt = gps_data[9]; 
                                gps_unit = gps_data[10]; 
                                gps_geo = gps_data[11]; 
                                gps_geo_unit = gps_data[12]; 
                                 
                                if (gps_pos_fix == '1') { 
                                    console.log('GPS Fixed'); 
                                    console.log('Time: ', gps_time); 
                                    console.log('Position: ' + gps_lat + gps_lat_ns + ',' + gps_lon + gps_lon_ew); 
                                    console.log('Altitude: ' + gps_msl_alt + 'M' + ' +/- ' + gps_hdop + 'M'); 
                                    console.log('Satellites Qty: ' + gps_satt_qty + '\n'); 
                                } 
                                 
                                if (gps_pos_fix == '2') { 
                                    console.log('DGPS Fixed'); 
                                    console.log('Time: ', gps_time); 
                                    console.log('Position: ' + gps_lat + gps_lat_ns + ',' + gps_lon + gps_lon_ew); 
                                    console.log('Altitude: ' + gps_msl_alt + 'M' + ' +/- ' + gps_hdop + 'M'); 
                                    console.log('Satellites Qty: ' + gps_satt_qty + '\n'); 
                                } 
                                 
                                if (gps_pos_fix == '0') { 
                                    console.log('No GPS Fix'); 
                                } 
                      
                      
                            } 
                             
                        }); 
                      });