more logic and fixes, maybe buggy

master
Ondřej Hruška 2 years ago
parent 177eb7cf17
commit 475478aea4
  1. 2
      main/actuators.c
  2. 105
      main/fancontrol.c
  3. 21
      main/fancontrol.h
  4. 5
      main/settings.h

@ -76,6 +76,7 @@ static void motor_init() {
} }
void act_motor_power_set(uint16_t perc) { void act_motor_power_set(uint16_t perc) {
if (gAct.power == perc) return;
if (perc > 0) { if (perc > 0) {
if (perc < gSettings.min_power) { if (perc < gSettings.min_power) {
perc = gSettings.min_power; perc = gSettings.min_power;
@ -88,6 +89,7 @@ void act_motor_power_set(uint16_t perc) {
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, duty); ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, duty);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1); ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1);
} else { } else {
gAct.power = 0;
ledc_stop(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 0); ledc_stop(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 0);
} }
} }

@ -107,9 +107,64 @@ static void timerCallback(TimerHandle_t xTimer) {
if (gState.blind_position >= gSettings.blind_time) { if (gState.blind_position >= gSettings.blind_time) {
act_motor_power_set(gState.set_power); act_motor_power_set(gState.set_power);
// Stop condition if (gState.real_direction == gAct.dir && gState.run_time >= gSettings.min_recup_time) {
if (gState.real_direction == gAct.dir) { // Stop condition
if (gState.run_time >= gSettings.recup_time) { bool do_switch = false;
// TODO questionable logic, verify
if (gSettings.recup_mode == RECUP_MODE_TIME) {
do_switch = gState.run_time >= gSettings.recup_time;
} else if (gState.run_time >= gSettings.max_recup_time) {
do_switch = true;
} else {
// temp-based switching - magic(tm)
const int16_t ideal_delta = gState.t_indoor - gState.t_outdoor;
int16_t delta, stop_delta;
bool allow_temp_switch = false;
if (gState.real_direction == MOTOR_DIR_OUT) {
delta = gState.t_indoor - gState.t_exhaust;
// 100% factor = nadoraz
stop_delta = ((int32_t)ideal_delta
* (int32_t)(100 - gSettings.recup_factor)) / 100;
// Delta = IN - OUT
if (gState.valid_t_indoor && gState.valid_t_exhaust && gState.valid_t_outdoor) {
allow_temp_switch = true;
}
} else {
// IN
delta = gState.t_inflow - gState.t_outdoor;
// 100% factor = nadoraz
stop_delta = ((int32_t)ideal_delta
* (int32_t)(gSettings.recup_factor)) / 100;
// Delta = IN - OUT
if (gState.valid_t_intake && gState.valid_t_indoor && gState.valid_t_outdoor) {
allow_temp_switch = true;
}
}
if (allow_temp_switch) {
if (gSettings.summer_mode) {
if (ideal_delta < 0) {
// warmer outside, trying to keep cool in
if (delta >= stop_delta) {
do_switch = true;
}
}
// colder outside - no stopping (will run to max recup time)
} else {
if (ideal_delta > 0) {
// colder outside, trying to keep warmth in
if (delta <= stop_delta) {
do_switch = true;
}
}
// warmer outside - no stopping (will run to max recup time)
}
}
}
if (do_switch) {
// zmena smeru // zmena smeru
gState.run_time = 0; gState.run_time = 0;
act_motor_direction_set(1 - gAct.dir); act_motor_direction_set(1 - gAct.dir);
@ -132,25 +187,27 @@ static void timerCallback(TimerHandle_t xTimer) {
} }
if (end_temp_meas) { if (end_temp_meas) {
uint16_t t1 = (uint16_t) (gState.t1_aggr / gState.t_aggr_cnt); if (gState.t_aggr_cnt > 0) {
uint16_t t2 = (uint16_t) (gState.t2_aggr / gState.t_aggr_cnt); uint16_t t1 = (uint16_t) (gState.t1_aggr / gState.t_aggr_cnt);
switch (gState.real_direction) { uint16_t t2 = (uint16_t) (gState.t2_aggr / gState.t_aggr_cnt);
case MOTOR_DIR_IN: switch (gState.real_direction) {
gState.t_outdoor = t2; case MOTOR_DIR_IN:
gState.t_intake = t1; gState.t_outdoor = t2;
gState.valid_t_outdoor = gState.valid_t_intake = true; gState.t_inflow = t1;
if (gState.effective_vent_mode == VENT_MODE_IN) { gState.valid_t_outdoor = gState.valid_t_intake = true;
gState.valid_t_indoor = gState.valid_t_exhaust = false; if (gState.effective_vent_mode == VENT_MODE_IN) {
} gState.valid_t_indoor = gState.valid_t_exhaust = false;
break; }
case MOTOR_DIR_OUT: break;
gState.t_indoor = t1; case MOTOR_DIR_OUT:
gState.t_exhaust = t2; gState.t_indoor = t1;
gState.valid_t_indoor = gState.valid_t_exhaust = true; gState.t_exhaust = t2;
if (gState.effective_vent_mode == VENT_MODE_OUT) { gState.valid_t_indoor = gState.valid_t_exhaust = true;
gState.valid_t_outdoor = gState.valid_t_intake = false; if (gState.effective_vent_mode == VENT_MODE_OUT) {
} gState.valid_t_outdoor = gState.valid_t_intake = false;
break; }
break;
}
} }
gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0; gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0;
} }
@ -185,8 +242,10 @@ void fan_set_vent_mode(enum ventilation_mode mode) {
gState.set_vent_mode = mode; gState.set_vent_mode = mode;
gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0; gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0;
if (gState.set_power != 0) { if (gState.set_power != 0 || mode == VENT_MODE_FREE) {
gState.effective_vent_mode = mode; gState.effective_vent_mode = mode;
} else if (gState.set_power == 0) {
gState.effective_vent_mode = VENT_MODE_OFF;
} }
if (mode == VENT_MODE_OFF || mode == VENT_MODE_FREE) { if (mode == VENT_MODE_OFF || mode == VENT_MODE_FREE) {

@ -18,6 +18,15 @@ enum ventilation_mode {
VENT_MODE_RECUP = 7, VENT_MODE_RECUP = 7,
}; };
enum recup_mode {
/** stricly time based recuperation switching */
RECUP_MODE_TIME = 0,
/** Temperature-based recuperation switching
* (switch direction when further blowing won't save energy) */
RECUP_MODE_TEMP = 1,
};
struct FanControlState { struct FanControlState {
/** /**
* Power requested trough register or as the default value. * Power requested trough register or as the default value.
@ -39,13 +48,13 @@ struct FanControlState {
bool valid_t_actual_1; bool valid_t_actual_1;
bool valid_t_actual_2; bool valid_t_actual_2;
uint16_t t_indoor; int16_t t_indoor;
uint16_t t_outdoor; int16_t t_outdoor;
uint16_t t_intake; int16_t t_inflow;
uint16_t t_exhaust; int16_t t_exhaust;
uint16_t t_actual_1; int16_t t_actual_1;
uint16_t t_actual_2; int16_t t_actual_2;
// Private // Private
/** /**

@ -40,7 +40,10 @@ extern nvs_handle g_nvs_storage;
X(uint32_t , ap_ip , , 0x0100a8c0 , true , u32 , &) /* 192.168.0.1 */ \ X(uint32_t , ap_ip , , 0x0100a8c0 , true , u32 , &) /* 192.168.0.1 */ \
X(uint32_t , static_dns , , 0x08080808 , true , u32 , &) /* 8.8.8.8 */ \ X(uint32_t , static_dns , , 0x08080808 , true , u32 , &) /* 8.8.8.8 */ \
X(uint16_t , recup_mode , , 0 , true , u16 , &) /* recuperator control mode - 0=time, 1=min time+temp equilibrium */ \ X(uint16_t , recup_mode , , 0 , true , u16 , &) /* recuperator control mode - 0=time, 1=min time+temp equilibrium */ \
X(uint16_t , recup_time , , 60 , true , u16 , &) /* seconds */ \ X(uint16_t , recup_time , , 60 , true , u16 , &) /* seconds */ \
X(uint16_t , recup_factor , , 80 , true , u16 , &) /* perc */ \
X(uint16_t , min_recup_time , , 30 , true , u16 , &) /* seconds */ \
X(uint16_t , max_recup_time , , 120 , true , u16 , &) /* seconds */ \
X(uint16_t , ramp_time , , 3 , true , u16 , &) /* cas rozjezdu nebo zastaveni motoru (s) */ \ X(uint16_t , ramp_time , , 3 , true , u16 , &) /* cas rozjezdu nebo zastaveni motoru (s) */ \
X(uint16_t , blind_time , , 30 , true , u16 , &) /* cas otevreni nebo zavreni rolety (s) */ \ X(uint16_t , blind_time , , 30 , true , u16 , &) /* cas otevreni nebo zavreni rolety (s) */ \
X(uint16_t , initial_mode , , 0 , true , u16 , &) /* rezim po zapnuti napajeni */ \ X(uint16_t , initial_mode , , 0 , true , u16 , &) /* rezim po zapnuti napajeni */ \

Loading…
Cancel
Save