charge_control: refactoring, bug fixes
- Moved shared state transition checks to separate function - Improved behaviour when the battery is full
This commit is contained in:
parent
d9bc181973
commit
7ca6104e80
|
@ -57,13 +57,46 @@ static fxp_t sleep_solar_current;
|
||||||
static fxp_t sleep_solar_excess_voltage;
|
static fxp_t sleep_solar_excess_voltage;
|
||||||
|
|
||||||
|
|
||||||
static void control_solar_switch(fxp_t u_bat, fxp_t corridor_high, fxp_t corridor_low)
|
static enum ChargeState control_solar_charging(
|
||||||
|
fxp_t corridor_high,
|
||||||
|
fxp_t corridor_low,
|
||||||
|
uint64_t uptime_ms,
|
||||||
|
struct MeasurementResult *meas,
|
||||||
|
enum ChargeState current_state,
|
||||||
|
uint64_t time_in_state)
|
||||||
{
|
{
|
||||||
if(u_bat >= corridor_high) {
|
static uint64_t last_switch_change_time = 0;
|
||||||
|
uint64_t solar_switch_onoff_duration = uptime_ms - last_switch_change_time;
|
||||||
|
|
||||||
|
bool last_switch_state = power_switch_solar_status();
|
||||||
|
|
||||||
|
if(meas->u_bat >= corridor_high) {
|
||||||
power_switch_solar_off();
|
power_switch_solar_off();
|
||||||
} else if(u_bat <= corridor_low) {
|
} else if(meas->u_bat <= corridor_low) {
|
||||||
power_switch_solar_on();
|
power_switch_solar_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool current_switch_state = power_switch_solar_status();
|
||||||
|
|
||||||
|
if(last_switch_state != current_switch_state) { // switch changed
|
||||||
|
last_switch_change_time = uptime_ms;
|
||||||
|
solar_switch_onoff_duration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// temperature limit
|
||||||
|
if(meas->temperature > internal_temperature_limit) {
|
||||||
|
return CHARGE_HIGH_TEMPERATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// low-current limit (go to sleep at night)
|
||||||
|
if((time_in_state > SLEEP_STATE_DELAY)
|
||||||
|
&& (current_switch_state == true)
|
||||||
|
&& (solar_switch_onoff_duration > SLEEP_SWITCH_DELAY)
|
||||||
|
&& (meas->i_solar < sleep_solar_current)) {
|
||||||
|
return CHARGE_SLEEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return current_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,52 +119,46 @@ static void solar_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHARGE_INITIAL:
|
case CHARGE_INITIAL:
|
||||||
control_solar_switch(meas->u_bat, u_bat_initial_full, u_bat_initial_low);
|
charge_state = control_solar_charging(
|
||||||
|
u_bat_initial_full,
|
||||||
// temperature limit
|
u_bat_initial_low,
|
||||||
if(meas->temperature > internal_temperature_limit) {
|
uptime_ms,
|
||||||
charge_state = CHARGE_HIGH_TEMPERATURE;
|
meas,
|
||||||
break;
|
charge_state,
|
||||||
}
|
charge_time_in_state);
|
||||||
|
|
||||||
// time limit for initial charging
|
// time limit for initial 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;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// low-current limit (go to sleep at night)
|
|
||||||
if(meas->i_solar < sleep_solar_current) {
|
|
||||||
charge_state = CHARGE_SLEEP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHARGE_TRANSITION:
|
case CHARGE_TRANSITION:
|
||||||
// FIXME: dynamically adjust thresholds
|
// FIXME: dynamically adjust thresholds
|
||||||
control_solar_switch(meas->u_bat, u_bat_float_full, u_bat_float_low);
|
charge_state = control_solar_charging(
|
||||||
|
u_bat_float_full,
|
||||||
// temperature limit
|
u_bat_float_low,
|
||||||
if(meas->temperature > internal_temperature_limit) {
|
uptime_ms,
|
||||||
charge_state = CHARGE_HIGH_TEMPERATURE;
|
meas,
|
||||||
break;
|
charge_state,
|
||||||
}
|
charge_time_in_state);
|
||||||
|
|
||||||
// time limit for transition to float charging
|
// time limit for transition to float charging
|
||||||
if(charge_time_in_state > INITIAL_TO_FLOAT_TRANSITION_TIME) {
|
if(charge_time_in_state > INITIAL_TO_FLOAT_TRANSITION_TIME) {
|
||||||
charge_state = CHARGE_FLOAT;
|
charge_state = CHARGE_FLOAT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// low-current limit (go to sleep at night)
|
|
||||||
if(meas->i_solar < sleep_solar_current) {
|
|
||||||
charge_state = CHARGE_SLEEP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHARGE_FLOAT:
|
case CHARGE_FLOAT:
|
||||||
control_solar_switch(meas->u_bat, u_bat_float_full, u_bat_float_low);
|
charge_state = control_solar_charging(
|
||||||
|
u_bat_float_full,
|
||||||
|
u_bat_float_low,
|
||||||
|
uptime_ms,
|
||||||
|
meas,
|
||||||
|
charge_state,
|
||||||
|
charge_time_in_state);
|
||||||
|
|
||||||
// temperature limit
|
// temperature limit
|
||||||
if(meas->temperature > internal_temperature_limit) {
|
if(meas->temperature > internal_temperature_limit) {
|
||||||
|
@ -195,7 +222,7 @@ static void load_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas)
|
||||||
// calculate charge pump output excess voltage over battery voltage
|
// calculate charge pump output excess voltage over battery voltage
|
||||||
// and compare to the threshold
|
// and compare to the threshold
|
||||||
if(fxp_sub(meas->u_sw, meas->u_bat) > min_charge_pump_excess_voltage) {
|
if(fxp_sub(meas->u_sw, meas->u_bat) > min_charge_pump_excess_voltage) {
|
||||||
discharge_state = DISCHARGE_VOLTAGE_LOW;
|
discharge_state = DISCHARGE_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,13 @@
|
||||||
|
|
||||||
/* Minimum charge current required before charging is stopped to save power at
|
/* Minimum charge current required before charging is stopped to save power at
|
||||||
* the charge pump (in mA). */
|
* the charge pump (in mA). */
|
||||||
#define SLEEP_SOLAR_CURRENT 5
|
#define SLEEP_SOLAR_CURRENT 1
|
||||||
|
|
||||||
|
/* Delay between state change and sleep state check (in ms). */
|
||||||
|
#define SLEEP_STATE_DELAY 100
|
||||||
|
|
||||||
|
/* Delay between charging switch state change and sleep state check(in ms). */
|
||||||
|
#define SLEEP_SWITCH_DELAY 1000
|
||||||
|
|
||||||
/* Maximum allowed microcontroller temperature (in units of 0.1 °C). If this
|
/* Maximum allowed microcontroller temperature (in units of 0.1 °C). If this
|
||||||
* temperature is exceeded, charging is stopped. The load is kept on. Do not
|
* temperature is exceeded, charging is stopped. The load is kept on. Do not
|
||||||
|
|
Loading…
Reference in a new issue