|
|
@ -8,9 +8,11 @@ |
|
|
|
#include "settings.h" |
|
|
|
#include "settings.h" |
|
|
|
#include "actuators.h" |
|
|
|
#include "actuators.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define UNIDIR_T_MEAS_PERIOD 15 /* s */ |
|
|
|
struct FanControlState gState = {}; |
|
|
|
struct FanControlState gState = {}; |
|
|
|
|
|
|
|
|
|
|
|
static void timerCallback(TimerHandle_t xTimer); |
|
|
|
static void timerCallback(TimerHandle_t xTimer); |
|
|
|
|
|
|
|
static void invalidate_temps(); |
|
|
|
|
|
|
|
|
|
|
|
void settings_blind_time_set(uint16_t blind_time) { |
|
|
|
void settings_blind_time_set(uint16_t blind_time) { |
|
|
|
bool nadoraz = (gState.blind_position >= gSettings.blind_time) || (gState.blind_position >= blind_time); |
|
|
|
bool nadoraz = (gState.blind_position >= gSettings.blind_time) || (gState.blind_position >= blind_time); |
|
|
@ -25,7 +27,7 @@ void settings_blind_time_set(uint16_t blind_time) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void fancontrol_init() { |
|
|
|
void fancontrol_init() { |
|
|
|
gState.vent_mode = gSettings.initial_mode; |
|
|
|
gState.set_vent_mode = gSettings.initial_mode; |
|
|
|
gState.set_power = gSettings.initial_power; |
|
|
|
gState.set_power = gSettings.initial_power; |
|
|
|
|
|
|
|
|
|
|
|
xTimerCreate("fanctl", |
|
|
|
xTimerCreate("fanctl", |
|
|
@ -69,7 +71,9 @@ static void timerCallback(TimerHandle_t xTimer) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (gState.vent_mode) { |
|
|
|
bool end_temp_meas = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (gState.effective_vent_mode) { |
|
|
|
case VENT_MODE_OFF: |
|
|
|
case VENT_MODE_OFF: |
|
|
|
act_motor_power_set(0); |
|
|
|
act_motor_power_set(0); |
|
|
|
act_blind_set(0); |
|
|
|
act_blind_set(0); |
|
|
@ -84,6 +88,9 @@ 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); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (gState.t_aggr_cnt > UNIDIR_T_MEAS_PERIOD) { |
|
|
|
|
|
|
|
end_temp_meas = true; |
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case VENT_MODE_IN: |
|
|
|
case VENT_MODE_IN: |
|
|
|
act_motor_direction_set(MOTOR_DIR_IN); |
|
|
|
act_motor_direction_set(MOTOR_DIR_IN); |
|
|
@ -91,6 +98,9 @@ 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); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (gState.t_aggr_cnt > UNIDIR_T_MEAS_PERIOD) { |
|
|
|
|
|
|
|
end_temp_meas = true; |
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case VENT_MODE_RECUP: |
|
|
|
case VENT_MODE_RECUP: |
|
|
|
act_blind_set(1); |
|
|
|
act_blind_set(1); |
|
|
@ -103,6 +113,7 @@ static void timerCallback(TimerHandle_t xTimer) { |
|
|
|
// 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); |
|
|
|
|
|
|
|
end_temp_meas = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -110,23 +121,94 @@ static void timerCallback(TimerHandle_t xTimer) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (gAct.dir == gState.real_direction && gState.ramp >= gSettings.ramp_time) { |
|
|
|
if (gState.effective_vent_mode == VENT_MODE_RECUP) { |
|
|
|
// Measure temperatures
|
|
|
|
if (gState.real_direction == MOTOR_DIR_OUT) { |
|
|
|
int16_t t1 = 200; |
|
|
|
gState.instantaneous_vent_mode = VENT_MODE_OUT; |
|
|
|
int16_t t2 = 200; // TODO
|
|
|
|
} else { |
|
|
|
|
|
|
|
gState.instantaneous_vent_mode = VENT_MODE_IN; |
|
|
|
gState.t_actual_1 = t1; |
|
|
|
} |
|
|
|
gState.t_actual_2 = t2; |
|
|
|
} else { |
|
|
|
|
|
|
|
gState.instantaneous_vent_mode = gState.effective_vent_mode; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (end_temp_meas) { |
|
|
|
|
|
|
|
uint16_t t1 = (uint16_t) (gState.t1_aggr / gState.t_aggr_cnt); |
|
|
|
|
|
|
|
uint16_t t2 = (uint16_t) (gState.t2_aggr / gState.t_aggr_cnt); |
|
|
|
switch (gState.real_direction) { |
|
|
|
switch (gState.real_direction) { |
|
|
|
case MOTOR_DIR_IN: |
|
|
|
case MOTOR_DIR_IN: |
|
|
|
gState.t_outdoor = t2; |
|
|
|
gState.t_outdoor = t2; |
|
|
|
gState.t_intake = t1; |
|
|
|
gState.t_intake = t1; |
|
|
|
|
|
|
|
gState.valid_t_outdoor = gState.valid_t_intake = true; |
|
|
|
|
|
|
|
if (gState.effective_vent_mode == VENT_MODE_IN) { |
|
|
|
|
|
|
|
gState.valid_t_indoor = gState.valid_t_exhaust = false; |
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case MOTOR_DIR_OUT: |
|
|
|
case MOTOR_DIR_OUT: |
|
|
|
gState.t_indoor = t1; |
|
|
|
gState.t_indoor = t1; |
|
|
|
gState.t_exhaust = t2; |
|
|
|
gState.t_exhaust = t2; |
|
|
|
|
|
|
|
gState.valid_t_indoor = gState.valid_t_exhaust = true; |
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (gState.effective_vent_mode == VENT_MODE_IN |
|
|
|
|
|
|
|
|| gState.effective_vent_mode == VENT_MODE_OUT |
|
|
|
|
|
|
|
|| gState.effective_vent_mode == VENT_MODE_RECUP) { |
|
|
|
|
|
|
|
// Measure temperatures
|
|
|
|
|
|
|
|
int16_t t1 = 200; |
|
|
|
|
|
|
|
int16_t t2 = 190; // TODO
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gState.t_actual_1 = t1; |
|
|
|
|
|
|
|
gState.t_actual_2 = t2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gState.valid_t_actual_1 = gState.valid_t_actual_2 = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (gAct.dir == gState.real_direction |
|
|
|
|
|
|
|
&& gState.ramp >= gSettings.ramp_time) { |
|
|
|
|
|
|
|
gState.t1_aggr += t1; |
|
|
|
|
|
|
|
gState.t2_aggr += t2; |
|
|
|
|
|
|
|
gState.t_aggr_cnt++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
gState.valid_t_actual_1 = gState.valid_t_actual_2 = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void fan_set_vent_mode(enum ventilation_mode mode) { |
|
|
|
|
|
|
|
if (mode == gState.set_vent_mode) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gState.set_vent_mode = mode; |
|
|
|
|
|
|
|
gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0; |
|
|
|
|
|
|
|
if (gState.set_power != 0) { |
|
|
|
|
|
|
|
gState.effective_vent_mode = mode; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mode == VENT_MODE_OFF || mode == VENT_MODE_FREE) { |
|
|
|
|
|
|
|
invalidate_temps(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void invalidate_temps() { |
|
|
|
|
|
|
|
gState.valid_t_indoor = false; |
|
|
|
|
|
|
|
gState.valid_t_outdoor = false; |
|
|
|
|
|
|
|
gState.valid_t_intake = false; |
|
|
|
|
|
|
|
gState.valid_t_exhaust = false; |
|
|
|
|
|
|
|
gState.valid_t_actual_1 = false; |
|
|
|
|
|
|
|
gState.valid_t_actual_2 = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void fan_set_power(uint16_t power) { |
|
|
|
|
|
|
|
gState.set_power = power; |
|
|
|
|
|
|
|
if (power == 0) { |
|
|
|
|
|
|
|
gState.effective_vent_mode = VENT_MODE_OFF; |
|
|
|
|
|
|
|
invalidate_temps(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
gState.effective_vent_mode = gState.set_vent_mode; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |