diff options
| author | jacqueline <me@jacqueline.id.au> | 2024-06-25 12:45:39 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2024-06-25 12:45:39 +1000 |
| commit | d75927ff92b3513732573b70747e8311f91bfaed (patch) | |
| tree | a3a0b6bed5363dda2c41529f75f7d9abdffeefc5 /src/tangara/battery/battery.cpp | |
| parent | 5e2945f24612641cb41c91405a651ffcbc51cb37 (diff) | |
| download | tangara-fw-d75927ff92b3513732573b70747e8311f91bfaed.tar.gz | |
Use a curve to estimate battery %
This is a bit more accurate than our previous linear relationship,
particularly at lower voltages.
Diffstat (limited to 'src/tangara/battery/battery.cpp')
| -rw-r--r-- | src/tangara/battery/battery.cpp | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/src/tangara/battery/battery.cpp b/src/tangara/battery/battery.cpp index 2d2fff56..3cfdb20c 100644 --- a/src/tangara/battery/battery.cpp +++ b/src/tangara/battery/battery.cpp @@ -5,7 +5,9 @@ */ #include "battery/battery.hpp" +#include <stdint.h> +#include <cmath> #include <cstdint> #include "drivers/adc.hpp" @@ -58,14 +60,17 @@ auto Battery::Update() -> void { auto charge_state = samd_.GetChargeStatus(); - // FIXME: So what we *should* do here is measure the actual real-life - // time from full battery -> empty battery, store it in NVS, then rely on - // that. If someone could please do this, it would be lovely. Thanks! uint32_t mV = std::max(adc_->Millivolts(), kEmptyChargeMilliVolts); - uint_fast8_t percent = static_cast<uint_fast8_t>(std::min<double>( - std::max<double>(0.0, mV - kEmptyChargeMilliVolts) / - (kFullChargeMilliVolts - kEmptyChargeMilliVolts) * 100.0, - 100.0)); + + // Ideally the way you're 'supposed' to measure battery charge percent is to + // keep continuous track of the amps going in and out of it at any point. I'm + // skeptical of this approach, and we're not set up with the hardware needed + // to do it anyway. Instead, we use a curve-fitting formula by StackOverflow + // user 'Roho' to estimate the remaining capacity based on the battery's + // voltage. This seems to work pretty good! + double v = mV / 1000.0; + uint_fast8_t percent = static_cast<uint_fast8_t>(std::clamp<double>( + 123 - (123 / std::pow(1 + std::pow(v / 3.7, 80.0), 0.165)), 0.0, 100.0)); bool is_charging; if (!charge_state) { |
