Repository navigation
GPS power cycling between fixes (companion) 🤖🤖 - #3684
ajgray2017 wants to merge 6 commits into
Conversation
Battery companions with a GPS enable pin could only keep the GPS powered all the time or turn it off. - New sensor setting gps_duty (seconds between fixes, 0 = always on, default; max 86400) via the existing custom vars, persisted in NodePrefs (gps.duty) and re-applied in applyGpsPrefs(). - While GPS is on and gps_duty > 0: power on, wait for a fix, hold it GPS_DUTY_SETTLE_SECS (10 s) so the RTC syncs, store the position, power off, wake gps_duty seconds later. gps_active stays true throughout, so adverts/telemetry keep the last fix. gps_duty=0 behaves as before. - Optional GPS_DUTY_MAX_ON_SECS gives up without a fix (default 0). - OLED GPS page shows "gps on 5m" / "gps sleep 5m"; long-press on the GPS page cycles off -> on -> 1m -> 5m -> 15m -> 60m -> off (plain toggle if the board has no gps_duty). - Not applied to RAK WisBlock GPS boards. FAQ 5.17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With gps_duty > 0, loop() kept calling _location->loop() while the GPS was powered down. The NMEA parser still held the last fix (it is only cleared on wake), so isValid() stayed true, and the provider's 30-minute RTC re-sync could fire during the sleep and set the clock to the last fix's time: up to gps_duty seconds in the past (an hour with the 1h preset, a day at the 86400 maximum). Only run the parser while the GPS is powered, or when not duty cycling. The stored position is unaffected; it is copied before power-down. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
gps_duty was listed whenever a GPS was detected, so repeater and room server firmware showed it in "sensor list" and accepted "sensor set gps_duty N" with an immediate effect, but never saved it: the value was lost on reboot. Only the companion persists gps_duty. Follow the same opt-in as the runtime GPS pin settings: the setting is listed and accepted only after the firmware calls configureGPSDuty(), which the companion does from applyGpsPrefs(). ENV_GPS_DUTY_CYCLE moves to the header so the companion can test for it; boards whose sensor manager is not an EnvironmentSensorManager (e.g. Heltec Wireless Tracker) don't define it and are unaffected. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
On PERSISTANT_GPS boards initBasicGPS() leaves the GPS powered and sets gps_active without going through start_gps(), so gps_powered stayed false. With gps_duty > 0 the first loop then "woke" a GPS that was already on: a second begin()/reset() and parser clear right after boot, and an extra claim on the location provider. None of today's PERSISTANT_GPS boards (T-Beam, T-Beam 1W, ThinkNode M5) pass a shared power pin, so the extra claim had no effect yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The GPS page showed a 3600 s duty as "gps on 1h" while the long-press alert for the same preset said "GPS: 60m". Format both with one helper that picks the largest exact unit (s, m or h), and update the FAQ preset list to match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
gps_duty is listed on every board with a detected GPS, but it can only power the GPS down where the firmware controls its power (an enable pin or switched supply). Say so, and what it still does on other boards. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Totally agree with you, and we have had several attempts to implement duty cycle but sadly we didn't merge it lacking time to test on all boards ... I think the first step is to merge #1799 don't know if it will happen with this PR (because it is old and should have been taken care of sooner), but I want a clean frontier between LocationManager and EnvironmentSensors and things have not gone in the good way lately ... Then, when things are clearer we'll implement duty cycle in LocationManager and add cli commands to control it You're proposal is interesting but I prefer when we go small steps (and in first steps I don't see why we would make changes to the UI). Also we can use AI, but don't let it do everything as it seems to be the case with this PR. |
|
Thanks for this — we run a similar GPS duty cycle on a solar repeater (ProMicro + serial GNSS with EN pin) and can share some field notes:
We're also proposing a GPS anti-spoofing guard (#3733) that hooks into the same |
Take whatever youd like! i wrote this for myself, since the little heltec v3's I built didnt have huge batteries. @AlexandrTyshchenko |
|
Thanks @ajgray2017, much appreciated! My duty cycle lives in the repeater build for now, so it's good to see the same approach working on a companion. Per @fdlamotte's comment I'll wait for #1799 and then propose duty cycling as small steps on top of |
|
I might not wait for #1799 after all ... Hope to find time next week to refactor GPS, would like a clean interface for all the roles to use it and configure via cli then adding duty_cycle is easy #778 was close to what I wanted but we didn't finish it (and for some time back then I couldn't work on meshcore due to other things) |
|
Sounds good, @fdlamotte. A clean GPS interface shared by all roles is exactly what I was missing on the repeater side. Two small things it would help to leave room for, so I can port my PRs onto it instead of hooking into
#3729 (UART baud autodetect) would fit naturally into the NMEA provider's start-up. Happy to test the refactor on a ProMicro repeater with a serial GNSS (EN pin) and duty cycling, and to rebase both PRs once it lands. |
|
it's nice to have some discussion about this before doing the implementation task on the separation between LP and ESM, after reading #778 one of the key factor of this separation is to bring GpsDriver ... I think the reason why things got pushed to ESM is because LP is seen as the driver and ESM the managerm where for GPS, LP should be the manager (and should report only the values to ESM), so we need a driver to talk to ;) (If I recall well, this is what we had come to when discussing this with @awolden ) I will open a PR as soon as I have the first bits working so people can discuss which direction to go to ... |
|
Makes sense to me - LP as the GPS manager with a
I'll hold off on rebasing until your first PR is up, then port both onto it and test on a ProMicro repeater with a serial GNSS (EN pin) and duty cycling. |
|
Refactor of the GPS has now been done ... and it covers the aim of this PR Thanks for proposing that again .. that made me move to concretize what I had in mind for a long time |
Problem
On battery companions the GPS is either powered all the time or off. Meshtastic users expect an interval mode: wake, get a fix, power down, repeat. Nodes that rarely move save a lot of battery this way.
Change
gps_duty: seconds between fixes,0= always on (the default), max 86400. It uses the existingCMD_GET/SET_CUSTOM_VAR, so there is no protocol change.EnvironmentSensorManager::configureGPSDuty(). The companion calls it because it saves the value. Repeater and room server firmware don't list it, sosensor setcan't create an unsaved setting there.gps_duty > 0,EnvironmentSensorManager::loop():GPS_DUTY_SETTLE_SECS(default 10 s) so the RTC can sync;gps_dutyseconds before the next wake.gps_activestays true while the GPS is off, so thegpssetting, adverts and telemetry keep using the last fix. Settinggps_duty=0while asleep powers the GPS straight back on.gps_duty=0, behaviour is the same as before. The parser clear and RTC re-sync on wake only happen when cycling.NodePrefs(gps.duty) and re-applied inapplyGpsPrefs().gps on 5m, orgps sleep 5mwhile the GPS is off.gps_dutykeep the old toggle, and the sensors page keeps the plain toggle.GPS_DUTY_MAX_ON_SECSgives up without a fix (default 0 = wait for a fix).Testing
Heltec V3 companion, u-blox module powered from a GPIO enable pin (GPIO42):
Bounds:
gps_duty=-5andgps_duty=90000are rejected.60and300are accepted and persist across a reboot.No fix, indoors (debug build,
GPS_DUTY_MAX_ON_SECS=45,gps_duty=60):no fix, sleeping45 s after power-on, thenwaking60.0 s later, repeating.gps_duty=0while asleep: NMEA output resumes 0.2 s later and the GPS stays on (no sleep for 60 s). Setting60again resumes cycling.Repeater with the same GPS:
sensor listshows onlygps, andsensor set gps_duty 60repliescan't find custom var.Unit tests:
pio test -e native -e native_kiss_modempasses (54/54).Cycle with a fix (
gps_duty=300, indoors near a window): fix, power down, wake 300.0 s later, new fix (541 s cold start), power down.RTC during sleep, original vs. this PR. Test-only build with the provider's resync interval cut from 30 min to 120 s so the bug shows within one sleep. The clock was checked against the host:
With the parser running, each resync put the clock back to the last fix's time. With the stock 30 min interval and the 1h preset, this sets the clock back by up to an hour.
OLED: long-press on the GPS page steps through the presets (checked by hand).
Boards: the fix and RTC tests ran on a second Heltec V3 with the same wiring. The other tests ran on the first board.
Compile-checked (all build, no new warnings;
wio_wm1110_repeatershows the same 5ENV_INCLUDE_GPS redefinedwarnings asdev):Heltec_v3_companion_radio_usb,Heltec_v3_companion_radio_ble,Heltec_v3_repeater,Heltec_v3_room_server,Heltec_t114_companion_radio_ble,Heltec_Wireless_Tracker_companion_radio_ble,Tbeam_SX1276_companion_radio_ble,Tbeam_SX1276_repeater,LilyGo_TDeck_companion_radio_ble,RAK_4631_companion_radio_ble,RAK_4631_companion_radio_ethernet,RAK_4631_repeater,RAK_4631_repeater_ethernet,RAK_4631_room_server,RAK_4631_room_server_ethernet,PicoW_repeater,wio-e5-mini_repeater,LilyGo_Tlora_C6_repeater_,wio_wm1110_repeater.Open questions for maintainers
GPS_DUTY_MAX_ON_SECSdefault to a timeout (e.g. 300 s), so the GPS doesn't drain the battery indoors waiting for a fix?Note
This is independent of #3683 (runtime GPS pins) and branches from
dev. Both touch the GPS settings list,GPSPrefsand the FAQ numbering. I test-merged the two: the conflicts are "keep both sides", plus one shared#ifblock in the header and the FAQ renumbered to 5.18. The result runs on a Heltec V3 with all six GPS settings working.🤖 Generated with Claude Code