fix: Use a formula table to better approximate remaining battery capacity

This commit is contained in:
MickiusMousius 2023-12-11 17:30:53 +10:30
parent 2c50cff891
commit f4c9b12d78

View file

@ -29,15 +29,36 @@ int battery_channel_get(const struct battery_value *value, enum sensor_channel c
return 0;
}
uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) {
// Simple linear approximation of a battery based off adafruit's discharge graph:
// https://learn.adafruit.com/li-ion-and-lipoly-batteries/voltages
typedef struct {
int16_t millivolts;
float slope;
float offset;
} batt_est_formula;
if (bat_mv >= 4200) {
return 100;
} else if (bat_mv <= 3450) {
return 0;
uint8_t lithium_ion_mv_to_pct(int16_t bat_mv) {
// Lookup table of slope formulas for calculating remaining battery capacity.
// The original values used to calculate slopes come from:
//
// https://blog.ampow.com/lipo-voltage-chart/
const batt_est_formula lipo_formula_lookup[9] = {
{.millivolts = 4200, .slope = 0, .offset = 100},
{.millivolts = 4150, .slope = 0.1, .offset = -320},
{.millivolts = 4110, .slope = 0.125, .offset = -423.75},
{.millivolts = 4020, .slope = 0.111, .offset = -366.22},
{.millivolts = 3870, .slope = 0.133, .offset = -454.68},
{.millivolts = 3690, .slope = 0.278, .offset = -1015.84},
{.millivolts = 3610, .slope = 0.063, .offset = -222.47},
{.millivolts = 3270, .slope = 0.015, .offset = -48.09},
};
for (int i = 0; i < 9; i++) {
batt_est_formula current_formula = lipo_formula_lookup[i];
if (bat_mv >= current_formula.millivolts) {
float capacity = bat_mv * current_formula.slope + current_formula.offset;
return (uint8_t)capacity;
}
}
return bat_mv * 2 / 15 - 459;
return 0;
}