Parsing GPS - misses every other second

Hi,

I used the code available from the playground and it works pretty much as is. <I should clarify that when using the hardware serial interface, the GPS data is parsed correctly.>

but when I setup a software serial pin using either SoftwareSerial or NewSoftSerial to receive GPS data, it misses every other block of data from the GPS.

This is where the code is:

http://www.arduino.cc/playground/Tutorials/GPS

I can't figure out why it misses the GPS data, unless the software serial takes too long to initialize and start reading data and misses the CR.

Are you sure the GPS is configured to output once per second?

That is the typical default, but most units can be configured to change the output rate.

-j

I'm sure the GPS does output every second. It works great when using the hardware serial interface and updates the monitor every second.

But when I change to the software serial interface, it still updates every second, but every other $GPRMC line gets mixed with one of the other lines so the parsing section of the code misses it...

I'm trying to reserve the HW serial for another purpose and to learn what is going wrong.

In that case my guess would be that the processor is busy and misses part of the GPS sentence. NSS will miss any data that comes in when not actually reading.

-j

So this might be a software problem. It does look like Arduino receives all of the data, but does not parse it correctly.

I'm not using the parallax GPS module, but another Rockwell International Jupiter board. The output should be standard NMEA...

Here is what the serial monitor displays. You can see all of the sentances, but they are not parsed correctly

$GPRMC,000553,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6A


---------------
Time in UTC (HhMmSs): 000553
Status (A=OK,V=KO): V
Latitude: 0000.0000
Direction (N/S): N
Longitude: 00000.0000
Direction (E/W): W
Velocity in knots: 0.000
Heading in degrees: 0.0
Date UTC (DdMmAa): 130895
Magnetic degrees: 7.9
(E/W): 
Mode: $GPRMC,000553,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W
---------------
$GPRMC,000554,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6D
$PRWIZCH,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0*4D
$GPRMC,000555,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6C


---------------
Time in UTC (HhMmSs): 000555
Status (A=OK,V=KO): V
Latitude: 0000.0000
Direction (N/S): N
Longitude: 00000.0000
Direction (E/W): W
Velocity in knots: 0.000
Heading in degrees: 0.0
Date UTC (DdMmAa): 130895
Magnetic degrees: 7.9
(E/W): 
Mode: $GPRMC,000555,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W
---------------
$GPRMC,000556,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6F
$PRWIZCH,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0*4D
$GPRMC,000557,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6E


---------------
Time in UTC (HhMmSs): 000557
Status (A=OK,V=KO): V
Latitude: 0000.0000
Direction (N/S): N
Longitude: 00000.0000
Direction (E/W): W
Velocity in knots: 0.000
Heading in degrees: 0.0
Date UTC (DdMmAa): 130895
Magnetic degrees: 7.9
(E/W): 
Mode: $GPRMC,000557,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W
---------------
$GPRMC,000558,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*61
$PRWIZCH,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0*4D
$GPRMC,000559,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*60


---------------
Time in UTC (HhMmSs): 000559
Status (A=OK,V=KO): V
Latitude: 0000.0000
Direction (N/S): N
Longitude: 00000.0000
Direction (E/W): W
Velocity in knots: 0.000
Heading in degrees: 0.0
Date UTC (DdMmAa): 130895
Magnetic degrees: 7.9
(E/W): 
Mode: $GPRMC,000559,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W
---------------
$GPRMC,000600,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6F
$PRWIZCH,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0,23,0*4D
$GPRMC,000601,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W*6E


---------------
Time in UTC (HhMmSs): 000601
Status (A=OK,V=KO): V
Latitude: 0000.0000
Direction (N/S): N
Longitude: 00000.0000
Direction (E/W): W
Velocity in knots: 0.000
Heading in degrees: 0.0
Date UTC (DdMmAa): 130895
Magnetic degrees: 7.9
(E/W): 
Mode: $GPRMC,000601,V,0000.0000,N,00000.0000,W,0.000,0.0,130895,7.9,W
---------------

Here is my actual code:

/*
Example code for testing GPS sent through serial monitor to the Arduino
based on:
 Igor Gonz�lez Mart�n. 05-04-2007
 igor.gonzalez.martin@gmail.com
 English translation by djmatic 19-05-2007
 Listen for the $GPRMC string and extract the GPS location data from this.
 Display the result in the Arduino's serial monitor.
*/

/*
LCD code based on:
 port of Peter Anderson's  LCD117_1.BS2  (Parallax Basic Stamp 2) to Arduino
 Paul Badger 2007
 Comments and bug fixes Ian Patterson 9/08
 original Peter H. Anderson, Baltimore, MD, Oct, '06
*/

//import libraries
#include <string.h>
#include <ctype.h>
//#include <SoftwareSerial.h>
#include <NewSoftSerial.h>


//LCD setup
#define rxLCDPin 4  //rxPin is immaterial - not used - just make this an unused Arduino pin number
#define txLCDPin 14 //pin 14 is analog pin 0, on a BBB just use a servo cable :), see Reference pinMode
//SoftwareSerial LCD=SoftwareSerial(rxLCDPin, txLCDPin);
NewSoftSerial LCD=NewSoftSerial(rxLCDPin, txLCDPin);

