fix parser when no fix

RMC and GGA sentences were no properly parsed when there was no fix.
They were assuming numeric values between commas, but you just get a
string of commas when there’s no fix. This was causing the RMC ate to
be parsed incorrectly.
This commit is contained in:
driverblock 2014-09-27 08:02:59 -04:00
parent e7a91195e5
commit 04fc848c26
1 changed files with 134 additions and 85 deletions

View File

@ -47,6 +47,8 @@ boolean Adafruit_GPS::parse(char *nmea) {
//return false;
}
}
int32_t degree;
long minutes;
char degreebuff[10];
// look for a few common sentences
if (strstr(nmea, "$GPGGA")) {
@ -64,58 +66,86 @@ boolean Adafruit_GPS::parse(char *nmea) {
// parse out latitude
p = strchr(p, ',')+1;
strncpy(degreebuff, p, 2);
p += 2;
degreebuff[2] = '\0';
int32_t degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
long minutes = 50 * atol(degreebuff) / 3;
latitude_fixed = degree + minutes;
latitude = degree / 100000 + minutes * 0.000006F;
if (',' != *p)
{
strncpy(degreebuff, p, 2);
p += 2;
degreebuff[2] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
latitude_fixed = degree + minutes;
latitude = degree / 100000 + minutes * 0.000006F;
}
p = strchr(p, ',')+1;
if (p[0] == 'N') lat = 'N';
else if (p[0] == 'S') lat = 'S';
else if (p[0] == ',') lat = 0;
else return false;
if (',' != *p)
{
if (p[0] == 'N') lat = 'N';
else if (p[0] == 'S') lat = 'S';
else if (p[0] == ',') lat = 0;
else return false;
}
// parse out longitude
p = strchr(p, ',')+1;
strncpy(degreebuff, p, 3);
p += 3;
degreebuff[3] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
longitude_fixed = degree + minutes;
longitude = degree / 100000 + minutes * 0.000006F;
if (',' != *p)
{
strncpy(degreebuff, p, 3);
p += 3;
degreebuff[3] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
longitude_fixed = degree + minutes;
longitude = degree / 100000 + minutes * 0.000006F;
}
p = strchr(p, ',')+1;
if (p[0] == 'W') lon = 'W';
else if (p[0] == 'E') lon = 'E';
else if (p[0] == ',') lon = 0;
else return false;
if (',' != *p)
{
if (p[0] == 'W') lon = 'W';
else if (p[0] == 'E') lon = 'E';
else if (p[0] == ',') lon = 0;
else return false;
}
p = strchr(p, ',')+1;
fixquality = atoi(p);
if (',' != *p)
{
fixquality = atoi(p);
}
p = strchr(p, ',')+1;
satellites = atoi(p);
if (',' != *p)
{
satellites = atoi(p);
}
p = strchr(p, ',')+1;
HDOP = atof(p);
if (',' != *p)
{
HDOP = atof(p);
}
p = strchr(p, ',')+1;
altitude = atof(p);
if (',' != *p)
{
altitude = atof(p);
}
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
geoidheight = atof(p);
if (',' != *p)
{
geoidheight = atof(p);
}
return true;
}
if (strstr(nmea, "$GPRMC")) {
@ -143,58 +173,77 @@ boolean Adafruit_GPS::parse(char *nmea) {
// parse out latitude
p = strchr(p, ',')+1;
strncpy(degreebuff, p, 2);
p += 2;
degreebuff[2] = '\0';
long degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
long minutes = 50 * atol(degreebuff) / 3;
latitude_fixed = degree + minutes;
latitude = degree / 100000 + minutes * 0.000006F;
if (',' != *p)
{
strncpy(degreebuff, p, 2);
p += 2;
degreebuff[2] = '\0';
long degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
long minutes = 50 * atol(degreebuff) / 3;
latitude_fixed = degree + minutes;
latitude = degree / 100000 + minutes * 0.000006F;
}
p = strchr(p, ',')+1;
if (p[0] == 'N') lat = 'N';
else if (p[0] == 'S') lat = 'S';
else if (p[0] == ',') lat = 0;
else return false;
if (',' != *p)
{
if (p[0] == 'N') lat = 'N';
else if (p[0] == 'S') lat = 'S';
else if (p[0] == ',') lat = 0;
else return false;
}
// parse out longitude
p = strchr(p, ',')+1;
strncpy(degreebuff, p, 3);
p += 3;
degreebuff[3] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
longitude_fixed = degree + minutes;
longitude = degree / 100000 + minutes * 0.000006F;
if (',' != *p)
{
strncpy(degreebuff, p, 3);
p += 3;
degreebuff[3] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
longitude_fixed = degree + minutes;
longitude = degree / 100000 + minutes * 0.000006F;
}
p = strchr(p, ',')+1;
if (p[0] == 'W') lon = 'W';
else if (p[0] == 'E') lon = 'E';
else if (p[0] == ',') lon = 0;
else return false;
if (',' != *p)
{
if (p[0] == 'W') lon = 'W';
else if (p[0] == 'E') lon = 'E';
else if (p[0] == ',') lon = 0;
else return false;
}
// speed
p = strchr(p, ',')+1;
speed = atof(p);
if (',' != *p)
{
speed = atof(p);
}
// angle
p = strchr(p, ',')+1;
angle = atof(p);
if (',' != *p)
{
angle = atof(p);
}
p = strchr(p, ',')+1;
uint32_t fulldate = atof(p);
day = fulldate / 10000;
month = (fulldate % 10000) / 100;
year = (fulldate % 100);
if (',' != *p)
{
uint32_t fulldate = atof(p);
day = fulldate / 10000;
month = (fulldate % 10000) / 100;
year = (fulldate % 100);
}
// we dont parse the remaining, yet!
return true;
}