Skip to content

GPS causes +8mA power consumption even when disabled on Heltec T114 #1628

@mileshkin

Description

@mileshkin

Environment

  • Board: Heltec T114 (nRF52840)
  • Build flag: -D ENV_INCLUDE_GPS=1
  • GPS Module: Connected to Serial1 (PIN_GPS_TX=37, PIN_GPS_RX=39)
  • Control pins: PIN_GPS_EN=21, PIN_GPS_STANDBY=34, PIN_GPS_RESET=38

Problem Description

When compiling with -D ENV_INCLUDE_GPS=1, the board consumes ~8mA additional current even when GPS is disabled through the UI settings.

Current Measurements:

  • With -D ENV_INCLUDE_GPS=0: 14-16 mA (normal) ✅
  • With -D ENV_INCLUDE_GPS=1 and GPS disabled: 22-24 mA ❌
  • With -D ENV_INCLUDE_GPS=1 and GPS enabled: 50-56 mA

Expected Behavior:

GPS disabled → 14-16 mA (same as ENV_INCLUDE_GPS=0)

Actual Behavior:

GPS disabled → 22-24 mA (+8mA leak)

Investigation Done

What we checked:

  1. GPIO pins (PIN_GPS_EN, PIN_GPS_STANDBY, PIN_GPS_RESET)

    • ✅ All properly initialized to OFF/SLEEP state in UITask::begin()
    • setGPSHardwareState() correctly manages all pins
    • ✅ Verified with oscilloscope - pins are in correct state
  2. Serial1 (UART)

    • ❌ Adding Serial1.end() in stop_gps() causes issues:
      • Either no effect on power consumption, OR
      • Board hangs/doesn't boot, OR
      • GPS can't be toggled on/off again
    • Serial1 is initialized in EnvironmentSensorManager::initBasicGPS() but never stopped
  3. I2C Wire1

    • ✅ Tested by commenting out -D ENV_PIN_SDA and -D ENV_PIN_SCL
    • No change in power consumption
  4. MicroNMEALocationProvider constructor

    • Creates global object before setup()
    • Initializes PIN_GPS_EN but NOT PIN_GPS_STANDBY (we fixed this, but no effect)

Code Analysis:

The issue appears when this line executes in target.cpp:

#if ENV_INCLUDE_GPS
#include <helpers/sensors/MicroNMEALocationProvider.h>
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);

Comparison

Important: The same code works correctly on Heltec V4 board with no extra power consumption when GPS is disabled.

Questions

  1. What peripheral/resource is consuming the extra 8mA when ENV_INCLUDE_GPS=1?
  2. Why does Serial1.end() cause instability instead of saving power?
  3. Is there something in the global object initialization that keeps a resource active?
  4. How is this handled differently on Heltec V4 vs T114?

Attempted Fixes

Fix 1: Add PIN_GPS_STANDBY to MicroNMEALocationProvider

// Added _pin_standby member and initialization in constructor
if (_pin_standby != -1) {
    pinMode(_pin_standby, OUTPUT);
    digitalWrite(_pin_standby, PIN_GPS_STANDBY_ACTIVE);  // Put GPS to sleep
}

Result: No change in power consumption

Fix 2: Stop Serial1 in stop_gps()

void EnvironmentSensorManager::stop_gps() {
    _location->stop();
    Serial1.end();  // Stop UART
}

Result: Board becomes unstable or GPS won't restart

Fix 3: Initialize all GPS pins to OFF in UITask::begin()

digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);      // Disable power
digitalWrite(PIN_GPS_STANDBY, PIN_GPS_STANDBY_ACTIVE);  // Sleep mode

Result: No change in power consumption

Request

Could someone help identify:

  1. What resource/peripheral stays active when ENV_INCLUDE_GPS=1?
  2. The correct way to fully power down GPS-related peripherals on nRF52840?
  3. Why the same code works on V4 but not on T114?

Additional Context

This is critical for battery-powered applications where +50% idle power consumption is unacceptable.

Any guidance would be greatly appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions