From 25996e9330e1c8ba71dd5d5af540f27fe1a08778 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 1 Aug 2026 08:16:03 -0500 Subject: [PATCH] Fix W12 battery reading: add ADC_CTRL and correct the divider ratio (#11323) * Fix W12 battery reading: add ADC_CTRL and correct the divider ratio The W12 battery config was taken from the vendor's Demo_06_ADC_Read.ino, which reads GPIO1, multiplies by 2.0 under a literal "Assumption: 2:1 voltage divider" comment, and never touches the ADC enable at all. All three of those details are wrong. Schematic W12-MB-V0.2 sheet 1 has the divider behind a P-MOSFET high-side switch so it only draws from the cell during a reading: BAT --S[Q6 AO3401A]D-- R50 390K --IO1_ADC_IN-- R51 100K -- GND |G R49 1K to BAT (gate pull-up: Q6 off by default) +-- R48 1K -- C[Q7 S8050 NPN]E -- GND, base <- R52 1K <- IO2 So GPIO2 is ADC_CTRL, not "a second (solar/VUSB) divider" as the variant claimed, and the NPN inverts it, making it active HIGH. Left undriven, Q6 stays off and GPIO1 sits at ground through R51 - a hard 0 raw rather than the 100-250mV of noise a floating pin gives - so every boot reported "battery hardware absent (USB-only)" and battery_level 101. The divider is 390K/100K, so the multiplier is 4.9, not 2.0. That puts a 4.2V cell at only ~857mV on the pin, so drop the attenuation from the 12dB default (0-3100mV) to 2.5dB (0-1250mV) to use the range properly. This matches the Heltec V3/V4 network, but their ADC_CTRL 37 cannot be reused here: GPIO33-37 are consumed by this board's octal PSRAM. Verified on hardware: reports 4067mV / 91%, stable to the mV across consecutive samples, where it previously read 0mV with a cell attached. * Trim the battery comment block to house style Per the repo guideline that code comments stay to one or two lines and avoid multi-paragraph blocks, drop the ASCII schematic from the header. The full circuit trace lives in the previous commit message and the PR description, which is where that rationale belongs. Comment-only; both define values are unchanged. --- variants/esp32s3/meshnology-w12/variant.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/variants/esp32s3/meshnology-w12/variant.h b/variants/esp32s3/meshnology-w12/variant.h index 999c7c45d..5ab0c7bf4 100644 --- a/variants/esp32s3/meshnology-w12/variant.h +++ b/variants/esp32s3/meshnology-w12/variant.h @@ -17,10 +17,14 @@ #define BUTTON_PIN 0 // BOOT doubles as user button // ─── Battery ────────────────────────────────────────────────────────────────── -// GPIO2 monitors a second (solar/VUSB) divider and is not used here +// GPIO2 gates a P-MOSFET high-side switch on the divider (schematic W12-MB-V0.2 sheet 1); an NPN +// inverts it, so it is active HIGH. Undriven, the switch stays off and GPIO1 reads a hard 0 mV. #define BATTERY_PIN 1 #define ADC_CHANNEL ADC_CHANNEL_0 // GPIO1 = ADC1_CH0 -#define ADC_MULTIPLIER 2.0 +#define ADC_CTRL 2 +#define ADC_CTRL_ENABLED HIGH +#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // 4.2V cell is only ~857mV after the divider +#define ADC_MULTIPLIER (490.0 / 100.0) // R50 390K + R51 100K, over R51 // ─── LoRa radio ─────────────────────────────────────────────────────────────── // RF switching is hardwired to the radio's CTX/CPS pins, and the external PA enables