summaryrefslogtreecommitdiff
path: root/src/drivers/battery.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-22 15:55:25 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-22 15:55:25 +1000
commitee949829d98c3b8df685319559a5798aad74bf13 (patch)
tree68cbf80bdc61a2bdb7572d33e47c7f6230555406 /src/drivers/battery.cpp
parent9c105cf613fb849268d619dc887dc2b54dcd4ec6 (diff)
downloadtangara-fw-ee949829d98c3b8df685319559a5798aad74bf13.tar.gz
Add battery % with change events
Diffstat (limited to 'src/drivers/battery.cpp')
-rw-r--r--src/drivers/battery.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/drivers/battery.cpp b/src/drivers/battery.cpp
index 445e9c23..1755fd64 100644
--- a/src/drivers/battery.cpp
+++ b/src/drivers/battery.cpp
@@ -14,6 +14,21 @@
namespace drivers {
+/*
+ * Battery voltage, in millivolts, at which the battery charger IC will stop
+ * charging.
+ */
+static const uint32_t kFullChargeMilliVolts = 4200;
+
+/*
+ * Battery voltage, in millivolts, at which *we* will consider the battery to
+ * be completely discharged. This is intentionally higher than the charger IC
+ * cut-off and the protection on the battery itself; we want to make sure we
+ * finish up and have everything unmounted and snoozing before the BMS cuts us
+ * off.
+ */
+static const uint32_t kEmptyChargeMilliVolts = 3200; // BMS limit is 3100.
+
static const adc_bitwidth_t kAdcBitWidth = ADC_BITWIDTH_12;
static const adc_unit_t kAdcUnit = ADC_UNIT_1;
// Max battery voltage should be a little over 2V due to our divider, so we need
@@ -44,6 +59,8 @@ Battery::Battery() {
};
ESP_ERROR_CHECK(adc_cali_create_scheme_line_fitting(
&calibration_config, &adc_calibration_handle_));
+
+ UpdatePercent();
}
Battery::~Battery() {
@@ -60,7 +77,21 @@ auto Battery::Millivolts() -> uint32_t {
ESP_ERROR_CHECK(
adc_cali_raw_to_voltage(adc_calibration_handle_, raw, &voltage));
- return voltage;
+ // Voltage divider halves the battery voltage to get it into the ADC's range.
+ return voltage * 2;
+}
+
+auto Battery::UpdatePercent() -> bool {
+ auto old_percent = percent_;
+ // 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(Millivolts(), kEmptyChargeMilliVolts);
+ percent_ = static_cast<uint_fast8_t>(std::min<double>(
+ std::max<double>(0.0, mV - kEmptyChargeMilliVolts) /
+ (kFullChargeMilliVolts - kEmptyChargeMilliVolts) * 100.0,
+ 100.0));
+ return old_percent != percent_;
}
} // namespace drivers