c++gpsarduinonmea

Decode GPS NMEA code using arduino


I know this has been asked many times but I really can't find what I am really searching.

I am using an Arduino Uno and a GPS Shield that shows GPS data through serial.

Here is the code I am uploading to my Arduino to interface the GPS Shield:

void loop() // run over and over
{
    while(!(mySerial.available())){}
      Serial.write(mySerial.read());
}

That is just the code. Nevertheless, as it continuously loops, on a Serial Monitor, it also output GPS data every second.

Here is its output every second:

$GPGGA,013856.000,000.9090,N,9090.90,E,1,09,1.1,316.97,M,0.00,M,,*66
$GPGSA,A,3,07,08,11,1ÿ3,16,19,23,27,42,,,,2.8,1.1,2.5*3F
$GPRMC,013856.000,A,000.9090,N,9090.90,E,0.0,038.1,310814,,,A*62
$GPGSV,ÿ3,1,12,16,26,059,33,27,33,025,44,08,30,330,32,07,31,326,34*7A
$GPGSV,3,2,12,19,58,354,31,01,33,186,18,23,32,221,24,11,5ÿ9,198,31*70
$GPGSV,3,3,12,42,60,129,32,13,38,253,27,32,06,161,,31,01,140,*7E

As it updates every second, the coordinates changes to minimal, which means the GPS Shield is working.

The problem here is, I wanted to parse the GPS data, especially on the GPGGA line only, and ignore the other lines. I would like to parse the Status, Latitude, N/S Indicator, Longitude, and E/W Indicator.

I have searched for the NMEA Library (http://nmea.sourceforge.net/), but I have no idea how to use it.

Can someone please help me here? Thank you.


Solution

  • You can use TinyGPS to parse the NMEA strings. If you are interested in only 1 sentence. You can write a custom parser as below for that sentence only.

    int handle_byte(int byteGPS) {
    buf[counter1] = byteGPS;
    //Serial.print((char)byteGPS);
    counter1++;
    if (counter1 == 300) {
      return 0;
    }
    
    if (byteGPS == ',') {
        counter2++;
        offsets[counter2] = counter1;
        if (counter2 == 13) {
          return 0;
        }   }   if (byteGPS == '*') {
        offsets[12] = counter1;   }
    
      // Check if we got a <LF>, which indicates the end of line   if (byteGPS == 10) {
    
        // Check that we got 12 pieces, and that the first piece is 6 characters
        if (counter2 != 12 || (get_size(0) != 6)) {
          return 0;
        }
    
        // Check that we received $GPRMC
        // CMD buffer contains $GPRMC
        for (int j=0; j<6; j++) {
    
          if (buf[j] != cmd[j]) {
            return 0;
          }
        }
    
        // Check that time is well formed
        if (get_size(1) != 10) {
    
          return 0;
        }
    
        // Check that date is well formed
        if (get_size(9) != 6) {
          return 0;
        }
    
        SeeedOled.setTextXY(7,0);
        for (int j=0; j<6; j++) {
          SeeedOled.putChar(*(buf+offsets[1]+j));
        }
        SeeedOled.setTextXY(7,7);
    
        for (int j=0; j<6; j++) {
          SeeedOled.putChar(*(buf+offsets[9]+j));
        }
    
        // TODO: compute and validate checksum
    
        // TODO: handle timezone offset
    
          return 0;   }   
    return 1; }