Parsing code for GPS NMEA string

39,593

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).

Share:
39,593
shailendra
Author by

shailendra

Trying to learn more of C,C++ and perl and LINUX.Interested in learning server side coding, and AI also.

Updated on October 21, 2020

Comments

  • shailendra
    shailendra over 3 years

    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
    
  • ryyker
    ryyker over 10 years
    Nice answer. Do you think if((mySerial.available() may be checking for non-null response? (regarding your suggesting to check by using strlen)
  • ryyker
    ryyker over 10 years
    Same question - answered here
  • shailendra
    shailendra over 10 years
    I used <CR> and <Lf> in my code and it worked out for me for first 20-25 outpurts over COM16 port but after that same undefined output started coming.Is is due to the array size which i had defined for gpsdata[65]?
  • shailendra
    shailendra over 10 years
    this didn't worked out for me, as it output is again undefined when i tried it.I willl use the malloc functionality definitely in my code.
  • ryyker
    ryyker over 10 years
    I just updated this post, did you get the lines that test for '\n\r'?, and do you know if you are supposed to keep them, or are you supposed to strip them off and append a '\0' char to terminate. A C string always needs a '\0' termination for it to be used in any C string function.
  • shailendra
    shailendra over 10 years
    One more thing to be added, in your code you are only printing if myString don't have GPGGA, my aim is to store the string which is coming after GPGGA only.
  • ryyker
    ryyker over 10 years
    @shailendra - Actually, the string is already completed in my code, just as it is. Both ways, including the '\n\r', or simply appending a '\0'. (you never told me which one is preferable, with or without the '\n\r'). If you need a way to get the string out of the function, I will give you an example, see my edit.
  • shailendra
    shailendra over 10 years
    :well including \n\r is required.I am too using the same thing in my code but i am not using dynamic memory allocation but by both way, output is changing dramatically,i think the problem is with the output string.I used your code too, but same response.I will post the output after using your code in my code
  • Some programmer dude
    Some programmer dude over 10 years
    @shailendra Yes, you might want to increase the array size.