mirror of https://github.com/zmkfirmware/zmk.git
Fix: Use a lookup table & interpolation to better estimate remaining battery capacity
The old battery capacity estimate code uses a linear approximation to estimate the remaining battery capacity. This is computationally very efficient, however, the estimate is very inaccurate once below 60%. This change uses a small table of bounded functions to provide a more accurate estimate of remaining capacity. The values in the table re-implement the old estimation "curve".
This commit is contained in:
parent
90bca78300
commit
5ceaa1b879
|
|
@ -29,15 +29,37 @@ 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
|
||||
uint8_t lithium_ion_mv_to_pct(int16_t batt_mv) {
|
||||
// Lookup table of slope formulas for calculating remaining battery capacity.
|
||||
//
|
||||
// The current set of values acheives the same as: bat_mv * 2 / 15 - 459;
|
||||
//
|
||||
// Future updates sould include more complete lookup tables for different
|
||||
// battery types slectable through config flags.
|
||||
struct lookup_point {
|
||||
int16_t millivolts;
|
||||
int16_t percent;
|
||||
};
|
||||
|
||||
if (bat_mv >= 4200) {
|
||||
return 100;
|
||||
} else if (bat_mv <= 3450) {
|
||||
return 0;
|
||||
static const struct lookup_point battery_lookup[] = {
|
||||
{.millivolts = 4200, .percent = 100},
|
||||
{.millivolts = 3450, .percent = 0},
|
||||
};
|
||||
|
||||
if (batt_mv > battery_lookup[0].millivolts) {
|
||||
return battery_lookup[0].percent;
|
||||
}
|
||||
|
||||
return bat_mv * 2 / 15 - 459;
|
||||
for (int i = 1; i < ARRAY_SIZE(battery_lookup); i++) {
|
||||
struct lookup_point one = battery_lookup[i - 1];
|
||||
struct lookup_point two = battery_lookup[i];
|
||||
if (batt_mv >= two.millivolts) {
|
||||
const int t = batt_mv - one.millivolts;
|
||||
const int dx = two.millivolts - one.millivolts;
|
||||
const int dy = two.percent - one.percent;
|
||||
return one.percent + dy * t / dx;
|
||||
}
|
||||
}
|
||||
|
||||
return battery_lookup[ARRAY_SIZE(battery_lookup) - 1].percent;
|
||||
}
|
||||
Loading…
Reference in New Issue