Skip to content

Fix GPS UART consuming +8mA when disabled (nRF52)#1633

Open
weebl2000 wants to merge 1 commit intomeshcore-dev:devfrom
weebl2000:fix/gps-uart-power-leak
Open

Fix GPS UART consuming +8mA when disabled (nRF52)#1633
weebl2000 wants to merge 1 commit intomeshcore-dev:devfrom
weebl2000:fix/gps-uart-power-leak

Conversation

@weebl2000
Copy link
Contributor

@weebl2000 weebl2000 commented Feb 8, 2026

I don't have a Heltec T114 so I cannot test this myself.

Summary

Fixes #1628 — GPS causes +8mA power consumption even when disabled on Heltec T114 (nRF52840).

  • Serial1.begin() is called during initBasicGPS() to probe for GPS hardware, but never ended when GPS is subsequently disabled. On nRF52840, the UARTE peripheral stays active, drawing ~8mA through the peripheral itself and current leaking via the TX pin (held HIGH in idle UART state) into the GPS module's ESD protection diodes.
  • _location->loop() was called unconditionally in the main loop, reading from Serial1 even when GPS was disabled. This both prevented simply adding Serial1.end() (would crash) and wasted cycles.

Changes

  • Call Serial1.end() in initBasicGPS() and stop_gps() to fully disable the UART peripheral when GPS is off
  • Re-initialize Serial1 in start_gps() so GPS can be toggled back on via settings
  • Gate _location->loop() behind gps_active check to prevent accessing an ended Serial

Why Heltec V4 (ESP32) is unaffected

ESP32 UART peripherals consume negligible power when idle (more aggressively clock-gated). On nRF52840, the UARTE keeps the HFCLK running for start-bit detection.

Note: the RAK board path already correctly calls Serial1.end() when no GPS is found, confirming this approach is valid. RAK paths are unaffected by this change (they return early via #ifdef RAK_WISBLOCK_GPS guards).

Test plan

  • Build and flash Heltec T114 with ENV_INCLUDE_GPS=1, verify idle current returns to ~14-16mA with GPS disabled
  • Verify GPS can be toggled on/off via settings and continues to acquire fix
  • Verify no regression on ESP32 GPS targets (Heltec Tracker v2, etc.)

When GPS is disabled (or not detected), Serial1.begin() was called
during initBasicGPS() but never ended. On nRF52840 the UARTE
peripheral stays active, drawing ~8mA through the peripheral itself
and current leaking via TX pin into the GPS module's ESD diodes.

- Call Serial1.end() in initBasicGPS() and stop_gps() to disable UART
- Re-initialize Serial1 in start_gps() so GPS can be toggled back on
- Gate _location->loop() behind gps_active to prevent accessing ended
  Serial (and avoid pointless NMEA polling when GPS is off)

Fixes meshcore-dev#1628
@mileshkin
Copy link

I tried fixing it this way. Like in your case, it resulted in a persistent "Loading..." message.

@weebl2000
Copy link
Contributor Author

The key difference from your Fix 2 is the gps_active guard on _location->loop(). Without it, the main loop keeps calling _location->loop()Serial1.available() / Serial1.read() on the ended UART — which on nRF52 causes undefined behavior (hang/crash).

This PR gates that call behind gps_active, so after Serial1.end() nobody touches the ended UART. That should prevent the hang you saw.

Would you be able to test this branch on your T114?

@mileshkin
Copy link

I cloned your branch and compiled a firmware from it - the first thing i did, flashed it to my T114, and got an infinite "Loading..."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants