diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-08-22 15:55:25 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-08-22 15:55:25 +1000 |
| commit | ee949829d98c3b8df685319559a5798aad74bf13 (patch) | |
| tree | 68cbf80bdc61a2bdb7572d33e47c7f6230555406 /src/drivers/battery.cpp | |
| parent | 9c105cf613fb849268d619dc887dc2b54dcd4ec6 (diff) | |
| download | tangara-fw-ee949829d98c3b8df685319559a5798aad74bf13.tar.gz | |
Add battery % with change events
Diffstat (limited to 'src/drivers/battery.cpp')
| -rw-r--r-- | src/drivers/battery.cpp | 33 |
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 |
