Reworked battery charge state detection for boards with only ADC-based PMU. Improved battery charge status info on display.

This commit is contained in:
Mark Qvist 2025-11-10 15:49:52 +01:00
parent 427c06bf81
commit 59c0a60b33
3 changed files with 53 additions and 23 deletions

View file

@ -574,6 +574,9 @@ void draw_battery_bars(int px, int py) {
}
if (battery_state == BATTERY_STATE_CHARGING && !disable_charge_status) {
float battery_prog = battery_percent;
if (battery_prog > 85) { battery_prog = 84; }
if (charge_tick < battery_prog ) { charge_tick = battery_prog; }
battery_value = charge_tick;
charge_tick += 3;
if (charge_tick > 100) charge_tick = 0;

View file

@ -204,13 +204,13 @@ upload-heltec32_v3:
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
@sleep 1
rnodeconf /dev/ttyUSB0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware.ino.bin)
@sleep 3
python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
#@sleep 3
#python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
upload-heltec32_v4:
arduino-cli upload -p /dev/ttyACM1 --fqbn esp32:esp32:esp32s3
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32s3
@sleep 1
rnodeconf /dev/ttyACM1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware.ino.bin)
rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware.ino.bin)
#@sleep 3
#python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin

65
Power.h
View file

@ -95,8 +95,19 @@
float bat_delay_v = 0;
float bat_state_change_v = 0;
#elif BOARD_MODEL == BOARD_HELTEC32_V3
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.3
// Unless we implement some real voodoo
// on these boards, we can't say with
// any certainty whether we are actually
// charging and have reached a charge
// complete state. The *only* data point
// we have to go from is the bus voltage.
// The BAT_V_CHG and BAT_V_FLOAT values
// are set high here to avoid the display
// indication confusingly flapping
// between charge completed, charging and
// discharging states.
#define BAT_V_MIN 3.05
#define BAT_V_MAX 4.0
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 7
@ -112,8 +123,8 @@
float bat_delay_v = 0;
float bat_state_change_v = 0;
#elif BOARD_MODEL == BOARD_HELTEC32_V4
#define BAT_V_MIN 3.15
#define BAT_V_MAX 4.3
#define BAT_V_MIN 3.05
#define BAT_V_MAX 4.0
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 7
@ -166,19 +177,28 @@
uint32_t last_pmu_update = 0;
uint8_t pmu_target_pps = 1;
int pmu_update_interval = 1000/pmu_target_pps;
uint8_t pmu_charged_ascertain = 0;
uint8_t pmu_rc = 0;
uint8_t pmu_sc = 0;
float bat_delay_diff = 0;
bool bat_diff_positive = false;
#define PMU_R_INTERVAL 5
#define PMU_SCV_RESET_INTERVAL 3
void kiss_indicate_battery();
void measure_battery() {
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_HELTEC_T114 || BOARD_MODEL == BOARD_TECHO
battery_installed = true;
battery_indeterminate = true;
#if BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4
battery_indeterminate = false;
#else
battery_indeterminate = true;
#endif
#if BOARD_MODEL == BOARD_HELTEC32_V3
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.0041;
#elif BOARD_MODEL == BOARD_HELTEC32_V4
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.0041;
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.00418;
#elif BOARD_MODEL == BOARD_T3S3
float battery_measurement = (float)(analogRead(pin_vbat)) / 4095.0*6.7828;
#elif BOARD_MODEL == BOARD_HELTEC_T114
@ -217,23 +237,23 @@ void measure_battery() {
if (battery_percent < 0.0) battery_percent = 0.0;
if (bat_samples_count%BAT_SAMPLES == 0) {
float bat_delay_diff = bat_state_change_v-battery_voltage;
if (bat_delay_diff < 0) { bat_delay_diff *= -1; }
pmu_sc++;
bat_delay_diff = battery_voltage-bat_state_change_v;
if (battery_voltage < bat_delay_v && battery_voltage < BAT_V_FLOAT) {
if (bat_voltage_dropping == false) {
if (bat_delay_diff > 0.008) {
if (bat_delay_diff < -0.008) {
bat_voltage_dropping = true;
bat_state_change_v = battery_voltage;
// SerialBT.printf("STATE CHANGE to DISCHARGE at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v);
}
} else {
if (pmu_sc%PMU_SCV_RESET_INTERVAL == 0) { bat_state_change_v = battery_voltage; }
}
} else {
if (bat_voltage_dropping == true) {
if (bat_delay_diff > 0.01) {
bat_voltage_dropping = false;
bat_state_change_v = battery_voltage;
// SerialBT.printf("STATE CHANGE to CHARGE at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v);
}
}
}
@ -242,12 +262,19 @@ void measure_battery() {
}
if (bat_voltage_dropping && battery_voltage < BAT_V_FLOAT) {
// if (battery_state != BATTERY_STATE_DISCHARGING) { SerialBT.printf("STATE CHANGE to DISCHARGING at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); }
battery_state = BATTERY_STATE_DISCHARGING;
pmu_charged_ascertain = 0;
} else {
if (battery_percent < 100.0) {
battery_state = BATTERY_STATE_CHARGING;
} else {
battery_state = BATTERY_STATE_CHARGED;
if (pmu_charged_ascertain < 8) { pmu_charged_ascertain++; }
else {
if (battery_percent < 100.0) {
// if (battery_state != BATTERY_STATE_CHARGING) { SerialBT.printf("STATE CHANGE to CHARGING at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); }
battery_state = BATTERY_STATE_CHARGING;
} else {
// if (battery_state != BATTERY_STATE_CHARGED) { SerialBT.printf("STATE CHANGE to CHARGED at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); }
battery_state = BATTERY_STATE_CHARGED;
}
}
}
@ -256,11 +283,11 @@ void measure_battery() {
#endif
// if (bt_state == BT_STATE_CONNECTED) {
// SerialBT.printf("\nBus voltage %.3fv. Unfiltered %.3fv.", battery_voltage, bat_v_samples[BAT_SAMPLES-1]);
// SerialBT.printf("\nBus voltage %.3fv. Unfiltered %.3fv. Diff %.3f", battery_voltage, bat_v_samples[BAT_SAMPLES-1], bat_delay_diff);
// if (bat_voltage_dropping) { SerialBT.printf("\n Voltage is dropping. Percentage %.1f%%.", battery_percent); }
// else { SerialBT.printf("\n Voltage is not dropping. Percentage %.1f%%.", battery_percent); }
// if (battery_state == BATTERY_STATE_DISCHARGING) { SerialBT.printf("\n Battery discharging. delay_v %.3fv", bat_delay_v); }
// if (battery_state == BATTERY_STATE_CHARGING) { SerialBT.printf("\n Battery charging. delay_v %.3fv", bat_delay_v); }
// if (battery_state == BATTERY_STATE_DISCHARGING) { SerialBT.printf("\n Battery discharging. delay_v %.3fv\nState change at %.3fv", bat_delay_v, bat_state_change_v); }
// if (battery_state == BATTERY_STATE_CHARGING) { SerialBT.printf("\n Battery charging. delay_v %.3fv\nState change at %.3fv", bat_delay_v, bat_state_change_v); }
// if (battery_state == BATTERY_STATE_CHARGED) { SerialBT.print("\n Battery is charged."); }
// SerialBT.print("\n");
// }
@ -389,7 +416,7 @@ bool init_pmu() {
return true;
#elif BOARD_MODEL == BOARD_HELTEC32_V4
pinMode(pin_ctrl,OUTPUT);
digitalWrite(pin_ctrl, LOW);
digitalWrite(pin_ctrl, HIGH);
return true;
#elif BOARD_MODEL == BOARD_HELTEC_T114
pinMode(pin_ctrl,OUTPUT);