feat: Add ability to fetch battery voltage.
* To be able to use the Zephyr `voltage-divider` driver, add a mode for fetching raw voltage from the sensor and do state of charge calculation outside of the driver.
This commit is contained in:
parent
931a36ff4a
commit
44358798d3
2 changed files with 55 additions and 1 deletions
14
app/Kconfig
14
app/Kconfig
|
@ -383,6 +383,20 @@ config ZMK_BATTERY_REPORTING
|
|||
select ZMK_LOW_PRIORITY_WORK_QUEUE
|
||||
imply BT_BAS if ZMK_BLE
|
||||
|
||||
if ZMK_BATTERY_REPORTING
|
||||
|
||||
choice ZMK_BATTERY_REPORTING_FETCH_MODE
|
||||
prompt "Battery Reporting Fetch Mode"
|
||||
|
||||
config ZMK_BATTERY_REPORTING_FETCH_MODE_STATE_OF_CHARGE
|
||||
bool "State of charge"
|
||||
|
||||
config ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE
|
||||
bool "Lithium Voltage"
|
||||
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config ZMK_IDLE_TIMEOUT
|
||||
int "Milliseconds of inactivity before entering idle state (OLED shutoff, etc)"
|
||||
default 30000
|
||||
|
|
|
@ -34,11 +34,29 @@ static const struct device *const battery = DEVICE_DT_GET(DT_CHOSEN(zmk_battery)
|
|||
static const struct device *battery;
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE)
|
||||
static 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
|
||||
|
||||
if (bat_mv >= 4200) {
|
||||
return 100;
|
||||
} else if (bat_mv <= 3450) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bat_mv * 2 / 15 - 459;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE)
|
||||
|
||||
static int zmk_battery_update(const struct device *battery) {
|
||||
struct sensor_value state_of_charge;
|
||||
int rc;
|
||||
|
||||
int rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE);
|
||||
#if IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_STATE_OF_CHARGE)
|
||||
|
||||
rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE);
|
||||
if (rc != 0) {
|
||||
LOG_DBG("Failed to fetch battery values: %d", rc);
|
||||
return rc;
|
||||
|
@ -50,6 +68,28 @@ static int zmk_battery_update(const struct device *battery) {
|
|||
LOG_DBG("Failed to get battery state of charge: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
#elif IS_ENABLED(CONFIG_ZMK_BATTERY_REPORTING_FETCH_MODE_LITHIUM_VOLTAGE)
|
||||
rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_VOLTAGE);
|
||||
if (rc != 0) {
|
||||
LOG_DBG("Failed to fetch battery values: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct sensor_value voltage;
|
||||
rc = sensor_channel_get(battery, SENSOR_CHAN_VOLTAGE, &voltage);
|
||||
|
||||
if (rc != 0) {
|
||||
LOG_DBG("Failed to get battery voltage: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
uint16_t mv = voltage.val1 * 1000 + (voltage.val2 / 1000);
|
||||
state_of_charge.val1 = lithium_ion_mv_to_pct(mv);
|
||||
|
||||
LOG_DBG("State of change %d from %d mv", state_of_charge.val1, mv);
|
||||
#else
|
||||
#error "Not a supported reporting fetch mode"
|
||||
#endif
|
||||
|
||||
if (last_state_of_charge != state_of_charge.val1) {
|
||||
last_state_of_charge = state_of_charge.val1;
|
||||
|
|
Loading…
Add table
Reference in a new issue