//GPS setup
#define rxGPSPin 2  //rxGPSPin
#define txGPSPin 3  //txGPSPin
//SoftwareSerial GPS=SoftwareSerial(rxGPSPin, txGPSPin);
NewSoftSerial GPS=NewSoftSerial(rxGPSPin, txGPSPin);
int ledPin=13;  //LED test pin
int byteGPS=-1;
char linea[300]="";
char comandoGPR[7]="$GPRMC";
int cont=0;
int bien=0;
int conta=0;
int indices[13];

int rxSerialPin=0;  //serial rxPIN 
int txSerialPin=1;  //serial txPIN

void setup() {

  pinMode(ledPin, OUTPUT);  //Initialize LED pin

  //set up hardware serial
  pinMode(rxSerialPin, INPUT);
  pinMode(txSerialPin, OUTPUT);
  Serial.begin(4800);   

  //set up GPS
  pinMode(rxGPSPin, INPUT);
  pinMode(txGPSPin, OUTPUT);
  GPS.begin(4800);  //4800 baud is GPS comm speed
  for (int i=0; i<300; i++){  //Initialize a buffer for received GPS data
    linea[i]=' ';
  }

  //set up LCD
  pinMode(txLCDPin, OUTPUT);
  LCD.begin(9600);  //9600 baud is chip comm speed
  LCD.print("?G216");  //set display geometry,  2 x 16 characters in this case
  delay(500);  //pause to allow LCD EEPROM to program
  LCD.print("?B80");  //set backlight from 00 to ff hex (minimum to maximum brightness)
  delay(1000);  //pause to allow LCD EEPROM to program
  LCD.print("?s5");  //set tabs to five spaces
  delay(1000);  //pause to allow LCD EEPROM to program
  LCD.print("?c0");  //set cursor style, 0= none 2= blinking 3=underline
  delay(5);
  LCD.print("?f");  //clear the LCD
  delay(5);
  LCD.print("Hello GPS");
  delay(1000);

}

void loop() {

  digitalWrite(ledPin, HIGH);
  byteGPS = GPS.read();  //Read a byte of the software serial port
  //byteGPS = Serial.read();  //Read a byte of the hardware serial port

  if (byteGPS == -1) {  //See if the port is empty yet
  //delay(10); 
  } 
  else {
    linea[conta]=byteGPS;  //If there is serial port data, it is put in the buffer
    conta++;                      
    Serial.print(byteGPS, BYTE);

    if (byteGPS==13){  //If the received byte is = to 13, carriage return, end of transmission
      digitalWrite(ledPin, LOW); 
      cont=0;
      bien=0;
      for (int i=1; i<7; i++){  //Verifies if the received command starts with $GPR
        if (linea[i]==comandoGPR[i-1]){
          bien++;
        }
      }
      if(bien==6){  //If yes, continue and process the data
        for (int i=0; i<300; i++){
          if (linea[i]==','){  //check for the position of the  "," separator
            indices[cont]=i;
            cont++;
          }
          if (linea[i]=='*'){  //... and the "*"
            indices[12]=i;
            cont++;
          }
        }
        Serial.println("");  //... and write to the serial port
        Serial.println("");
        Serial.println("---------------");
        for (int i=0; i<12; i++){
          switch(i){
          case 0 :
            Serial.print("Time in UTC (HhMmSs): ");
            LCD.print("?x10?y0");
            break;
          case 1:
            Serial.print("Status (A=OK,V=KO): ");
            break;
          case 2:
            Serial.print("Latitude: ");
            LCD.print("?x00?y0");
            break;
          case 3:
            Serial.print("Direction (N/S): ");
            LCD.print("?x09?y0");
            break;
          case 4:
            Serial.print("Longitude: ");
            LCD.print("?x00?y1");
            break;
          case 5:
            Serial.print("Direction (E/W): ");
            LCD.print("?x09?y1");
            break;
          case 6:
            Serial.print("Velocity in knots: ");
            break;
          case 7:
            Serial.print("Heading in degrees: ");
            break;
          case 8:
            Serial.print("Date UTC (DdMmAa): ");
            LCD.print("?x10?y1");
            break;
          case 9:
            Serial.print("Magnetic degrees: ");
            break;
          case 10:
            Serial.print("(E/W): ");
            break;
          case 11:
            Serial.print("Mode: ");
            break;
          case 12:
            Serial.print("Checksum: ");
            break;
          }
          for (int j=indices[i]; j<(indices[i+1]-1); j++){
            Serial.print(linea[j+1]);
            if (i==0){
              LCD.print(linea[j+1]);
            }
            if (i==2){
              LCD.print(linea[j+1]);
            }
            if (i==3){
              LCD.print(linea[j+1]);
            }
            if (i==4){
              LCD.print(linea[j+1]);
            }
            if (i==5){
              LCD.print(linea[j+1]);
            }
            if (i==8){
              LCD.print(linea[j+1]);
            }
          }
          Serial.println("");
        }
        Serial.println("---------------");
      }
      conta=0;  //Reset the buffer
      for (int i=0; i<300; i++){
        linea[i]=' ';             
      }
    }
  }
}

I scrapped this code and went with TinyGPS, which works very well.

I'll struggle with a few coding issues and post other questions if I can't solve them.

Thanks for all the input; it helps the learning...