Public Access
custom_sdkconfig makes pioarduino regenerate the ESP-IDF libraries: asymmetric TLS buffers (16 KB in, 4 KB out) and dynamic buffers that free handshake-only data once connected. The rebuild also follows the board: no PSRAM, 8 MB flash. The project now carries the partition table the hybrid build needs (identical to the framework's: the app slots must not move under updates over the air). Generated files are ignored. Debug Build, GNSS on, IRC on TLS: 78 KB free and a 59 KB low (M2 began at 31 KB and 12.6 KB; the floor is 40 KB). The full stress set passes on it: refused installs over Wi-Fi and from SD, put/get, screenshot, core dump decode, Probation; under all of it at once, the low is 46 KB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
60 lines
6.0 KiB
Markdown
60 lines
6.0 KiB
Markdown
# M2 — GNSS
|
||
|
||
**Status:** done on the device (branch `m2`): every "Done when" item below is met.
|
||
|
||
## Measured
|
||
|
||
- **Cold start** (`$PCAS10,2`) to a 3D Fix, by a window: **73 s**, 5 satellites used of 8 in view. A restart of the ESP32 alone keeps the receiver's Fix (the Cap stays powered).
|
||
- By a window: 3D Fix from GPS, GLONASS, Galileo and BeiDou, up to 14 of 17 satellites used, HDOP 1.0–1.3.
|
||
- **Heap, Debug Build, GNSS on, IRC on TLS** (floor 40 KB; v0.2.1 had a 79 KB low):
|
||
|
||
| | Free | Lowest |
|
||
|---|---|---|
|
||
| Start of M2 | 31 KB | 12.6 KB |
|
||
| Stacks and buffers trimmed by measurement | 46 KB | 18 KB |
|
||
| mDNS removed | 54 KB | 34 KB |
|
||
| Framework rebuilt with smaller TLS buffers (ADR 0006) | **78 KB** | **59 KB** |
|
||
|
||
Under the heaviest combined load measured (IRC, two refused installs, a 1.6 MB put and get), the low is 46 KB. The cost had come mostly from the OTA and Debug Build work, not GNSS. Stacks were set to measured peak plus about 2 KB (loop 6 KB, update 5, storage 6, irc 6); after a TLS handshake the irc task has 1.7 KB left. IRC can now be stopped by hand (`/quit` in any state, `irc stop`), which frees its TLS memory.
|
||
|
||
**Goal:** the device knows where it is and what time it is without a network: a GNSS Service in the background, a GNSS App with the position and a sky view of the satellites, the clock set from satellites when there's no NTP, and Tracks recorded to the SD card.
|
||
|
||
**Hardware:** the Cap LoRa-1262 carries an ATGM336H-6N (AT6668), multi-constellation (GPS, BeiDou, Galileo, GLONASS, QZSS), with a ceramic antenna. NMEA over UART, 115200 8N1. **Measured (step 1, `gnss probe`): RX GPIO 15, TX GPIO 13, 115200 8N1**, as in Meshtastic's board file; M5Stack's page names GPIO 8 and 9, which are the internal I2C bus the keyboard controller sits on. Output is NMEA 4.10 style: `GN` RMC, VTG and GGA, one GSA per constellation with the system ID (1 GPS, 2 GLONASS, 3 Galileo, 4 BeiDou, 5 QZSS) in its last field, and a GSV sequence per constellation and signal (`GP`, `GL`, `GA`, …) with the signal ID last. RMC carries a time even without a Fix (status `V`), so only a Fix makes it trustworthy.
|
||
|
||
## Decisions (design round 2026-10-04)
|
||
|
||
| # | Decision |
|
||
|---|---|
|
||
| Q58 | Settings has a GNSS On/Off switch, **On by default**. Off puts the receiver in standby. *Measured:* `$PCAS12,<seconds>` (CASIC) stops its output within a second, for up to at least 65535 s, and any command wakes it within a second; Off sends `PCAS12,65535` (renewed hourly), On sends a hot start, `PCAS10,0`. |
|
||
| Q59 | The **GNSS App** has two views, switched with Tab. *Position*: latitude, longitude, altitude, speed, course, Fix (none / 2D / 3D), satellites used and in view, HDOP, UTC time. *Sky*: the satellites placed by azimuth and elevation, coloured by constellation, filled when used in the Fix. |
|
||
| Q60 | "Radar" in M2 means the Sky view. A radar of other Nodes by distance and bearing needs the mesh: M4. |
|
||
| Q61 | The **Status Bar** shows a GNSS mark: absent when off, muted while searching, normal with a 2D Fix, with the satellite count with a 3D Fix. |
|
||
| Q62 | GNSS time **sets the clock once there's a Fix**, and refreshes it every 10 minutes. *Revised in step 3:* the clock's trust order from M0 (Mesh < NTP < GNSS) already ranks GNSS above NTP, which is right: GNSS time is at least as accurate. So GNSS also corrects a clock NTP set, not only an unset one. |
|
||
| Q63 | A **Track** is started and stopped in the GNSS App. It's written as GPX to `/gnss/tracks/<YYYYMMDD-HHMMSS>.gpx`, a point every 5 s when the position moved more than 5 m. It keeps recording with the App closed, with a Toast on start and stop and a Status Bar mark, and gets its own Storage Clean-up category. |
|
||
| Q64 | Coordinates in **decimal degrees plus the Maidenhead locator**; a Settings switch for degrees, minutes and seconds. Metric units only. |
|
||
| Q65 | **The position never leaves the device in M2.** Sharing it over the mesh, and at what precision, is decided in M4. |
|
||
| Q66 | **Our own NMEA parser**, host-tested: RMC, GGA, GSA and GSV, with each talker ID mapped to its constellation. TinyGPSPlus (named in ADR 0001) doesn't track the satellite list across constellations, which the Sky view needs. |
|
||
| Q67 | The receiver keeps its **defaults** (all constellations, 1 Hz). No receiver settings. Time to first fix is measured and recorded here. |
|
||
| Q68 | Debug aids: `gnss status`, and `gnss nmea on/off` to stream the raw sentences to the console (USB serial and Debug Console). Raw NMEA is never written to the card. |
|
||
|
||
**Lesson (step 3):** the first probe also tried the pins swapped, driving the receiver's output line from the ESP32 for about a second. The receiver then went silent until a full power cycle (an ESP32 restart doesn't cut the Cap's power). Never drive GPIO 15.
|
||
|
||
## Done when
|
||
|
||
- The GNSS Service reads NMEA in the background whatever App is on screen, and a 3D Fix appears outdoors.
|
||
- The GNSS App shows the Position and Sky views, both live.
|
||
- The Status Bar shows the GNSS mark per Q61.
|
||
- With no Wi-Fi, the clock is set from GNSS after the first Fix.
|
||
- A Track records while the App is closed, survives the screen turning off, and opens as valid GPX on the PC.
|
||
- Settings → GNSS Off stops it (and the Status Bar mark goes away); On brings it back.
|
||
- Free heap stays above about 40 KB with GNSS, Wi-Fi, IRC on TLS and the UI running.
|
||
|
||
## Work breakdown
|
||
|
||
1. **Hardware check:** a `gnss probe` command reads the candidate UART pins and reports which carries NMEA, at what baud rate, and which talker IDs. Then the standby command (Q58) and a first time to first fix.
|
||
2. **NMEA parser** (host-tested): checksum, RMC, GGA, GSA, GSV across constellations, merged into one GNSS state (Fix, position, time, satellites).
|
||
3. **GNSS Service:** UART on its own task, the parser, `gnss status` and `gnss nmea`, Settings On/Off.
|
||
4. **Clock from GNSS** (Q62), and the Status Bar mark (Q61).
|
||
5. **GNSS App:** Position view, Maidenhead and coordinate formats (host-tested), then the Sky view.
|
||
6. **Tracks:** the 5 s / 5 m rule and GPX writing (host-tested), background recording, Clean-up category.
|