Parsing code for GPS NMEA string

shailendra picture shailendra · Nov 8, 2013 · Viewed 38.4k times · Source

enter image description herei am trying to parse the incoming GPGGA NMEA GPS string using Arduino uno and below code. What i am trying to do is that i am using only GPGGA NMEA string to get the values of Latitude, longitude and altitude.In my below code, i had put certain checks to check if incoming string is GPGGA or not, and then store the further string in a array which can be further parsed suing strtok function and all the 3 GPS coordinates can be easily find out.

But i am unable to figure out how to store only GPGGA string and not the further string.I am using a for loop but it isn't working.

I am not trying to use any library.I had came across certain existing codes like this.

Here is the GPGGA string information link

i am trying to have following functionlity i) Check if incoming string is GPGGA ii) If yes, then store the following string upto EOL or upto * (followed by checksum for the array) in a array, array length is variable(i am unable to find out solution for this) iii) Then parse the stored array(this is done, i tried this with a different array)

 #include <SoftwareSerial.h>

    SoftwareSerial mySerial(10,11);  // 10 RX / 11 TX

    void setup()
    {
    Serial.begin(9600);
    mySerial.begin(9600);
    }

    void loop()
    {
    uint8_t x;
    char gpsdata[65];

    if((mySerial.available()))
    {
    char c = mySerial.read();
    if(c == '$')
      {char c1 = mySerial.read();
       if(c1 == 'G')
         {char c2 = mySerial.read();
          if(c2 == 'P')
            {char c3 = mySerial.read();
             if(c3 == 'G')
               {char c4 = mySerial.read();
                if(c4 == 'G')
                   {char c5 = mySerial.read();
                    if(c5 == 'A')
                       {for(x=0;x<65;x++)
                        { 
                        gpsdata[x]=mySerial.read();


    while (gpsdata[x] == '\r' || gpsdata[x] == '\n')
                    {
                    break;
                    }

                        }

                       }
                       else{
                          Serial.println("Not a GPGGA string");
                        }
                   }
               }

            }     

         }

      }

    }

    Serial.println(gpsdata);
    }

Edit 1: Considering Joachim Pileborg, editing the for loop in the code.

I am adding a pic to show the undefined output of the code.

Input for the code:

$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43
$GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45

Answer

Some programmer dude picture Some programmer dude · Nov 8, 2013

After a quick check of the linked article on the NMEA 0183 protocol, this jumped out at me:

<CR><LF> ends the message.

This means, that instead of just read indiscriminately from the serial port, you should be looking for that sequence. If found, you should terminate the string, and break out of the loop.

Also, you might want to zero-initialize the data string to begin with, to easily see if there actually is any data in it to print (using e.g. strlen).