mikalhart / TinyGPSPlus

A new, customizable Arduino NMEA parsing library
http://arduiniana.org
1.05k stars 486 forks source link

Date and time invalid but return true. #70

Open eyesblue opened 4 years ago

eyesblue commented 4 years ago

Thanks for your great project first, it easy to use but not correct for my project.

I need get date and time from GPS, it runs correct at first time turn on the power, but after turn off power maybe few hour, my program get date and time from GPS module next time, it show me 1970/1/1 0h/0m/0s and these function still return true:

gps.date.isValid() gps.time.isValid()

please check the code, thx.

lumonic commented 4 years ago

Yeah, I am having the same issue.

GPS is returning 2000/0/0 as a date and it is saying this is valid.

TD-er commented 4 years ago

The $GPRMC sentence does provide the time- and date- stamp. It also has a flag for validity. So maybe this flag is also used on the timestamp?

A simple check in this library could be to test if the reported date is past the build time. But on the other hand I've also seen reported time stamps of way into the future which would not be filtered out by such a check.

lumonic commented 4 years ago

It look like the meaning of "valid" is that the value has been updated. Not terribly useful.

void TinyGPSDate::commit() { date = newDate; lastCommitTime = millis(); valid = updated = true; }

viktak commented 3 years ago

Same problem here...

TD-er commented 3 years ago

Maybe this part of the code: https://github.com/mikalhart/TinyGPSPlus/blob/b4c8e29d1def35806fb1fc75fe0013036843d643/src/TinyGPS%2B%2B.cpp#L173-L182

Should be changed into:

      case GPS_SENTENCE_GPRMC:
        if (sentenceHasFix)
        {
           date.commit();
           time.commit();
           location.commit();
           speed.commit();
           course.commit();
        }
        break;

The same applies for the GPS_SENTENCE_GPGGA case where the time.commit() is called.

TD-er commented 3 years ago

OK, I've dug a bit more into this and a pull request will be made soon. There is a number of places where we can add some sanity check for the validity of the data.

Not sure how, but I've found in my own data some flukes which have lat/long coordinates of several 1000's and as mentioned in this issue the time stamp could also be somewhat random data and still considere to be valid.

So very simple checks can be to test the degrees of lat/long not to exceed 90 resp. 180 degree. The decimals of time and date can also be checked as 123456 for example can never be a valid date (as there is no 34th month) and similar 234567 can never be a valid time.

xfdr0805 commented 3 years ago

I am having the same issue

adamgarbo commented 2 years ago

I also encountered this issue recently in the field. I was relying on the GPS (Adafruit Ultimate GPS) to periodically synchronize the RTC of a microcontroller (Adafruit Feather M0).

Despite using the following check to determine if the message was valid, in some cases I received a "valid" datetime of January 8, 2019. This ended up producing some major issues with timing and alarms.

if ((gps.location.isValid() && gps.date.isValid() && gps.time.isValid()) &&
    (gps.location.isUpdated() && gps.date.isUpdated() && gps.time.isUpdated()))

I ended up adding an additional check for the number of satellites, which appeared to resolve the issue. It seemed that the bad "valid" data only occurred when the number of satellites was zero.

(gps.satellites.value() > 0)

I am also very much in favour of having additional sanity checks for the date and time.

Cheers, Adam