From 9bf8f92df591e8634b62fe3bc278ff64f03f3dec Mon Sep 17 00:00:00 2001 From: Martin Boissonneault <19229816+Ve2mrx@users.noreply.github.com> Date: Sat, 14 Nov 2026 18:23:54 -0500 Subject: [PATCH] gps: don't let the settle time close a periodic window before the time sync In periodic mode a window closed after GPS_FIX_SETTLE_MS (10 s) from the first fix even if the clock sync was still pending. The sync needs about 4 s of continuous valid fixes (time_valid > 2, reset on any pass without a fix), so after a hot start, when the receiver reports a fix within seconds but not yet steadily, the window could close unsynced. On a board without an RTC the clock then stays at its default until the next window, a whole period later. Close the window only once the sync has been tried (done, not needed, or refused by GPS_GUARD); the settle time and the satellite count apply after that. The acquisition timeout still bounds the window. Co-Authored-By: Claude Opus 5.5 --- src/helpers/sensors/MicroNMEALocationProvider.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/helpers/sensors/MicroNMEALocationProvider.h b/src/helpers/sensors/MicroNMEALocationProvider.h index 34480b4582..85262ba42e 100644 --- a/src/helpers/sensors/MicroNMEALocationProvider.h +++ b/src/helpers/sensors/MicroNMEALocationProvider.h @@ -169,6 +169,12 @@ class MicroNMEALocationProvider : public LocationProvider { if (isValid()) time_valid++; } + // the time sync has had its chance: done, not needed, or refused by GPS_GUARD. + // updateTime() tries it on the tick where time_valid goes from 3 to 4. + bool timeSyncSettled() const { + return _clock == nullptr || !_time_sync_needed || time_valid > 3; + } + bool timeSyncAllowed() { #ifdef GPS_GUARD return _guard.acceptTime(getTimestamp(), _clock->getCurrentTime()); @@ -403,10 +409,13 @@ class MicroNMEALocationProvider : public LocationProvider { const uint8_t mode = currentFixMode(); if (mode == 0 || mode == 3) _goodFixInWindow = true; if (_acquiringPeriodically && _goodFixInWindow) { - // stay on until a pending time sync is done (or the settle time is over) - const bool synced = _clock == nullptr || !_time_sync_needed; - if ((nmea.getNumSatellites() >= GPS_MIN_SATS_FOR_FIX && synced) || - (uint32_t)(millis() - _firstFixInWindow) >= GPS_FIX_SETTLE_MS) { + // stay on until a pending time sync has been tried, even past the settle + // time: after a hot start the fix can come before the time is steady, and + // the window would close unsynced until the next period. The acquisition + // timeout below still bounds it. + if (timeSyncSettled() && + (nmea.getNumSatellites() >= GPS_MIN_SATS_FOR_FIX || + (uint32_t)(millis() - _firstFixInWindow) >= GPS_FIX_SETTLE_MS)) { finishPeriodicAcquisition(); } }