From 360c5d15e004ea1e0aab4b4e591f359338406d43 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 8f0137971..a50948778 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 95def06c9..8258b29d3 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 1c30fb44e8d68c26237b7d3f859317e74a19d0c5 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 a50948778..7feb95583 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 so this attenuation should cover it with some room to spare digitalWrite(PIN_ADC_CTRL, HIGH); delay(10); uint32_t raw_mv = 0;