From fe4f86bc845f3fc4ad044460b94479ae5563a77b Mon Sep 17 00:00:00 2001 From: Professr Date: Sun, 21 Jun 2020 16:21:34 -0700 Subject: [PATCH 1/2] Added battery charge percent estimation --- src/esp32/main-esp32.cpp | 20 +++++++++++--------- src/power.h | 15 +++++++++++++++ src/screen.cpp | 8 +++++--- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/esp32/main-esp32.cpp b/src/esp32/main-esp32.cpp index 45e2a123..f9aaf127 100644 --- a/src/esp32/main-esp32.cpp +++ b/src/esp32/main-esp32.cpp @@ -6,6 +6,7 @@ #include "power.h" #include "sleep.h" #include "target_specific.h" +#include bool bluetoothOn; @@ -75,6 +76,16 @@ void readPowerStatus() powerStatus.haveBattery = axp.isBatteryConnect(); if (powerStatus.haveBattery) { powerStatus.batteryVoltageMv = axp.getBattVoltage(); + // If the AXP192 returns a valid battery percentage, use it + if (axp.getBattPercentage() >= 0) { + powerStatus.batteryChargePercent = axp.getBattPercentage(); + } else { + // If the AXP192 returns a percentage less than 0, the feature is either not supported or there is an error + // In that case, we compute an estimate of the charge percent based on maximum and minimum voltages defined in power.h + int calculatedPercentage = ((powerStatus.batteryVoltageMv - BAT_MILLIVOLTS_EMPTY) * 1e2) / (BAT_MILLIVOLTS_FULL - BAT_MILLIVOLTS_EMPTY); + powerStatus.batteryChargePercent = (calculatedPercentage < 0) ? 0 : (calculatedPercentage > 100) ? 100 : calculatedPercentage; + } + DEBUG_MSG("Battery %dmV %d%%\n", powerStatus.batteryVoltageMv, powerStatus.batteryChargePercent); } powerStatus.usb = axp.isVBUSPlug(); powerStatus.charging = axp.isChargeing(); @@ -205,15 +216,6 @@ uint32_t axpDebugRead() Periodic axpDebugOutput(axpDebugRead); #endif -/** - * Per @spattinson - * MIN_BAT_MILLIVOLTS seems high. Typical 18650 are different chemistry to LiPo, even for LiPos that chart seems a bit off, other - * charts put 3690mV at about 30% for a lipo, for 18650 i think 10% remaining iis in the region of 3.2-3.3V. Reference 1st graph - * in [this test report](https://lygte-info.dk/review/batteries2012/Samsung%20INR18650-30Q%203000mAh%20%28Pink%29%20UK.html) - * looking at the red line - discharge at 0.2A - he gets a capacity of 2900mah, 90% of 2900 = 2610, that point in the graph looks - * to be a shade above 3.2V - */ -#define MIN_BAT_MILLIVOLTS 3250 // millivolts. 10% per https://blog.ampow.com/lipo-voltage-chart/ /// loop code specific to ESP32 targets void esp32Loop() diff --git a/src/power.h b/src/power.h index 6b190cbf..21c913d5 100644 --- a/src/power.h +++ b/src/power.h @@ -1,5 +1,18 @@ #pragma once +/** + * Per @spattinson + * MIN_BAT_MILLIVOLTS seems high. Typical 18650 are different chemistry to LiPo, even for LiPos that chart seems a bit off, other + * charts put 3690mV at about 30% for a lipo, for 18650 i think 10% remaining iis in the region of 3.2-3.3V. Reference 1st graph + * in [this test report](https://lygte-info.dk/review/batteries2012/Samsung%20INR18650-30Q%203000mAh%20%28Pink%29%20UK.html) + * looking at the red line - discharge at 0.2A - he gets a capacity of 2900mah, 90% of 2900 = 2610, that point in the graph looks + * to be a shade above 3.2V + */ +#define MIN_BAT_MILLIVOLTS 3250 // millivolts. 10% per https://blog.ampow.com/lipo-voltage-chart/ + +#define BAT_MILLIVOLTS_FULL 4100 +#define BAT_MILLIVOLTS_EMPTY 3500 + namespace meshtastic { @@ -9,6 +22,8 @@ struct PowerStatus { bool haveBattery; /// Battery voltage in mV, valid if haveBattery is true int batteryVoltageMv; + /// Battery charge percentage, either read directly or estimated + int batteryChargePercent; /// Whether USB is connected bool usb; /// Whether we are charging the battery diff --git a/src/screen.cpp b/src/screen.cpp index 1837ef79..e31d5ae0 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -658,9 +658,11 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16 snprintf(channelStr, sizeof(channelStr), "%s", channelName.c_str()); if (powerStatus.haveBattery) { // TODO: draw a battery icon instead of letter "B". - int batV = powerStatus.batteryVoltageMv / 1000; - int batCv = (powerStatus.batteryVoltageMv % 1000) / 10; - snprintf(batStr, sizeof(batStr), "B %01d.%02dV%c%c", batV, batCv, powerStatus.charging ? '+' : ' ', + //int batV = powerStatus.batteryVoltageMv / 1000; + //int batCv = (powerStatus.batteryVoltageMv % 1000) / 10; + //snprintf(batStr, sizeof(batStr), "B %01d.%02dV%c%c", batV, batCv, powerStatus.charging ? '+' : ' ', + // powerStatus.usb ? 'U' : ' '); + snprintf(batStr, sizeof(batStr), "B %d%%%c%c", powerStatus.batteryChargePercent, powerStatus.charging ? '+' : ' ', powerStatus.usb ? 'U' : ' '); } else { snprintf(batStr, sizeof(batStr), "%s", powerStatus.usb ? "USB" : ""); From 364fc84aaab3cd40d44e8e65baa10d4906f3616c Mon Sep 17 00:00:00 2001 From: Professr Date: Sun, 21 Jun 2020 16:31:09 -0700 Subject: [PATCH 2/2] Removed unnecessary include, ready for consideration for issue #196 --- src/esp32/main-esp32.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/esp32/main-esp32.cpp b/src/esp32/main-esp32.cpp index f9aaf127..8b08118c 100644 --- a/src/esp32/main-esp32.cpp +++ b/src/esp32/main-esp32.cpp @@ -6,7 +6,6 @@ #include "power.h" #include "sleep.h" #include "target_specific.h" -#include bool bluetoothOn;