NMEA decode from a buffer

Hi everyone,

I use sucesfully nmea.h librery for decoding. Now, my code goes bigger and sentences readed by serial.read from GPS is sometimes corrupted.

Standard decoding:

if (Serial1.available() > 0 )
{
char c = Serial1.read();
if (gps.decode(c)) {
gps.gprmc_status();
...

I wish to read GPS into a buffer:

void GPSload()
{
if (millis() - GPStimeout > 1000 )
{
char c = Serial1.read();
if(c != -1 && decoded != 1)
{
GPStimeout = millis();
buffer[bufferi] = c;
bufferi++;
if(c == 13) decoded =1;
...

and decod it whenewer I wish:

void GPSdecode()
{
buffer[bufferi] = 13; //
bufferi++;
buffer[bufferi] = 10; //
bufferi++;
for(int i=0; i < bufferi; i++)
{
if (gps.decode(buffer*)) {*

  • gps.gprmc_status();*
  • }*
    Serial.write(" ");
    Serial.writeln(gps.decode()); // HERE !!!
    }
    }
    While writing Serial.write(c, DEC); received GPS sentences, every sentence ends by 1310. (13 and 10 )
    Even I add the and it doesn´t works, evem without... wher I write code (HERE !!!), it returns 0 ALWAYS! Why? :-/
    any idea? :-?

Hi,

the problem is you do not read a telegram just from the beginning. You start reading somewhere in the middle. Change the code as follows, this should work.

int decode = 0;
char buffer[..]

void setup()
{
  decode = 0;
  ..
}

void loop()
{
 ..
 if (GPSload() == true) {
   // decode the telegram
  ...
  // and start new receiving
  decode = 0;
 } 
  ...
}

bool GPSload()
{
  char c;
  static int i;

  switch (decode) {
  case 0 : // wait for next reading
          Serial1.flush(); // discard all characters
        if ((millis()-GPStimeout) > 1000) {
          decode = 1;
          i = 0;
        }
        break;
  case 1:  // wait for Start of sequence
        if (Serial1.available()) {
           c = Serial1.read();
           if (c = '

I can not try if it works, i have no GPS receiver, but the importent things are:

  1. wait until a new GPS telegram starts (character $)
  2. read until the end of the telegram (character LF)

You can add a timeout to the GPSload to restart, if telegram not received within a certain time.

Mike
) {
            // start character found, store
            buffer[i++] = c;
                  decode = 2;
                }
             }
       break;
 case 2: // receive until end of sequence
       if (Serial1.available()) {
          c = Serial1.read();
                buffer[i++] = c;
          // unexpected start of new sequence
          if (c = '


I can not try if it works, i have no GPS receiver, but the importent things are:

1. wait until a new GPS telegram starts (character $)
2. read until the end of the telegram (character LF)

You can add a timeout to the GPSload to restart, if telegram not received within a certain time.

Mike
) {
                   // start from beginning
                   i = 0;
                buffer[i] = c;
                 }
            // look for end character
                 if (c == 10) {
                   // get actual time
                   GPStimeout = millis();
             decode = 3;
                 }
              }
        break;
  case 3:  // wait until telegram decoded
        break;
  }
  if (decode == 3) return true;
  else return false;
}

I can not try if it works, i have no GPS receiver, but the importent things are:

  1. wait until a new GPS telegram starts (character $)
  2. read until the end of the telegram (character LF)

You can add a timeout to the GPSload to restart, if telegram not received within a certain time.

Mike

Not reading from beginning shouldnt be a problem. Only can happen that I read longer or shorter sentence. Shorter sentence is rejected by the library and longer shall be accepted when the "$" come.

And more, I write the sentence from buffer to serial to check it and control. very offten I get whole sentence, but no acceptation...

in my case it isn't accepted. I'll try your proposal, but think the problem is somewhere else...

Petr