Exercise 9 now acquires satellites, more to do for this exercise, e.g. logging and RTC time setting

This commit is contained in:
John Poole 2026-02-17 11:12:31 -08:00
commit 21825c09c6
3 changed files with 73 additions and 14 deletions

View file

@ -2,10 +2,17 @@
This exercise boots the T-Beam Supreme and verifies GPS behavior at startup.
Important sequence note:
- Exercise 10 (`10_Simple_GPS`) should be completed before this exercise.
- Exercise 10 README contains the detailed pin-configuration explanation and troubleshooting rationale for why explicit GPS pin mapping is critical on this hardware.
- If GPS behavior is unexpected here, review Exercise 10 README first, then return to Exercise 9.
Implemented behavior:
1. Initializes PMU, OLED, and SD startup watcher (same startup SD path used in Exercise 08).
2. Probes GPS at startup for NMEA traffic, module identity, satellite count, and UTC time availability.
- Uses explicit GPS UART pins and an active startup probe (multi-baud + common GPS query commands), aligned with the approach validated in Exercise 10.
3. If L76K is detected, normal GPS-time flow continues.
4. If L76K is not detected and Quectel-style module text is detected, OLED shows a hard TODO error:
- Quectel detected

View file

@ -23,6 +23,10 @@ build_flags =
-D OLED_SDA=17
-D OLED_SCL=18
-D OLED_ADDR=0x3C
-D GPS_RX_PIN=9
-D GPS_TX_PIN=8
-D GPS_WAKEUP_PIN=7
-D GPS_1PPS_PIN=6
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1

View file

@ -40,6 +40,7 @@ static HardwareSerial g_gpsSerial(1);
static uint32_t g_logSeq = 0;
static uint32_t g_lastMinuteReportMs = 0;
static uint32_t g_gpsBaud = GPS_BAUD;
static bool g_prevHadSatellites = false;
static bool g_prevHadValidUtc = false;
@ -328,6 +329,59 @@ static void pollGpsSerial() {
}
}
static void startGpsUart(uint32_t baud) {
g_gpsSerial.end();
delay(20);
g_gpsSerial.setRxBufferSize(1024);
g_gpsSerial.begin(baud, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
g_gpsBaud = baud;
}
static bool collectGpsTraffic(uint32_t windowMs, bool updateSd) {
uint32_t start = millis();
size_t bytesSeen = 0;
while ((uint32_t)(millis() - start) < windowMs) {
while (g_gpsSerial.available() > 0) {
(void)g_gpsSerial.read();
bytesSeen++;
}
pollGpsSerial();
if (updateSd) {
g_sd.update();
}
delay(2);
}
return bytesSeen > 0 || g_gps.sawAnySentence;
}
static bool probeGpsAtBaud(uint32_t baud) {
startGpsUart(baud);
logf("Probing GPS at %lu baud...", (unsigned long)baud);
if (collectGpsTraffic(700, true)) {
return true;
}
// Common commands for MTK/L76K and related chipsets.
g_gpsSerial.write("$PCAS06,0*1B\r\n");
g_gpsSerial.write("$PMTK605*31\r\n");
g_gpsSerial.write("$PQTMVERNO*58\r\n");
g_gpsSerial.write("$PMTK353,1,1,1,1,1*2A\r\n");
g_gpsSerial.write("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n");
return collectGpsTraffic(1200, true);
}
static void initialGpsProbe() {
const uint32_t bauds[] = {GPS_BAUD, 115200, 38400, 57600, 19200};
for (size_t i = 0; i < sizeof(bauds) / sizeof(bauds[0]); ++i) {
if (probeGpsAtBaud(bauds[i])) {
logf("GPS traffic detected at %lu baud", (unsigned long)g_gpsBaud);
return;
}
}
logf("No GPS traffic detected during startup probe");
}
static uint8_t bestSatelliteCount() {
return (g_gps.satsUsed > g_gps.satsInView) ? g_gps.satsUsed : g_gps.satsInView;
}
@ -448,25 +502,17 @@ void setup() {
}
#ifdef GPS_WAKEUP_PIN
pinMode(GPS_WAKEUP_PIN, OUTPUT);
digitalWrite(GPS_WAKEUP_PIN, HIGH);
// Keep wake pin neutral; avoid forcing an unknown standby state.
pinMode(GPS_WAKEUP_PIN, INPUT);
#endif
#ifdef GPS_1PPS_PIN
pinMode(GPS_1PPS_PIN, INPUT);
#endif
#ifdef GPS_RX_PIN
#ifdef GPS_TX_PIN
g_gpsSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
#else
g_gpsSerial.begin(GPS_BAUD);
#endif
#else
g_gpsSerial.begin(GPS_BAUD);
#endif
logf("GPS UART started at %u baud", (unsigned)GPS_BAUD);
startGpsUart(GPS_BAUD);
logf("GPS UART started: RX=%d TX=%d baud=%lu", GPS_RX_PIN, GPS_TX_PIN, (unsigned long)g_gpsBaud);
initialGpsProbe();
oledShowLines("GPS startup probe", "Checking satellites", "and GPS time...");
@ -481,9 +527,11 @@ void setup() {
lastProbeUiMs = now;
char l3[28];
char l4[30];
char l5[24];
snprintf(l3, sizeof(l3), "Sats: %u", (unsigned)bestSatelliteCount());
snprintf(l4, sizeof(l4), "Module: %s", gpsModuleToString(g_gps.module).c_str());
oledShowLines("GPS startup probe", "Checking satellites", l3, l4);
snprintf(l5, sizeof(l5), "NMEA:%s %lu", g_gps.sawAnySentence ? "yes" : "no", (unsigned long)g_gpsBaud);
oledShowLines("GPS startup probe", "Checking satellites", l3, l4, l5);
}
delay(10);
}