From 7dd5c7a403f0cd10d39b4e97c910cc092cfc8c38 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 5 Jun 2026 10:25:33 +0100 Subject: [PATCH 1/2] HeltecV4: Fix battery ADC reading accuracy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct ADC_MULTIPLIER from 5.42 to 4.9 to match the R27/R28 resistor divider on the schematic (390kΩ + 100kΩ) / 100kΩ = 4.9. Also switch from analogRead() with manual 3.3V/1024 conversion to analogReadMilliVolts() at 12-bit resolution, which uses the ESP32's built-in ADC calibration for improved accuracy. Schematic reference: https://resource.heltec.cn/download/WiFi_LoRa_32_V4 --- variants/heltec_v4/HeltecV4Board.cpp | 10 +++++----- variants/heltec_v4/HeltecV4Board.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/variants/heltec_v4/HeltecV4Board.cpp b/variants/heltec_v4/HeltecV4Board.cpp index 8f01379714..a50948778f 100644 --- a/variants/heltec_v4/HeltecV4Board.cpp +++ b/variants/heltec_v4/HeltecV4Board.cpp @@ -62,18 +62,18 @@ void HeltecV4Board::begin() { } uint16_t HeltecV4Board::getBattMilliVolts() { - analogReadResolution(10); + analogReadResolution(12); digitalWrite(PIN_ADC_CTRL, HIGH); delay(10); - uint32_t raw = 0; + uint32_t raw_mv = 0; for (int i = 0; i < 8; i++) { - raw += analogRead(PIN_VBAT_READ); + raw_mv += analogReadMilliVolts(PIN_VBAT_READ); } - raw = raw / 8; + raw_mv /= 8; digitalWrite(PIN_ADC_CTRL, LOW); - return (adc_mult * (3.3 / 1024.0) * raw) * 1000; + return adc_mult * raw_mv; } const char* HeltecV4Board::getManufacturerName() const { diff --git a/variants/heltec_v4/HeltecV4Board.h b/variants/heltec_v4/HeltecV4Board.h index 95def06c95..8258b29d32 100644 --- a/variants/heltec_v4/HeltecV4Board.h +++ b/variants/heltec_v4/HeltecV4Board.h @@ -7,7 +7,7 @@ #include "LoRaFEMControl.h" #ifndef ADC_MULTIPLIER - #define ADC_MULTIPLIER 5.42 + #define ADC_MULTIPLIER 4.9 // (R1+R2)/R2 = (390k+100k)/100k #endif class HeltecV4Board : public ESP32Board { From b32182e3cd88192fbef7b81b01451d7e1bed261d Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 5 Jun 2026 17:32:29 +0100 Subject: [PATCH 2/2] HeltecV4: Use ADC_2_5db attenuation for battery reading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The resistor divider (390kΩ/100kΩ) keeps the ADC pin voltage in the 0.61-0.86V range across the full LiPoly range (3.0–4.2V). ADC_2_5db (~1250mV full-scale) uses ~70% of the ADC range at full charge, giving better resolution than the default ADC_11db (~20%) while maintaining headroom over ADC_0db (~950mV) to handle chip-to-chip ADC variation. --- variants/heltec_v4/HeltecV4Board.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/heltec_v4/HeltecV4Board.cpp b/variants/heltec_v4/HeltecV4Board.cpp index a50948778f..91ffac2181 100644 --- a/variants/heltec_v4/HeltecV4Board.cpp +++ b/variants/heltec_v4/HeltecV4Board.cpp @@ -63,6 +63,7 @@ void HeltecV4Board::begin() { uint16_t HeltecV4Board::getBattMilliVolts() { analogReadResolution(12); + analogSetPinAttenuation(PIN_VBAT_READ, ADC_2_5db); // divider puts pin at 0.61-0.86V; 2.5dB gives headroom over ADC_0db for chip variation digitalWrite(PIN_ADC_CTRL, HIGH); delay(10); uint32_t raw_mv = 0;