Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NMEA senteces not valid? #155

Open
RodEnry opened this issue Dec 7, 2021 · 2 comments
Open

NMEA senteces not valid? #155

RodEnry opened this issue Dec 7, 2021 · 2 comments

Comments

@RodEnry
Copy link

RodEnry commented Dec 7, 2021

Hello guys,
I'm trying to figure out why my GPS sometimes throws strange values.
An example on LAT:
......................
345129181
345129183
444
345129184
345129182
......................

First of all, I'm running an Ublox SAM-M8Q gps module with an ESP32 microcontroller.
The GPS is set to 10Hz and a baudrate of 240400. To set everything I'm using this init function:

void initGPS() {
    uint8_t ubx10Hz[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0x64, 0x00, 0x01, 0x00, 0x01, 0x00, 0x7A, 0x12};

    uint8_t ubx240400badurate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 
    0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x84, 0x03, 
    0x00, 0x23, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xC8};

    GPS_Serial.begin(9600, SERIAL_8N1, RXD2, TXD2);

    //Set baudrate and refresh rate to 10Hz
    GPS_Serial.write(ubx10Hz, sizeof(ubx10Hz));
    GPS_Serial.flush(); 
    GPS_Serial.write(ubx240400badurate, sizeof(ubx240400badurate));
    GPS_Serial.flush(); 
    delay(10);
    GPS_Serial.end();

    //Restart UART with the new baudrate
    GPS_Serial.begin(240400, SERIAL_8N1, RXD2, TXD2);
    GPS_Serial.write(ubx240400badurate, sizeof(ubx240400badurate));
    GPS_Serial.flush(); 
    GPS_Serial.write(ubx10Hz, sizeof(ubx10Hz));
    GPS_Serial.flush(); 

}

I'm logging the data into an SD card (which is very fast). My original code was without the "if" statemets and I add them just for debugging purposes.
The loop is:

while (gps.available( GPS_Serial )) {
            currentFix = gps.read();
        } 

        if (currentFix.valid.location) {
            myStruct.lat = currentFix.location.lat();
            myStruct.lng = currentFix.location.lon();
        } else {
            Serial.print(" -NOT VALID LOCATION -");
        }
        if(currentFix.valid.altitude) {
            myStruct.meters = currentFix.altitude();
        } else {
            Serial.print(" -NOT VALID ALTITUDE -");
        }
        if(currentFix.valid.speed) {
            myStruct.gpsSpeed = currentFix.speed_kph();
        } else {
            Serial.println(" -NOT VALID SPEED -");
        }   

        Serial.print("  SATELL "); Serial.print(currentFix.satellites);
        Serial.print("  LAT "); Serial.print(currentFix.location.lat());
        Serial.print("  LAT "); Serial.print(currentFix.location.lon());
        Serial.print("  ALT "); Serial.print(currentFix.altitude());
        Serial.print("  SPEED "); Serial.print(currentFix.speed_kph());
        Serial.print("  TIME "); Serial.print(currentFix.dateTime.seconds);
        Serial.println("");

The consolle output is pretty strange. I can clearly see that the FIX was not valid, but the printed values of LAT,LON,ALT,SPEED are constantly updated!
image

@danalvarez
Copy link

danalvarez commented Dec 7, 2021

A couple things:

  1. If the fix is not valid, you shouldn't trust the information provided by calls to lat(), lon() and the likes. I am not sure what happens under the hood in NeoGPS when a fix is not valid.
  2. Even though the fix is invalid, do the reported values make sense for your geographical location?

Also, you would typically access lat and lon values via currentFix.latitude() and currentFix.longitude(), not via currentFix.location.latitude() as you are doing in your code. More info here: https://github.com/SlashDevin/NeoGPS/blob/master/extras/doc/Data%20Model.md

@RodEnry
Copy link
Author

RodEnry commented Dec 7, 2021

Hello @danalvarez ,
thanks for your clear reply.
The values definetly make sense! The GPS route is perfect, except for the strange values that sometimes happened.

Many thanks for your suggestion, I'll try to remove "location".

Another information: the while loop that read the GPS messages is inside a task that runs at 10Hz, exacly like the GPS. Is it possible that some timing issue is happening?

It's pretty strange the validation thing... but at the link you posted I can read:
"You should also know that, even though you have enabled a particular member (see GPSfix_cfg.h), it may not have a value until the related NMEA sentence sets it. And if you have not enabled that sentence for parsing in NMEAGPS_cfg.h, it will never be valid."

I'll need to change to true the two #defines?

//------------------------------------------------------
//  Becase the NMEA checksum is not very good at error detection, you can 
//    choose to enable additional validity checks.  This trades a little more 
//    code and execution time for more reliability.
//
//  Validation at the character level is a syntactic check only.  For 
//    example, integer fields must contain characters in the range 0..9, 
//    latitude hemisphere letters can be 'N' or 'S'.  Characters that are not 
//    valid for a particular field will cause the entire sentence to be 
//    rejected as an error, *regardless* of whether the checksum would pass.
#define NMEAGPS_VALIDATE_CHARS false

//  Validation at the field level is a semantic check.  For 
//    example, latitude degrees must be in the range -90..+90.
//    Values that are not valid for a particular field will cause the 
//    entire sentence to be rejected as an error, *regardless* of whether the 
//    checksum would pass.
#define NMEAGPS_VALIDATE_FIELDS false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants