From 744ab454b1d2ffd6ba5a6d131bc5e92e1aabb28b Mon Sep 17 00:00:00 2001 From: Eike Ahmels Date: Wed, 7 Feb 2024 00:07:42 +0100 Subject: [PATCH] Voltage detection method (#13350) change voltage detection method and is voltage stable flag to make it resilient and synced to update battery task Co-authored-by: Eike Ahmels --- src/main/sensors/battery.c | 32 +++++++++++++++++++------------- src/main/sensors/battery.h | 2 ++ src/main/sensors/voltage.c | 3 +++ src/main/sensors/voltage.h | 5 +++++ 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/main/sensors/battery.c b/src/main/sensors/battery.c index 211210f3e50..1384fa25573 100644 --- a/src/main/sensors/battery.c +++ b/src/main/sensors/battery.c @@ -67,7 +67,7 @@ * */ -#define VBAT_STABLE_MAX_DELTA 20 +#define VBAT_STABLE_MAX_DELTA 10 // 100mV #define LVC_AFFECT_TIME 10000000 //10 secs for the LVC to slowly kick in // Battery monitoring stuff @@ -159,8 +159,21 @@ void batteryUpdateVoltage(timeUs_t currentTimeUs) break; } + if (!voltageMeter.isVoltageStable && cmp32(millis(), voltageMeter.prevDisplayFilteredTime) >= PREV_DISPLAY_FILTERED_TIME_DIFF) { + if ((voltageState == BATTERY_NOT_PRESENT || voltageState == BATTERY_INIT) && isVoltageFromBattery()) { + voltageMeter.isVoltageStable = abs(voltageMeter.prevDisplayFiltered - voltageMeter.displayFiltered) <= VBAT_STABLE_MAX_DELTA; + } + + voltageMeter.prevDisplayFiltered = voltageMeter.displayFiltered; + voltageMeter.prevDisplayFilteredTime = millis(); + } + DEBUG_SET(DEBUG_BATTERY, 0, voltageMeter.unfiltered); DEBUG_SET(DEBUG_BATTERY, 1, voltageMeter.displayFiltered); + DEBUG_SET(DEBUG_BATTERY, 4, voltageMeter.isVoltageStable ? 1 : 0); + DEBUG_SET(DEBUG_BATTERY, 5, isVoltageFromBattery() ? 1 : 0); + DEBUG_SET(DEBUG_BATTERY, 6, voltageMeter.prevDisplayFiltered); + DEBUG_SET(DEBUG_BATTERY, 7, voltageState); } static void updateBatteryBeeperAlert(void) @@ -181,14 +194,7 @@ static void updateBatteryBeeperAlert(void) } } -//TODO: make all of these independent of voltage filtering for display - -static bool isVoltageStable(void) -{ - return abs(voltageMeter.displayFiltered - voltageMeter.unfiltered) <= VBAT_STABLE_MAX_DELTA; -} - -static bool isVoltageFromBat(void) +bool isVoltageFromBattery(void) { // We want to disable battery getting detected around USB voltage or 0V @@ -199,7 +205,7 @@ static bool isVoltageFromBat(void) void batteryUpdatePresence(void) { - if ((voltageState == BATTERY_NOT_PRESENT || voltageState == BATTERY_INIT) && isVoltageFromBat() && isVoltageStable()) { + if ((voltageState == BATTERY_NOT_PRESENT || voltageState == BATTERY_INIT) && isVoltageFromBattery() && voltageMeter.isVoltageStable) { // Battery has just been connected - calculate cells, warning voltages and reset state consumptionState = voltageState = BATTERY_OK; @@ -226,11 +232,11 @@ void batteryUpdatePresence(void) batteryCriticalHysteresisVoltage = (batteryCriticalVoltage > batteryConfig()->vbathysteresis) ? batteryCriticalVoltage - batteryConfig()->vbathysteresis : 0; lowVoltageCutoff.percentage = 100; lowVoltageCutoff.startTime = 0; - } else if (voltageState != BATTERY_NOT_PRESENT && isVoltageStable() && !isVoltageFromBat()) { + } else if (voltageState != BATTERY_NOT_PRESENT && voltageMeter.isVoltageStable && !isVoltageFromBattery()) { /* battery has been disconnected - can take a while for filter cap to disharge so we use a threshold of batteryConfig()->vbatnotpresentcellvoltage */ - consumptionState = voltageState = BATTERY_NOT_PRESENT; - + + voltageMeter.isVoltageStable = false; batteryCellCount = 0; batteryWarningVoltage = 0; batteryCriticalVoltage = 0; diff --git a/src/main/sensors/battery.h b/src/main/sensors/battery.h index aa33e3318a3..52c97fe324c 100644 --- a/src/main/sensors/battery.h +++ b/src/main/sensors/battery.h @@ -97,6 +97,8 @@ void batteryInit(void); void batteryUpdateVoltage(timeUs_t currentTimeUs); void batteryUpdatePresence(void); +bool isVoltageFromBattery(void); + batteryState_e getBatteryState(void); batteryState_e getVoltageState(void); batteryState_e getConsumptionState(void); diff --git a/src/main/sensors/voltage.c b/src/main/sensors/voltage.c index 61332b787b3..2fe2d26638e 100644 --- a/src/main/sensors/voltage.c +++ b/src/main/sensors/voltage.c @@ -89,7 +89,10 @@ const uint8_t supportedVoltageMeterCount = ARRAYLEN(voltageMeterIds); void voltageMeterReset(voltageMeter_t *meter) { meter->displayFiltered = 0; + meter->prevDisplayFiltered = 0; + meter->prevDisplayFilteredTime = 0; meter->unfiltered = 0; + meter->isVoltageStable = false; #if defined(USE_BATTERY_VOLTAGE_SAG_COMPENSATION) meter->sagFiltered = 0; #endif diff --git a/src/main/sensors/voltage.h b/src/main/sensors/voltage.h index b1f1f6c4c2c..2de9f897d04 100644 --- a/src/main/sensors/voltage.h +++ b/src/main/sensors/voltage.h @@ -25,6 +25,8 @@ #define SLOW_VOLTAGE_TASK_FREQ_HZ 50 #define FAST_VOLTAGE_TASK_FREQ_HZ 200 +#define PREV_DISPLAY_FILTERED_TIME_DIFF 500 // ms + // // meters // @@ -42,6 +44,9 @@ extern const char * const voltageMeterSourceNames[VOLTAGE_METER_COUNT]; typedef struct voltageMeter_s { uint16_t displayFiltered; // voltage in 0.01V steps + uint16_t prevDisplayFiltered; // voltage in 0.01V steps + timeMs_t prevDisplayFilteredTime; + bool isVoltageStable; uint16_t unfiltered; // voltage in 0.01V steps #if defined(USE_BATTERY_VOLTAGE_SAG_COMPENSATION) uint16_t sagFiltered; // voltage in 0.01V steps