charge_control: add extra state to fix initial charging

Before this change, initial charging ended exactly HOLD_TIME after the
CHARGE_INITIAL state was entered. This was usually not sufficient to
reach the INITIAL_FULL voltage. Now a new state is entered once the
INITIAL_FULL voltage is reached.
This commit is contained in:
Thomas Kolb 2021-07-10 16:29:48 +02:00
parent d239a947cd
commit 0339b521dd
3 changed files with 31 additions and 1 deletions

View file

@ -13,6 +13,7 @@
static const char *CHARGE_STATE_TEXT[] = { static const char *CHARGE_STATE_TEXT[] = {
"WAIT_CHARGEPUMP", "WAIT_CHARGEPUMP",
"INITIAL", "INITIAL",
"INITIAL_HOLD",
"TRANSITION", "TRANSITION",
"FLOAT", "FLOAT",
"SLEEP", "SLEEP",
@ -40,6 +41,8 @@ static fxp_t u_bat_regulation_corridor;
static fxp_t u_bat_initial_full; static fxp_t u_bat_initial_full;
static fxp_t u_bat_initial_low; static fxp_t u_bat_initial_low;
static fxp_t u_bat_initial_hold_cancel;
static fxp_t u_bat_float_full; static fxp_t u_bat_float_full;
static fxp_t u_bat_float_low; static fxp_t u_bat_float_low;
@ -127,7 +130,28 @@ static void solar_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas)
charge_state, charge_state,
charge_time_in_state); charge_time_in_state);
// time limit for initial charging // switch to hold state when high threshold is reached
if(meas->u_bat >= u_bat_initial_full) {
charge_state = CHARGE_INITIAL_HOLD;
}
break;
case CHARGE_INITIAL_HOLD:
charge_state = control_solar_charging(
u_bat_initial_full,
u_bat_initial_low,
uptime_ms,
meas,
charge_state,
charge_time_in_state);
// cancel charge hold if battery voltage is below threshold
if(meas->u_bat <= u_bat_initial_hold_cancel) {
charge_state = CHARGE_INITIAL;
}
// time limit for initial hold charging
if(charge_time_in_state > INITIAL_CHARGE_HOLD_TIME) { if(charge_time_in_state > INITIAL_CHARGE_HOLD_TIME) {
charge_state = CHARGE_TRANSITION; charge_state = CHARGE_TRANSITION;
} }
@ -295,6 +319,8 @@ void charge_control_init(void)
u_bat_initial_full = fxp_div(FXP_FROM_INT(U_BAT_INITIAL_FULL), FXP_FROM_INT(1000)); u_bat_initial_full = fxp_div(FXP_FROM_INT(U_BAT_INITIAL_FULL), FXP_FROM_INT(1000));
u_bat_initial_low = fxp_sub(u_bat_initial_full, u_bat_regulation_corridor); u_bat_initial_low = fxp_sub(u_bat_initial_full, u_bat_regulation_corridor);
u_bat_initial_hold_cancel = fxp_div(FXP_FROM_INT(U_BAT_INITIAL_HOLD_CANCEL), FXP_FROM_INT(1000));
u_bat_float_full = fxp_div(FXP_FROM_INT(U_BAT_FLOAT_FULL), FXP_FROM_INT(1000)); u_bat_float_full = fxp_div(FXP_FROM_INT(U_BAT_FLOAT_FULL), FXP_FROM_INT(1000));
u_bat_float_low = fxp_sub(u_bat_float_full, u_bat_regulation_corridor); u_bat_float_low = fxp_sub(u_bat_float_full, u_bat_regulation_corridor);

View file

@ -11,6 +11,7 @@ enum ChargeState
{ {
CHARGE_WAIT_CHARGEPUMP, CHARGE_WAIT_CHARGEPUMP,
CHARGE_INITIAL, CHARGE_INITIAL,
CHARGE_INITIAL_HOLD,
CHARGE_TRANSITION, CHARGE_TRANSITION,
CHARGE_FLOAT, CHARGE_FLOAT,
CHARGE_SLEEP, CHARGE_SLEEP,

View file

@ -9,6 +9,9 @@
/* Initial charge battery voltage threshold (in mV). */ /* Initial charge battery voltage threshold (in mV). */
#define U_BAT_INITIAL_FULL 28600 // stop charging if battery voltage reaches this threshold #define U_BAT_INITIAL_FULL 28600 // stop charging if battery voltage reaches this threshold
/* Cancel initial charge voltage hold below this battery voltage (in mV). */
#define U_BAT_INITIAL_HOLD_CANCEL 28000
/* Transition to floating voltage levels after this time (in ms). */ /* Transition to floating voltage levels after this time (in ms). */
#define INITIAL_CHARGE_HOLD_TIME 3600000 #define INITIAL_CHARGE_HOLD_TIME 3600000