From d516cd8a9eedfe0f4cd6c32e4526d6b0427ad338 Mon Sep 17 00:00:00 2001 From: pelgraine <140762863+pelgraine@users.noreply.github.com> Date: Fri, 10 Apr 2026 14:25:51 +1000 Subject: [PATCH] =?UTF-8?q?Fixes=20#1183=20=E2=80=94=20T-Echo=20Lite=20inc?= =?UTF-8?q?orrect=20battery=20voltage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Battery (TechoBoard.h/cpp): Added PIN_VBAT_MEAS_EN (P0.31) — the T-Echo Lite has a gated voltage divider that must be enabled before reading. Also added pinMode(PIN_VBAT_READ, INPUT) before each ADC read to reclaim P0.02 from other peripherals. Pin definitions hardcoded from LilyGo's t_echo_lite_config.h. I2C (variant.h): Corrected SDA/SCL from P0.04/P0.02 to P1.04/P1.02 per LilyGo's IIC_1_SDA/IIC_1_SCL. The old P0.02 mapping conflicted with the battery ADC pin. GPS (variant.h): Corrected all five GPS pin assignments to match LilyGo's config — UART TX/RX, wake, PPS, and power enable were all scrambled. SPI (variant.h): Fixed SPI_INTERFACES_COUNT from _PINNUM(0, 2) to (2). Tested on T-Echo Lite Non-Shell (USB-C, no display). Battery readings match Heltec V4 reference within 10mV. --- variants/lilygo_techo_lite/TechoBoard.cpp | 43 +++++++++++++++++------ variants/lilygo_techo_lite/TechoBoard.h | 19 +++++----- variants/lilygo_techo_lite/variant.h | 21 +++++------ 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/variants/lilygo_techo_lite/TechoBoard.cpp b/variants/lilygo_techo_lite/TechoBoard.cpp index 81d3d0c9..a11d31b2 100644 --- a/variants/lilygo_techo_lite/TechoBoard.cpp +++ b/variants/lilygo_techo_lite/TechoBoard.cpp @@ -8,24 +8,47 @@ void TechoBoard::begin() { NRF52Board::begin(); + // Configure battery measurement control BEFORE Wire.begin() + // to ensure P0.02 is not claimed by another peripheral + pinMode(PIN_VBAT_MEAS_EN, OUTPUT); + digitalWrite(PIN_VBAT_MEAS_EN, LOW); + pinMode(PIN_VBAT_READ, INPUT); + Wire.begin(); pinMode(SX126X_POWER_EN, OUTPUT); digitalWrite(SX126X_POWER_EN, HIGH); - delay(10); // give sx1262 some time to power up + delay(10); } uint16_t TechoBoard::getBattMilliVolts() { - int adcvalue = 0; - + // Use LilyGo's exact ADC configuration analogReference(AR_INTERNAL_3_0); analogReadResolution(12); - delay(10); - // ADC range is 0..3000mV and resolution is 12-bit (0..4095) - adcvalue = analogRead(PIN_VBAT_READ); - // Convert the raw value to compensated mv, taking the resistor- - // divider into account (providing the actual LIPO voltage) - return (uint16_t)((float)adcvalue * REAL_VBAT_MV_PER_LSB); + // Enable battery voltage divider (MOSFET gate on P0.31) + pinMode(PIN_VBAT_MEAS_EN, OUTPUT); + digitalWrite(PIN_VBAT_MEAS_EN, HIGH); + + // Reclaim P0.02 for analog input (in case another peripheral touched it) + pinMode(PIN_VBAT_READ, INPUT); + delay(10); // let divider + ADC settle + + // Read and average (matching LilyGo's approach) + uint32_t sum = 0; + for (int i = 0; i < 8; i++) { + sum += analogRead(PIN_VBAT_READ); + delayMicroseconds(100); + } + uint16_t adc = sum / 8; + + // Disable divider to save power + digitalWrite(PIN_VBAT_MEAS_EN, LOW); + + // LilyGo's exact formula: adc * (3000.0 / 4096.0) * 2.0 + // = adc * 0.73242188 * 2.0 = adc * 1.46484375 + uint16_t millivolts = (uint16_t)((float)adc * (3000.0f / 4096.0f) * 2.0f); + + return millivolts; } -#endif +#endif \ No newline at end of file diff --git a/variants/lilygo_techo_lite/TechoBoard.h b/variants/lilygo_techo_lite/TechoBoard.h index fda393e7..7a43fd83 100644 --- a/variants/lilygo_techo_lite/TechoBoard.h +++ b/variants/lilygo_techo_lite/TechoBoard.h @@ -4,14 +4,12 @@ #include #include -// built-ins -#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 - -#define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT -#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider - -#define PIN_VBAT_READ (4) -#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) +// ============================================================ +// T-Echo Lite battery pins — hardcoded from LilyGo t_echo_lite_config.h +// NOT using any defines from variant.h for battery measurement +// ============================================================ +#define PIN_VBAT_READ _PINNUM(0, 2) // BATTERY_ADC_DATA +#define PIN_VBAT_MEAS_EN _PINNUM(0, 31) // BATTERY_MEASUREMENT_CONTROL class TechoBoard : public NRF52BoardDCDC { public: @@ -20,10 +18,11 @@ public: uint16_t getBattMilliVolts() override; const char* getManufacturerName() const override { - return "LilyGo T-Echo"; + return "LilyGo T-Echo Lite"; } void powerOff() override { + digitalWrite(PIN_VBAT_MEAS_EN, LOW); #ifdef LED_RED digitalWrite(LED_RED, LOW); #endif @@ -41,4 +40,4 @@ public: #endif sd_power_system_off(); } -}; +}; \ No newline at end of file diff --git a/variants/lilygo_techo_lite/variant.h b/variants/lilygo_techo_lite/variant.h index 16e0b5cb..07202165 100644 --- a/variants/lilygo_techo_lite/variant.h +++ b/variants/lilygo_techo_lite/variant.h @@ -24,7 +24,7 @@ #define PIN_PWR_EN _PINNUM(0, 30) // RT9080_EN #define BATTERY_PIN _PINNUM(0, 2) -#define ADC_MULTIPLIER (4.90F) +#define ADC_MULTIPLIER (2.0F) #define ADC_RESOLUTION (14) #define BATTERY_SENSE_RES (12) @@ -47,13 +47,13 @@ //////////////////////////////////////////////////////////////////////////////// // I2C pin definition -#define PIN_WIRE_SDA _PINNUM(0, 4) // (SDA) -#define PIN_WIRE_SCL _PINNUM(0, 2) // (SCL) +#define PIN_WIRE_SDA _PINNUM(1, 4) // (SDA) - per LilyGo IIC_1_SDA +#define PIN_WIRE_SCL _PINNUM(1, 2) // (SCL) - per LilyGo IIC_1_SCL //////////////////////////////////////////////////////////////////////////////// // SPI pin definition -#define SPI_INTERFACES_COUNT _PINNUM(0, 2) +#define SPI_INTERFACES_COUNT (2) #define PIN_SPI_MISO _PINNUM(0, 17) // (MISO) #define PIN_SPI_MOSI _PINNUM(0, 15) // (MOSI) @@ -149,10 +149,11 @@ extern const int SCK; #define PIN_DISPLAY_BUSY DISP_BUSY //////////////////////////////////////////////////////////////////////////////// -// GPS +// GPS — per LilyGo t_echo_lite_config.h +// PIN_GPS_TX/RX named from GPS module's perspective -#define PIN_GPS_RX _PINNUM(1, 13) // RXD -#define PIN_GPS_TX _PINNUM(1, 15) // TXD -#define GPS_EN _PINNUM(1, 11) // POWER_RT9080_EN -#define PIN_GPS_STANDBY _PINNUM(1, 10) -#define PIN_GPS_PPS _PINNUM(0, 29) // 1PPS +#define PIN_GPS_TX _PINNUM(0, 29) // GPS UART TX → MCU RX +#define PIN_GPS_RX _PINNUM(1, 10) // GPS UART RX ← MCU TX +#define GPS_EN _PINNUM(1, 11) // GPS RT9080 power enable +#define PIN_GPS_STANDBY _PINNUM(1, 13) // GPS wake-up +#define PIN_GPS_PPS _PINNUM(1, 15) // GPS 1PPS \ No newline at end of file