diff options
Diffstat (limited to 'src/components/battery')
| -rw-r--r-- | src/components/battery/BatteryController.cpp | 30 | ||||
| -rw-r--r-- | src/components/battery/BatteryController.h | 7 |
2 files changed, 26 insertions, 11 deletions
diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index 300d0978..4d860490 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,4 +1,5 @@ #include "components/battery/BatteryController.h" +#include "components/utility/LinearApproximation.h" #include "drivers/PinMap.h" #include <hal/nrf_gpio.h> #include <nrfx_saadc.h> @@ -15,8 +16,8 @@ Battery::Battery() { } void Battery::ReadPowerState() { - isCharging = !nrf_gpio_pin_read(PinMap::Charging); - isPowerPresent = !nrf_gpio_pin_read(PinMap::PowerPresent); + isCharging = (nrf_gpio_pin_read(PinMap::Charging) == 0); + isPowerPresent = (nrf_gpio_pin_read(PinMap::PowerPresent) == 0); if (isPowerPresent && !isCharging) { isFull = true; @@ -60,8 +61,8 @@ void Battery::SaadcInit() { } void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { - const uint16_t battery_max = 4180; // maximum voltage of battery ( max charging voltage is 4.21 ) - const uint16_t battery_min = 3200; // minimum voltage of battery before shutdown ( depends on the battery ) + static const Utility::LinearApproximation<uint16_t, uint8_t, 6> approx { + {{{3500, 0}, {3616, 3}, {3723, 22}, {3776, 48}, {3979, 79}, {4180, 100}}}}; if (p_event->type == NRFX_SAADC_EVT_DONE) { @@ -74,19 +75,26 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { // p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024 voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024; - uint8_t newPercent; - if (isFull) { - newPercent = 100; - } else if (voltage < battery_min) { - newPercent = 0; - } else { - newPercent = std::min((voltage - battery_min) * 100 / (battery_max - battery_min), isCharging ? 99 : 100); + uint8_t newPercent = 100; + if (!isFull) { + // max. voltage while charging is higher than when discharging + newPercent = std::min(approx.GetValue(voltage), isCharging ? uint8_t {99} : uint8_t {100}); + } + + if (isPowerPresent) { + batteryLowNotified = false; } if ((isPowerPresent && newPercent > percentRemaining) || (!isPowerPresent && newPercent < percentRemaining) || firstMeasurement) { firstMeasurement = false; percentRemaining = newPercent; systemTask->PushMessage(System::Messages::BatteryPercentageUpdated); + + // warn about low battery when not charging and below threshold + if (BatteryIsLow() && !isPowerPresent && !batteryLowNotified) { + systemTask->PushMessage(System::Messages::LowBattery); + batteryLowNotified = true; + } } nrfx_saadc_uninit(); diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 5a7394c4..b47b77cc 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -18,6 +18,10 @@ namespace Pinetime { return percentRemaining; } + bool BatteryIsLow() const { + return percentRemaining <= lowBatteryThreshold; + } + uint16_t Voltage() const { return voltage; } @@ -39,6 +43,7 @@ namespace Pinetime { static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; uint16_t voltage = 0; uint8_t percentRemaining = 0; + bool batteryLowNotified = false; bool isFull = false; bool isCharging = false; @@ -50,6 +55,8 @@ namespace Pinetime { void SaadcEventHandler(nrfx_saadc_evt_t const* p_event); static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); + static constexpr uint8_t lowBatteryThreshold {15}; + bool isReading = false; Pinetime::System::SystemTask* systemTask = nullptr; |
