summaryrefslogtreecommitdiff
path: root/src/tangara/battery/battery.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-06-25 12:45:39 +1000
committerjacqueline <me@jacqueline.id.au>2024-06-25 12:45:39 +1000
commitd75927ff92b3513732573b70747e8311f91bfaed (patch)
treea3a0b6bed5363dda2c41529f75f7d9abdffeefc5 /src/tangara/battery/battery.cpp
parent5e2945f24612641cb41c91405a651ffcbc51cb37 (diff)
downloadtangara-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.cpp19
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) {