From 47c2b2e8b8c3895f4889249c91d527aa4ff9f0a3 Mon Sep 17 00:00:00 2001 From: Reid Tonking Date: Thu, 12 Feb 2026 11:47:13 -0600 Subject: [PATCH 1/2] wio-tracker-l1: improve battery voltage reading accuracy - Add 100us settling delay after enabling voltage divider - Average 8 ADC samples to reduce noise - Disable voltage divider after reading to save power (~2uA) - Move ADC configuration to begin() for consistency - Move getBattMilliVolts implementation to .cpp file Signed-off-by: Reid Tonking --- variants/wio-tracker-l1/WioTrackerL1Board.cpp | 22 ++++++++++++++++++- variants/wio-tracker-l1/WioTrackerL1Board.h | 9 +------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.cpp b/variants/wio-tracker-l1/WioTrackerL1Board.cpp index 4153714e9..a25568ef2 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.cpp +++ b/variants/wio-tracker-l1/WioTrackerL1Board.cpp @@ -7,7 +7,12 @@ void WioTrackerL1Board::begin() { NRF52BoardDCDC::begin(); btn_prev_state = HIGH; - pinMode(PIN_VBAT_READ, INPUT); // VBAT ADC input + // Configure battery voltage ADC + pinMode(PIN_VBAT_READ, INPUT); + pinMode(VBAT_ENABLE, OUTPUT); + digitalWrite(VBAT_ENABLE, HIGH); // Disable VBAT divider to save power + analogReadResolution(12); + analogReference(AR_INTERNAL); // Set all button pins to INPUT_PULLUP pinMode(PIN_BUTTON1, INPUT_PULLUP); pinMode(PIN_BUTTON2, INPUT_PULLUP); @@ -30,3 +35,18 @@ void WioTrackerL1Board::begin() { delay(10); // give sx1262 some time to power up } + +uint16_t WioTrackerL1Board::getBattMilliVolts() { + digitalWrite(VBAT_ENABLE, LOW); // Enable VBAT divider + delayMicroseconds(100); // Allow voltage divider to settle + + // Average multiple samples to reduce noise + uint32_t raw = 0; + for (int i = 0; i < 8; i++) { + raw += analogRead(PIN_VBAT_READ); + } + raw = raw / 8; + + digitalWrite(VBAT_ENABLE, HIGH); // Disable divider to save power + return (raw * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096; +} diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.h b/variants/wio-tracker-l1/WioTrackerL1Board.h index 052238e66..37ffad3e1 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.h +++ b/variants/wio-tracker-l1/WioTrackerL1Board.h @@ -21,14 +21,7 @@ class WioTrackerL1Board : public NRF52BoardDCDC { } #endif - uint16_t getBattMilliVolts() override { - int adcvalue = 0; - analogReadResolution(12); - analogReference(AR_INTERNAL); - delay(10); - adcvalue = analogRead(PIN_VBAT_READ); - return (adcvalue * ADC_MULTIPLIER * AREF_VOLTAGE) / 4.096; - } + uint16_t getBattMilliVolts() override; const char* getManufacturerName() const override { return "Seeed Wio Tracker L1"; From 9ccf38d6bc1f16d78f67c97e3d82db6ee1a2cf6b Mon Sep 17 00:00:00 2001 From: Reid Tonking Date: Thu, 12 Feb 2026 13:09:30 -0600 Subject: [PATCH 2/2] wio-tracker-l1: add power management support - Add boot voltage protection (won't boot below 3.3V) - Add LPCOMP wake configuration for voltage recovery - Implement initiateShutdown() with LPCOMP wake on low voltage - Enable NRF52_POWER_MANAGEMENT build flag Device will enter protective shutdown on low battery and wake automatically when voltage recovers to ~3.7V or USB is connected. Signed-off-by: Reid Tonking --- variants/wio-tracker-l1/WioTrackerL1Board.cpp | 33 +++++++++++++++++-- variants/wio-tracker-l1/WioTrackerL1Board.h | 4 +++ variants/wio-tracker-l1/platformio.ini | 1 + variants/wio-tracker-l1/variant.h | 9 +++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.cpp b/variants/wio-tracker-l1/WioTrackerL1Board.cpp index a25568ef2..ac07c6e93 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.cpp +++ b/variants/wio-tracker-l1/WioTrackerL1Board.cpp @@ -3,16 +3,46 @@ #include "WioTrackerL1Board.h" +#ifdef NRF52_POWER_MANAGEMENT +// Static configuration for power management +// Values set in variant.h defines +const PowerMgtConfig power_config = { + .lpcomp_ain_channel = PWRMGT_LPCOMP_AIN, + .lpcomp_refsel = PWRMGT_LPCOMP_REFSEL, + .voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK +}; + +void WioTrackerL1Board::initiateShutdown(uint8_t reason) { + bool enable_lpcomp = (reason == SHUTDOWN_REASON_LOW_VOLTAGE || + reason == SHUTDOWN_REASON_BOOT_PROTECT); + + pinMode(VBAT_ENABLE, OUTPUT); + digitalWrite(VBAT_ENABLE, enable_lpcomp ? LOW : HIGH); + + if (enable_lpcomp) { + configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel); + } + + enterSystemOff(reason); +} +#endif // NRF52_POWER_MANAGEMENT + void WioTrackerL1Board::begin() { NRF52BoardDCDC::begin(); btn_prev_state = HIGH; - // Configure battery voltage ADC + // Configure battery voltage ADC (needed for boot voltage check) pinMode(PIN_VBAT_READ, INPUT); pinMode(VBAT_ENABLE, OUTPUT); digitalWrite(VBAT_ENABLE, HIGH); // Disable VBAT divider to save power analogReadResolution(12); analogReference(AR_INTERNAL); + +#ifdef NRF52_POWER_MANAGEMENT + // Boot voltage protection check (may not return if voltage too low) + checkBootVoltage(&power_config); +#endif + // Set all button pins to INPUT_PULLUP pinMode(PIN_BUTTON1, INPUT_PULLUP); pinMode(PIN_BUTTON2, INPUT_PULLUP); @@ -20,7 +50,6 @@ void WioTrackerL1Board::begin() { pinMode(PIN_BUTTON4, INPUT_PULLUP); pinMode(PIN_BUTTON5, INPUT_PULLUP); pinMode(PIN_BUTTON6, INPUT_PULLUP); - #if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL) Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL); diff --git a/variants/wio-tracker-l1/WioTrackerL1Board.h b/variants/wio-tracker-l1/WioTrackerL1Board.h index 37ffad3e1..e27483280 100644 --- a/variants/wio-tracker-l1/WioTrackerL1Board.h +++ b/variants/wio-tracker-l1/WioTrackerL1Board.h @@ -8,6 +8,10 @@ class WioTrackerL1Board : public NRF52BoardDCDC { protected: uint8_t btn_prev_state; +#ifdef NRF52_POWER_MANAGEMENT + void initiateShutdown(uint8_t reason) override; +#endif + public: WioTrackerL1Board() : NRF52Board("WioTrackerL1 OTA") {} void begin(); diff --git a/variants/wio-tracker-l1/platformio.ini b/variants/wio-tracker-l1/platformio.ini index 75651d695..28cf98ddb 100644 --- a/variants/wio-tracker-l1/platformio.ini +++ b/variants/wio-tracker-l1/platformio.ini @@ -8,6 +8,7 @@ build_flags = ${nrf52_base.build_flags} -I lib/nrf52/s140_nrf52_7.3.0_API/include/nrf52 -I variants/wio-tracker-l1 -D WIO_TRACKER_L1 + -D NRF52_POWER_MANAGEMENT -D RADIO_CLASS=CustomSX1262 -D WRAPPER_CLASS=CustomSX1262Wrapper -D LORA_TX_POWER=22 diff --git a/variants/wio-tracker-l1/variant.h b/variants/wio-tracker-l1/variant.h index 86ad62baa..ffc0e84d9 100644 --- a/variants/wio-tracker-l1/variant.h +++ b/variants/wio-tracker-l1/variant.h @@ -50,6 +50,15 @@ #define ADC_MULTIPLIER (2.0F) #define ADC_RESOLUTION (12) +// Power management boot protection threshold (millivolts) +// Set to 0 to disable boot protection +#define PWRMGT_VOLTAGE_BOOTLOCK 3300 // Won't boot below this voltage + +// LPCOMP wake configuration (voltage recovery from SYSTEMOFF) +#define PWRMGT_LPCOMP_AIN 7 // AIN7 = P0.31 = PIN_VBAT_READ +// Wake when battery voltage recovers to ~3.7V +#define PWRMGT_LPCOMP_REFSEL 12 // 9/16 VDD + // Serial interfaces #define PIN_SERIAL1_RX (7) #define PIN_SERIAL1_TX (6)