Issues with extracting the fix data using custom NMEA sentence extraction
Opened this issue · 8 comments
I'm trying to extract the GPS Fix data using the custom NMEA sentence extraction but it does not seem to work.
The GPS fix data is present in the GNGGA sentence as the 6th element. In the code, I have,
TinyGPSPlus gps;
TinyGPSCustom fixStatus(gps, "GNGGA", 6);
and in the loop() function, I have,
Serial.print("Fix status: "); Serial.println(fixStatus.value());
However, I do not see 1
though the GPGGA sentence does show it,
$GNGGA,125322.00,xxxx.xxxxx,X,xxxx.xxxxx,X,1,11,0.78,560.0,M,-68.1,M,,*68
The full code is here.
Using GNGGA means you want GLONASS navigation.
Are you using a current version of TinyGPS?
GLONASS support was added later: ba91ede
I never realised that I was using an older version - 1.0.2
. I added the library from the Arduino IDE and assumed it would be the latest version. I've now updated to the latest release. I still do not see the fix value. Also, I accidentally set the 5th value to be extracted (instead of 6th) and it showed me -68.1
. In the GNGGA sentence that is the 11th value. Something is not quite right!
@classbproject I use the following code with good success to determine the fix and validity of my received data:
TinyGPSPlus gnss;
// Custom TinyGPS objects to store fix and validity information
TinyGPSCustom gnssFix(gnss, "GNGGA", 6); // Fix quality
TinyGPSCustom gnssValidity(gnss, "GNRMC", 2); // Validity
And then to check if the sentences are valid, I check the custom fix and validity values, as well as the number of satellites:
// Check if NMEA sentences have a valid fix and are not stale
if ((gnssFix.value() > 0 && gnssFix.age() < 1000) &&
(String(gnssValidity.value()) == "A" && gnssValidity.age() < 1000) &&
gnss.satellites.value() > 0)
{
Cheers,
Adam
// Check if NMEA sentences have a valid fix and are not stale
if ((gnssFix.value() > 0 && gnssFix.age() < 1000) &&
(String(gnssValidity.value()) == "A" && gnssValidity.age() < 1000) &&
gnss.satellites.value() > 0)
{
This doesn't make sense to me, since it adds overhead to calculate a status which is already processed by TinyGPS. Simply check if location.isValid()
and/or altitude.isValid()
. TinyGPS commits these values, if a fix was present when these values arrived.
To detect a fix TinyGPS does exactly the same as your code suggests:
case COMBINE(GPS_SENTENCE_GPRMC, 2): // GPRMC validity
sentenceHasFix = term[0] == 'A';
case COMBINE(GPS_SENTENCE_GPGGA, 6): // Fix data (GPGGA)
sentenceHasFix = term[0] > '0';
I am using this approach:
https://github.com/hottimuc/Lora-TTNMapper-T-Beam/blob/master/fromV08/gps.cpp#L67
Thanks for your input.
To give you some background, I previously had an issue with the validity check I was using where I would lose contact with my instruments for a month.
if ((gps.location.isValid() && gps.date.isValid() && gps.time.isValid()) &&
(gps.location.isUpdated() && gps.date.isUpdated() && gps.time.isUpdated())) {}
Somehow, data with incorrect dates were making it past the check and causing havoc with my real-time clock alarms. I spoke to Mikal directly about this and it turns out date.isValid()
and time.isValid()
are not very rigorous and can easily report an incorrect date and/or time as valid.
After that, I started doing things explicitly myself to ensure the validity check worked. I don't mind the redundancy.
Cheers,
Adam
isValid() means the data was seen by TinyGPS in a sentence with fix. It does not mean the sentence is not stale. Thus, you should combine this with checking the age of the sentence. That's all. See my example.
Thanks for your feedback. Glad to have confirmation my code above is the correct (albeit redundant) approach.
@classbproject I use the following code with good success to determine the fix and validity of my received data:
TinyGPSPlus gnss; // Custom TinyGPS objects to store fix and validity information TinyGPSCustom gnssFix(gnss, "GNGGA", 6); // Fix quality TinyGPSCustom gnssValidity(gnss, "GNRMC", 2); // Validity
And then to check if the sentences are valid, I check the custom fix and validity values, as well as the number of satellites:
// Check if NMEA sentences have a valid fix and are not stale if ((gnssFix.value() > 0 && gnssFix.age() < 1000) && (String(gnssValidity.value()) == "A" && gnssValidity.age() < 1000) && gnss.satellites.value() > 0) {
Cheers, Adam
@adamgarbo My apologies for the delayed response. I got a chance to work on this again now. I saw your comment on another thread for the fix check. For some reason the custom TinyGPS function won't work. I need to do more experiments to see why that won't work. This was a hardware issue that I've now fixed. Both the versions work. Thanks.
bool checkGPSFix()
{
while ((gpsSerial.available() > 0))
{
if (gps.encode(gpsSerial.read()))
{
if ((gps.location.isValid() && gps.date.isValid() && gps.time.isValid()) &&
(gps.location.isUpdated() && gps.date.isUpdated() && gps.time.isUpdated()) &&
(gps.satellites.value() > 0))
{
fixStatus = true;
Serial.print("Fix status: ");
Serial.println(fixStatus);
return fixStatus;
}
}
}
return 0;
}
void setup()
{
Serial.begin(serialBaud);
gpsSerial.begin(gpsBaud);
// Check if NMEA sentences have a valid fix and are not stale
Serial.println("\nWaiting for valid GPS signal...");
while (!checkGPSFix())
{
;
}
Serial.println("Valid GPS signal established.");
}