Reputation: 35
I'm using an old device (2006 - extremely trimmed embedded Linux) to get GPS latitude and longitude from an external receiver. GPS coordinates are displayed on device's LCD display. It used to work fine until the original GPS receiver failed. They replaced it with a new receiver but now it doesn't work anymore, all I see on LCD is: Latitude: - / Longitude: -.
I tried to see if the new GPS receiver is operational. And it seems the GPGGA packets are there. The old device expects GPGGA packets for parsing/processing.
char GPSLatBuf[12], GPSLonBuf[12];
int parseGPSData(char * gpsBuffer)
{
char * p;
char gpsQuality = '0';
if((p = strstr(gpsBuffer, "$GPGGA")) == NULL)
return -1;
memset(GPSLatBuf, 0, sizeof(GPSLatBuf));
memset(GPSLonBuf, 0, sizeof(GPSLonBuf));
p += 7; // UTC time
if(*p != ',')
{
p += 10; // Latitude
if(*p != ',')
{
memcpy(&GPSLatBuf[1], p, 9);
p += 10; // N/S Hemisphere
if(*p != ',')
{
GPSLatBuf[0] = (*p == 'N') ? '+' : '-';
p += 2; // Longitude
if(*p != ',')
{
memcpy(&GPSLonBuf[1], p, 10);
p += 11; // E/W Hemisphere
if(*p != ',')
{
GPSLonBuf[0] = (*p == 'E') ? '+' : '-';
p += 2; // GPS quality
if(*p != ',')
gpsQuality = *p;
}
}
}
}
}
if(gpsQuality == '0')
return -1;
return 0;
}
Expected to see non-void fields like before: +4916.4600 / -12311.1200 (just an example as I see nothing on display right now).
Upvotes: 0
Views: 147
Reputation: 2997
Hope this is not too late.
The idea is: the number of decimal digits of data inside GPGGA message* is somehow specific to GPS module.
Hence, your code has an issue here, as it uses fixed offsets to search for latitude, longitude, etc.
It is easy to fix that: instead of using fixed offsets, you should search for the delimiter ("," in this case) using strstr()
function.
Here's the corrected code:
int parseGPSData(char * gpsBuffer)
{
char * p;
char gpsQuality = '0';
if((p = strstr(gpsBuffer, "$GPGGA")) == NULL)
return -1;
memset(GPSLatBuf, 0, sizeof(GPSLatBuf));
memset(GPSLonBuf, 0, sizeof(GPSLonBuf));
if((p = strstr(p, ",")) != NULL)
{
p++; // there is UTC time
if((p = strstr(p, ",")) != NULL)
{
p++; // Latitude
memcpy(&GPSLatBuf[1], p, 9);
if((p = strstr(p, ",")) != NULL)
{
p++; // N/S Hemisphere
GPSLatBuf[0] = (*p == 'N') ? '+' : '-';
if((p = strstr(p, ",")) != NULL)
{
p++; // Longitude
memcpy(&GPSLonBuf[1], p, 10);
if((p = strstr(p, ",")) != NULL)
{
p++; // E/W Hemisphere
GPSLonBuf[0] = (*p == 'E') ? '+' : '-';
if((p = strstr(p, ",")) != NULL)
gpsQuality = p[1];
}
}
}
}
}
if(gpsQuality == '0')
return -1;
return 0;
}
I'm pretty sure this will solve your issue :)
*EDIT:
Here's how NMEA GGA message looks like - an example:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
where:
## GGA Global Positioning System Fix Data
## 123519 Fix taken at 12:35:19 UTC
## 4807.038,N Latitude 48 deg 07.038' N
## 01131.000,E Longitude 11 deg 31.000' E
## ...
More useful information you can find here: https://www.gpsinformation.org/dale/nmea.htm#GGA
Upvotes: 1