Improved power management for v2 RNodes and T-Beam devices
This commit is contained in:
parent
6a221ec67a
commit
6052c8cb40
2
Config.h
2
Config.h
|
@ -306,7 +306,9 @@
|
|||
#define BATTERY_STATE_CHARGING 0x02
|
||||
#define BATTERY_STATE_CHARGED 0x03
|
||||
bool battery_installed = false;
|
||||
bool battery_indeterminate = false;
|
||||
bool external_power = false;
|
||||
bool battery_ready = false;
|
||||
float battery_voltage = 0.0;
|
||||
float battery_percent = 0.0;
|
||||
uint8_t battery_state = 0x00;
|
||||
|
|
54
Display.h
54
Display.h
|
@ -166,23 +166,47 @@ void draw_mw_icon(int px, int py) {
|
|||
}
|
||||
|
||||
uint8_t charge_tick = 0;
|
||||
void draw_battery_bars(int px, int py) {
|
||||
void draw_battery_bars(int px, int py) {
|
||||
if (pmu_ready) {
|
||||
float battery_value = battery_percent;
|
||||
if (battery_state == BATTERY_STATE_CHARGING) {
|
||||
battery_value = charge_tick;
|
||||
charge_tick += 3;
|
||||
if (charge_tick > 100) charge_tick = 0;
|
||||
}
|
||||
if (battery_ready) {
|
||||
if (battery_installed) {
|
||||
float battery_value = battery_percent;
|
||||
|
||||
if (battery_state == BATTERY_STATE_CHARGING) {
|
||||
battery_value = charge_tick;
|
||||
charge_tick += 3;
|
||||
if (charge_tick > 100) charge_tick = 0;
|
||||
}
|
||||
|
||||
stat_area.fillRect(px, py, 14, 3, SSD1306_BLACK);
|
||||
if (battery_value > 7) stat_area.drawLine(px, py, px, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 20) stat_area.drawLine(px+1*2, py, px+1*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 33) stat_area.drawLine(px+2*2, py, px+2*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 46) stat_area.drawLine(px+3*2, py, px+3*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 59) stat_area.drawLine(px+4*2, py, px+4*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 72) stat_area.drawLine(px+5*2, py, px+5*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 85) stat_area.drawLine(px+6*2, py, px+6*2, py+2, SSD1306_WHITE);
|
||||
if (battery_indeterminate && battery_state == BATTERY_STATE_CHARGING) {
|
||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||
} else {
|
||||
if (battery_state == BATTERY_STATE_CHARGED) {
|
||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||
} else {
|
||||
// stat_area.fillRect(px, py, 14, 3, SSD1306_BLACK);
|
||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||
stat_area.drawRect(px-2, py-2, 17, 7, SSD1306_WHITE);
|
||||
stat_area.drawLine(px+15, py, px+15, py+3, SSD1306_WHITE);
|
||||
if (battery_value > 7) stat_area.drawLine(px, py, px, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 20) stat_area.drawLine(px+1*2, py, px+1*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 33) stat_area.drawLine(px+2*2, py, px+2*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 46) stat_area.drawLine(px+3*2, py, px+3*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 59) stat_area.drawLine(px+4*2, py, px+4*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 72) stat_area.drawLine(px+5*2, py, px+5*2, py+2, SSD1306_WHITE);
|
||||
if (battery_value > 85) stat_area.drawLine(px+6*2, py, px+6*2, py+2, SSD1306_WHITE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stat_area.fillRect(px-2, py-2, 18, 7, SSD1306_BLACK);
|
||||
stat_area.drawBitmap(px-2, py-2, bm_plug, 17, 7, SSD1306_WHITE, SSD1306_BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
Graphics.h
13
Graphics.h
|
@ -203,10 +203,10 @@ const unsigned char bm_frame [] PROGMEM = {
|
|||
0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x1c,
|
||||
0x20, 0x00, 0x31, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x31, 0x20, 0x00, 0x00, 0x00, 0x18,
|
||||
0x20, 0x00, 0x31, 0x40, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x20, 0xa0, 0x00, 0x00, 0x00, 0x38,
|
||||
0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa, 0x8a, 0xaa, 0x80
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x1c,
|
||||
0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x18,
|
||||
0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x38,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa, 0x8a, 0xaa, 0x80
|
||||
};
|
||||
|
||||
const unsigned char bm_checks [] PROGMEM = {
|
||||
|
@ -316,4 +316,9 @@ const unsigned char bm_n_uh [] PROGMEM = {
|
|||
0xe7, 0xc7, 0xe7, 0x07, 0x27, 0x27, 0x07, 0xe7, 0xe7, 0x07, 0x3f, 0x07, 0xe7, 0x07, 0x07, 0x3f,
|
||||
0x07, 0x27, 0x07, 0x07, 0xc7, 0xcf, 0x9f, 0x1f, 0x07, 0x27, 0x07, 0x27, 0x07, 0x07, 0x27, 0x07,
|
||||
0xe7, 0xe7
|
||||
};
|
||||
|
||||
const unsigned char bm_plug [] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x7f, 0x80, 0x55, 0xfc, 0x00, 0xaa, 0xfc, 0x00, 0x00,
|
||||
0x7f, 0x80, 0x00, 0x1c, 0x00
|
||||
};
|
105
Power.h
105
Power.h
|
@ -2,18 +2,31 @@
|
|||
#include <axp20x.h>
|
||||
AXP20X_Class PMU;
|
||||
|
||||
#define BAT_V_MIN 3.15
|
||||
#define BAT_V_MAX 4.14
|
||||
|
||||
void disablePeripherals() {
|
||||
PMU.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
|
||||
PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
|
||||
PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
|
||||
}
|
||||
#elif BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1
|
||||
#define BAT_V_INSTALLED 3.0
|
||||
#define BAT_V_MIN 3.4
|
||||
#define BAT_V_MAX 4.2
|
||||
#define BAT_V_CHG 4.345
|
||||
#define BAT_V_CHGD 4.31
|
||||
#define BAT_C_SAMPLES 7
|
||||
#define BAT_D_SAMPLES 2
|
||||
#define BAT_V_MIN 3.15
|
||||
#define BAT_V_MAX 4.3
|
||||
#define BAT_V_CHG 4.48
|
||||
#define BAT_V_FLOAT 4.33
|
||||
#define BAT_SAMPLES 5
|
||||
const uint8_t pin_vbat = 35;
|
||||
float bat_p_samples[BAT_SAMPLES];
|
||||
float bat_v_samples[BAT_SAMPLES];
|
||||
uint8_t bat_samples_count = 0;
|
||||
int bat_discharging_samples = 0;
|
||||
int bat_charging_samples = 0;
|
||||
int bat_charged_samples = 0;
|
||||
bool bat_voltage_dropping = false;
|
||||
float bat_delay_v = 0;
|
||||
#endif
|
||||
|
||||
uint32_t last_pmu_update = 0;
|
||||
|
@ -22,28 +35,68 @@ int pmu_update_interval = 1000/pmu_target_pps;
|
|||
|
||||
void measure_battery() {
|
||||
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1
|
||||
battery_voltage = (float)(analogRead(pin_vbat)) / 4095*2*3.3*1.1;
|
||||
battery_percent = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0;
|
||||
battery_installed = true;
|
||||
battery_indeterminate = true;
|
||||
bat_v_samples[bat_samples_count%BAT_SAMPLES] = (float)(analogRead(pin_vbat)) / 4095*2*3.3*1.1;
|
||||
bat_p_samples[bat_samples_count%BAT_SAMPLES] = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0;
|
||||
|
||||
bat_samples_count++;
|
||||
if (!battery_ready && bat_samples_count >= BAT_SAMPLES) {
|
||||
battery_ready = true;
|
||||
}
|
||||
|
||||
if (battery_voltage > BAT_V_INSTALLED) { battery_installed = true; } else { battery_installed = false; }
|
||||
if (battery_percent > 100.0) battery_percent = 100.0;
|
||||
if (battery_ready) {
|
||||
|
||||
if (battery_voltage > BAT_V_CHG) {
|
||||
battery_state = BATTERY_STATE_CHARGING;
|
||||
// Serial.printf("Battery charging. Voltage=%.2fv, percentage: %.2f%\n", battery_voltage, battery_percent);
|
||||
} else if (battery_voltage > BAT_V_CHGD) {
|
||||
battery_state = BATTERY_STATE_CHARGED;
|
||||
// Serial.printf("Battery charged. Voltage=%.2fv, percentage: %.2f%\n", battery_voltage, battery_percent);
|
||||
} else {
|
||||
battery_state = BATTERY_STATE_DISCHARGING;
|
||||
// Serial.printf("Battery discharging. Voltage=%.2fv, percentage: %.2f%\n", battery_voltage, battery_percent);
|
||||
battery_percent = 0;
|
||||
for (uint8_t bi = 0; bi < BAT_SAMPLES; bi++) {
|
||||
battery_percent += bat_p_samples[bi];
|
||||
}
|
||||
battery_percent = battery_percent/BAT_SAMPLES;
|
||||
|
||||
battery_voltage = 0;
|
||||
for (uint8_t bi = 0; bi < BAT_SAMPLES; bi++) {
|
||||
battery_voltage += bat_v_samples[bi];
|
||||
}
|
||||
battery_voltage = battery_voltage/BAT_SAMPLES;
|
||||
|
||||
if (bat_delay_v == 0) bat_delay_v = battery_voltage;
|
||||
if (battery_percent > 100.0) battery_percent = 100.0;
|
||||
if (battery_percent < 0.0) battery_percent = 0.0;
|
||||
|
||||
if (bat_samples_count%BAT_SAMPLES == 0) {
|
||||
if (battery_voltage < bat_delay_v && battery_voltage < BAT_V_FLOAT) {
|
||||
bat_voltage_dropping = true;
|
||||
} else {
|
||||
bat_voltage_dropping = false;
|
||||
}
|
||||
bat_samples_count = 0;
|
||||
}
|
||||
|
||||
if (bat_voltage_dropping && battery_voltage < BAT_V_FLOAT) {
|
||||
battery_state = BATTERY_STATE_DISCHARGING;
|
||||
} else {
|
||||
#if BOARD_MODEL == BOARD_RNODE_NG_21
|
||||
battery_state = BATTERY_STATE_CHARGING;
|
||||
#else
|
||||
battery_state = BATTERY_STATE_DISCHARGING;
|
||||
#endif
|
||||
}
|
||||
|
||||
// if (bt_state == BT_STATE_CONNECTED) {
|
||||
// SerialBT.printf("Bus voltage %.3fv. Unfiltered %.3fv.", battery_voltage, bat_v_samples[BAT_SAMPLES-1]);
|
||||
// if (bat_voltage_dropping) {
|
||||
// SerialBT.printf(" Voltage is dropping. Percentage %.1f%%.\n", battery_percent);
|
||||
// } else {
|
||||
// SerialBT.print(" Voltage is not dropping.\n");
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
#elif BOARD_MODEL == BOARD_TBEAM
|
||||
float discharge_current = PMU.getBattDischargeCurrent();
|
||||
float charge_current = PMU.getBattChargeCurrent();
|
||||
battery_voltage = PMU.getBattVoltage()/1000.0;
|
||||
battery_percent = PMU.getBattPercentage()*1.0;
|
||||
// battery_percent = PMU.getBattPercentage()*1.0;
|
||||
battery_installed = PMU.isBatteryConnect();
|
||||
external_power = PMU.isVBUSPlug();
|
||||
float ext_voltage = PMU.getVbusVoltage()/1000.0;
|
||||
|
@ -52,11 +105,14 @@ void measure_battery() {
|
|||
if (battery_installed) {
|
||||
if (PMU.isChargeing()) {
|
||||
battery_state = BATTERY_STATE_CHARGING;
|
||||
battery_percent = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0;
|
||||
} else {
|
||||
if (discharge_current > 0.0) {
|
||||
battery_state = BATTERY_STATE_DISCHARGING;
|
||||
battery_percent = ((battery_voltage-BAT_V_MIN) / (BAT_V_MAX-BAT_V_MIN))*100.0;
|
||||
} else {
|
||||
battery_state = BATTERY_STATE_CHARGED;
|
||||
battery_percent = 100.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -65,10 +121,15 @@ void measure_battery() {
|
|||
battery_voltage = 0.0;
|
||||
}
|
||||
|
||||
if (battery_percent > 100.0) battery_percent = 100.0;
|
||||
if (battery_percent < 0.0) battery_percent = 0.0;
|
||||
|
||||
float charge_watts = battery_voltage*(charge_current/1000.0);
|
||||
float discharge_watts = battery_voltage*(discharge_current/1000.0);
|
||||
float ext_watts = ext_voltage*(ext_current/1000.0);
|
||||
|
||||
battery_ready = true;
|
||||
|
||||
// if (bt_state == BT_STATE_CONNECTED) {
|
||||
// if (battery_installed) {
|
||||
// if (external_power) {
|
||||
|
@ -76,8 +137,8 @@ void measure_battery() {
|
|||
// } else {
|
||||
// SerialBT.println("Running on battery");
|
||||
// }
|
||||
// SerialBT.printf("Battery percentage %.1f%\n", battery_percent);
|
||||
// SerialBT.printf("Battery voltage %.1f%\n", battery_voltage);
|
||||
// SerialBT.printf("Battery percentage %.1f%%\n", battery_percent);
|
||||
// SerialBT.printf("Battery voltage %.2fv\n", battery_voltage);
|
||||
// // SerialBT.printf("Temperature %.1f%\n", auxillary_temperature);
|
||||
|
||||
// if (battery_state == BATTERY_STATE_CHARGING) {
|
||||
|
@ -85,7 +146,7 @@ void measure_battery() {
|
|||
// } else if (battery_state == BATTERY_STATE_DISCHARGING) {
|
||||
// SerialBT.printf("Discharging at %.2fw, %.1fmA at %.1fV\n", discharge_watts, discharge_current, battery_voltage);
|
||||
// } else if (battery_state == BATTERY_STATE_CHARGED) {
|
||||
// SerialBT.printf("Battely charged\n");
|
||||
// SerialBT.printf("Battery charged\n");
|
||||
// }
|
||||
// } else {
|
||||
// SerialBT.println("No battery installed");
|
||||
|
|
Loading…
Reference in New Issue