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