mirror of
https://github.com/ALLFATHER-BV/wadamesh.git
synced 2026-10-15 01:57:35 +00:00
touch: GPS page says what it is actually doing, not just "acquiring..."
The GPS settings page showed "GPS: acquiring..." and nothing else until a fix
landed. That single string covers two completely different situations: a receiver
happily tracking satellites that needs another minute, and a receiver that is not
talking at all. They look identical to the user, so there is no way to tell a
working device from a broken one by looking at it. That ambiguity is what turned a
healthy T-Display P4 GPS into a long investigation.
While acquiring, the page now shows:
- how long it has been searching, so a stuck receiver is obvious from elapsed
time alone rather than from staring at an unchanging word;
- whether the receiver has decoded satellite TIME. That is the useful tell: a
GPS decodes time/date off the air well before it has enough satellites to
solve a position, so valid time with no fix is positive proof the antenna and
the UART are fine and it is genuinely mid-acquisition. The wording then points
at sky view, which is the actual remedy;
- and when there is no satellite data at all, it says so plainly instead of
implying progress.
On a fix it now also shows altitude alongside the satellite count and position,
and the count is only printed when non-zero (it is satellites USED, so a bare
"0 sats" read as a fault).
Not included, and worth being clear about: satellites IN VIEW and per-satellite
SNR are NOT reachable from this repo. The core's MicroNMEALocationProvider keeps
its MicroNMEA object private and LocationProvider exposes only fix / sats-used /
lat / lon / alt / timestamp, so a full sky view needs a monorepo core change plus
a core-* tag bump. The boot probe added in bdc0c7f prints that data over serial in
the meantime.
Builds clean on V4, T-Deck and the P4; flashed and boot-verified on the P4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bdc0c7ffb6
commit
5c9f9cffef
+61
-9
@@ -2237,18 +2237,51 @@ static bool settingsModalIsOpen() { return g_set_modal.root != nullptr; }
|
||||
|
||||
// Compact one-line GPS status for the Device settings panel + control center.
|
||||
// TR("GPS: off") / "GPS: searching · N sats" / "GPS: fix · N sats <lat>, <lon>".
|
||||
// Stamped when acquisition starts so the page can show how long it has been searching; a stuck
|
||||
// receiver is then obvious from the elapsed time alone. Cleared on fix and when GPS is off.
|
||||
static uint32_t s_gps_acq_since = 0;
|
||||
|
||||
static const char* gpsStatusStr() {
|
||||
static char s[72];
|
||||
if (!g_lv.task || !g_lv.task->getGPSState()) { snprintf(s, sizeof s, TR("GPS: off")); return s; }
|
||||
// satellitesCount() is satellites USED IN THE FIX (0 until a lock), so during
|
||||
// cold acquisition it stays 0 — show "acquiring…" rather than a misleading
|
||||
// "0 sats". On lock, show the sat count + the (auto-populated) coordinates.
|
||||
if (!g_lv.task->getGpsFix()) { snprintf(s, sizeof s, TR("GPS: acquiring...")); return s; }
|
||||
static char s[200];
|
||||
if (!g_lv.task || !g_lv.task->getGPSState()) {
|
||||
s_gps_acq_since = 0;
|
||||
snprintf(s, sizeof s, TR("GPS: off"));
|
||||
return s;
|
||||
}
|
||||
// satellitesCount() is satellites USED IN THE FIX, so it stays 0 through a cold acquisition and
|
||||
// a bare "0 sats" would read as broken. The old line therefore said only "acquiring...", which
|
||||
// is just as unhelpful: it cannot distinguish a receiver happily tracking satellites that needs
|
||||
// another minute from one that is not talking at all. Both looked identical to the user, and
|
||||
// that ambiguity is exactly what cost a long P4 investigation.
|
||||
//
|
||||
// The tell is TIME. A receiver decodes satellite time/date well before it has enough satellites
|
||||
// to solve a position, so "no fix but valid GPS time" is positive proof that the antenna and the
|
||||
// link are fine and it is genuinely mid-acquisition.
|
||||
if (!g_lv.task->getGpsFix()) {
|
||||
const uint32_t now = millis();
|
||||
if (!s_gps_acq_since) s_gps_acq_since = now;
|
||||
const uint32_t secs = (now - s_gps_acq_since) / 1000u;
|
||||
const bool has_time = g_lv.task->getGpsTime() != 0;
|
||||
int n = snprintf(s, sizeof s, TR("GPS: searching"));
|
||||
if (n < (int)sizeof s) {
|
||||
if (secs < 600) n += snprintf(s + n, sizeof s - n, " %lum%02lus", (unsigned long)(secs / 60), (unsigned long)(secs % 60));
|
||||
else n += snprintf(s + n, sizeof s - n, " %lum", (unsigned long)(secs / 60));
|
||||
}
|
||||
if (n < (int)sizeof s) {
|
||||
snprintf(s + n, sizeof s - n, "\n%s", has_time
|
||||
? TR("Receiver OK, satellite time decoded. Waiting for enough satellites - needs a clear view of the sky.")
|
||||
: TR("No satellite data yet. Outdoors with a clear view of the sky it should appear within a few minutes."));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
s_gps_acq_since = 0;
|
||||
const int sats = g_lv.task->getGpsSats();
|
||||
const int alt = g_lv.task->getGpsAltitude();
|
||||
int n = snprintf(s, sizeof s, TR("GPS: fix"));
|
||||
if (sats >= 0 && n < (int)sizeof s) n += snprintf(s + n, sizeof s - n, " · %d sats", sats);
|
||||
if (sats > 0 && n < (int)sizeof s) n += snprintf(s + n, sizeof s - n, " · %d sats", sats);
|
||||
if (alt && n < (int)sizeof s) n += snprintf(s + n, sizeof s - n, " · %d m", alt);
|
||||
if (n < (int)sizeof s)
|
||||
snprintf(s + n, sizeof s - n, " %.5f, %.5f",
|
||||
snprintf(s + n, sizeof s - n, "\n%.5f, %.5f",
|
||||
g_lv.task->getNodeLat(), g_lv.task->getNodeLon());
|
||||
return s;
|
||||
}
|
||||
@@ -11498,7 +11531,8 @@ static void buildDeviceSettings(int sec) {
|
||||
lv_obj_set_style_text_font(g_set_modal.gps_status, &g_font_12, LV_PART_MAIN);
|
||||
lv_obj_set_pos(g_set_modal.gps_status, 4, y);
|
||||
lv_label_set_text(g_set_modal.gps_status, gpsStatusStr());
|
||||
y += SC(22);
|
||||
lv_obj_update_layout(g_set_modal.gps_status);
|
||||
y += LV_MAX(SC(22), lv_obj_get_height(g_set_modal.gps_status) + SC(6)); // status is 2 lines now
|
||||
|
||||
// (Expansion Kit moved to the Sensors page — see the DSEC_SENSORS block below.)
|
||||
|
||||
@@ -45223,6 +45257,24 @@ int UITask::getGpsSats() {
|
||||
return lp ? (int)lp->satellitesCount() : -1;
|
||||
}
|
||||
|
||||
uint32_t UITask::getGpsTime() {
|
||||
if (!_sensors) return 0;
|
||||
LocationProvider* lp = _sensors->getLocationProvider();
|
||||
if (!lp) return 0;
|
||||
const long t = lp->getTimestamp();
|
||||
// The provider builds this from the NMEA date/time fields, which read as year 0 (epoch far in
|
||||
// the past) until the receiver has actually decoded them off the air. Anything plausibly recent
|
||||
// means real satellite time.
|
||||
return (t > 1700000000L) ? (uint32_t)t : 0;
|
||||
}
|
||||
|
||||
int UITask::getGpsAltitude() {
|
||||
if (!_sensors) return 0;
|
||||
LocationProvider* lp = _sensors->getLocationProvider();
|
||||
if (!lp || !lp->isValid()) return 0;
|
||||
return (int)(lp->getAltitude() / 1000); // provider reports millimetres
|
||||
}
|
||||
|
||||
// Keep the node's advertised location synced to GPS once we have a fix, and
|
||||
// persist it occasionally so a fix survives reboot ("had a fix at least once").
|
||||
// Called every UITask::loop(). No-op on boards without GPS (provider == NULL).
|
||||
|
||||
@@ -459,6 +459,13 @@ public:
|
||||
bool getGpsFix();
|
||||
/** Satellites currently in view, or -1 if unknown / no GPS hardware. */
|
||||
int getGpsSats();
|
||||
/** UTC epoch the GPS itself has decoded, or 0 if it has none yet. A receiver decodes TIME from
|
||||
* the satellite stream well before it can solve a POSITION, so a valid time with no fix is
|
||||
* positive proof the module is alive and tracking, not dead. That is the distinction the GPS
|
||||
* page could not previously show, and it is what "acquiring..." was hiding. */
|
||||
uint32_t getGpsTime();
|
||||
/** Altitude in metres from the last fix (0 when there is no fix). */
|
||||
int getGpsAltitude();
|
||||
/** True once a valid fix has been seen this session. */
|
||||
bool getGpsHadFix() const { return _gps_had_fix; }
|
||||
double getNodeLat() const { return _sensors ? _sensors->node_lat : 0.0; }
|
||||
|
||||
Reference in New Issue
Block a user