new logic for temp based mode

fix-tempmode
Ondřej Hruška 2 years ago
parent 01b94ff604
commit afafc0172e
  1. 4
      main/actuators.c
  2. 1
      main/actuators.h
  3. 77
      main/fancontrol.c
  4. 1
      main/fancontrol.h
  5. 81
      main/mbiface.c
  6. 2
      main/onewires.c
  7. 1
      main/onewires.h
  8. 2
      main/settings.c
  9. 10
      main/settings.h

@ -154,3 +154,7 @@ cels_t act_temp2()
{ {
return gTempSensors[1]; return gTempSensors[1];
} }
uint16_t act_temps_serial() {
return gTempsSerial;
}

@ -32,5 +32,6 @@ void act_statusled_set(bool on);
cels_t act_temp1(); cels_t act_temp1();
cels_t act_temp2(); cels_t act_temp2();
uint16_t act_temps_serial();
#endif //FANCTL_ACTUATORS_H #endif //FANCTL_ACTUATORS_H

@ -20,6 +20,8 @@ static void timerCallback();
static void invalidate_temps(); static void invalidate_temps();
static float absf(float f);
void settings_blind_time_set(uint16_t blind_time) void settings_blind_time_set(uint16_t blind_time)
{ {
// if the blind is surely at the end // if the blind is surely at the end
@ -92,6 +94,18 @@ static const char * vent_mode_labels[] = {
static void timerCallback() static void timerCallback()
{ {
// Measure temperatures
cels_t tin = act_temp1();
cels_t tout = act_temp2();
float old_tin = gState.t_actual_in;
float old_tout = gState.t_actual_out;
gState.t_actual_in = tin;
gState.t_actual_out = tout;
gState.valid_t_actual_in = gState.valid_t_actual_out = tempSensorsOk;
// posun rolety // posun rolety
if (gAct.blind) { if (gAct.blind) {
if (gState.blind_position < gSettings.blind_time) { if (gState.blind_position < gSettings.blind_time) {
@ -167,14 +181,55 @@ static void timerCallback()
// Stop condition // Stop condition
bool do_switch = false; bool do_switch = false;
// vyfukovaci strana trubice, libovona strana
if (gState.real_direction == MOTOR_DIR_IN) {
if (gState.t_actual_in <= gSettings.t_in_min || gState.t_actual_in >= gSettings.t_in_max) {
ESP_LOGW(TAG, "Temp limit reached, change dir!");
do_switch = true;
}
}
float t_output = gState.real_direction == MOTOR_DIR_OUT ? gState.t_actual_out : gState.t_actual_in;
float t_input = gState.real_direction == MOTOR_DIR_IN ? gState.t_actual_out : gState.t_actual_in;
float delta = absf(t_input - t_output);
if (gState.real_direction == MOTOR_DIR_IN) {
if (delta < gSettings.t_stopdelta_in) {
ESP_LOGW(TAG, "IN stop delta reached, change dir!");
do_switch = true;
}
} else {
if (delta < gSettings.t_stopdelta_out) {
ESP_LOGW(TAG, "OUT stop delta reached, change dir!");
do_switch = true;
}
}
if (gSettings.recup_mode == RECUP_MODE_TIME) { if (gSettings.recup_mode == RECUP_MODE_TIME) {
do_switch = gState.run_time >= gSettings.recup_time; if (gState.run_time >= gSettings.recup_time) {
ESP_LOGW(TAG, "Recup time elapsed, change dir!");
do_switch = true;
}
} else { } else {
if (gState.run_time >= gSettings.max_recup_time) { if (gState.run_time >= gSettings.max_recup_time) {
ESP_LOGW(TAG, "Max time elapsed, change dir!");
// Max time elapsed, switch even if the condition was not reached // Max time elapsed, switch even if the condition was not reached
do_switch = true; do_switch = true;
} else { } else {
// TODO if (gState.lastTempsSerial != act_temps_serial()) {
// expecting some change in temps
float speed;
if (gState.real_direction == MOTOR_DIR_IN) {
speed = absf(tin - old_tin);
} else {
speed = absf(tout - old_tout);
}
if (speed < gSettings.t_stop_speed) {
ESP_LOGW(TAG, "Near-equilibrium reached, change dir!");
do_switch = true;
}
}
} }
} }
@ -205,15 +260,6 @@ static void timerCallback()
gState.instantaneous_vent_mode = gState.effective_vent_mode; gState.instantaneous_vent_mode = gState.effective_vent_mode;
} }
// Measure temperatures
cels_t t1 = act_temp1();
cels_t t2 = act_temp2();
gState.t_actual_in = t1;
gState.t_actual_out = t2;
gState.valid_t_actual_in = gState.valid_t_actual_out = tempSensorsOk;
if (end_temp_meas) { if (end_temp_meas) {
switch (gState.real_direction) { switch (gState.real_direction) {
case MOTOR_DIR_IN: case MOTOR_DIR_IN:
@ -251,6 +297,15 @@ static void timerCallback()
); );
} }
static float absf(float f)
{
if (f < 0) {
return -f;
} else {
return f;
}
}
void fan_set_vent_mode(enum ventilation_mode mode) void fan_set_vent_mode(enum ventilation_mode mode)
{ {
ESP_LOGI(TAG, "Set vent mode = %s", vent_mode_labels[mode]); ESP_LOGI(TAG, "Set vent mode = %s", vent_mode_labels[mode]);

@ -54,6 +54,7 @@ struct FanControlState {
cels_t t_inflow; cels_t t_inflow;
cels_t t_exhaust; cels_t t_exhaust;
uint16_t lastTempsSerial;
cels_t t_actual_in; cels_t t_actual_in;
cels_t t_actual_out; cels_t t_actual_out;

@ -30,8 +30,13 @@ enum HoldingRegisters {
H_RECUP_TIME = 13, H_RECUP_TIME = 13,
H_RECUP_TIME_MIN = 14, H_RECUP_TIME_MIN = 14,
H_RECUP_TIME_MAX = 15, H_RECUP_TIME_MAX = 15,
H_RECUP_FACTOR = 16, // H_RECUP_FACTOR = 16,
H_MIN_POWER = 17, H_MIN_POWER = 17,
H_T_IN_MIN = 18,
H_T_IN_MAX = 19,
H_T_STOPDELTA_IN = 20,
H_T_STOPDELTA_OUT = 21,
H_T_STOP_SPEED = 22,
// Hardware settings (don't need to change once set correctly) // Hardware settings (don't need to change once set correctly)
H_RAMP_TIME = 30, H_RAMP_TIME = 30,
@ -98,7 +103,13 @@ void endOfAccess(ModbusSlave_t *ms) {
// //
} }
#define cels2reg(cels) ((uint16_t) roundf((cels) * 100)) union ui16 {
uint16_t u;
uint16_t i;
};
#define cels2reg(cels) (((union ui16) { .i = ((int16_t) roundf((cels) * 100.0f)) }).u)
#define reg2cels(regv) (((float) ((union ui16) { .u = (regv) }).i) / 100.0f)
ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
ESP_LOGD(TAG, "Read input %d", ref); ESP_LOGD(TAG, "Read input %d", ref);
@ -211,9 +222,26 @@ ModbusException_t rh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
case H_RECUP_TIME_MAX: case H_RECUP_TIME_MAX:
*pValue = gSettings.max_recup_time; *pValue = gSettings.max_recup_time;
break; break;
case H_RECUP_FACTOR: // case H_RECUP_FACTOR:
*pValue = gSettings.recup_factor; // *pValue = gSettings.recup_factor;
// break;
case H_T_IN_MIN:
*pValue = cels2reg(gSettings.t_in_min);
break;
case H_T_IN_MAX:
*pValue = cels2reg(gSettings.t_in_max);
break;
case H_T_STOPDELTA_IN:
*pValue = cels2reg(gSettings.t_stopdelta_in);
break; break;
case H_T_STOPDELTA_OUT:
*pValue = cels2reg(gSettings.t_stopdelta_out);
break;
case H_T_STOP_SPEED:
*pValue = cels2reg(gSettings.t_stop_speed);
break;
case H_RAMP_TIME: case H_RAMP_TIME:
*pValue = gSettings.ramp_time; *pValue = gSettings.ramp_time;
break; break;
@ -257,6 +285,7 @@ static bool is_valid_vent_mode(int value) {
ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) { ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) {
ESP_LOGD(TAG, "Write holding %d := %02x", ref, value); ESP_LOGD(TAG, "Write holding %d := %02x", ref, value);
float f;
switch (ref) { switch (ref) {
case H_MODE: case H_MODE:
@ -317,13 +346,49 @@ ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) {
gSettings.max_recup_time = value; gSettings.max_recup_time = value;
settings_persist(SETTINGS_max_recup_time); settings_persist(SETTINGS_max_recup_time);
break; break;
case H_RECUP_FACTOR: // case H_RECUP_FACTOR:
if (value > 100) { // if (value > 100) {
// return MB_EXCEPTION_ILLEGAL_DATA_VALUE;
// }
// gSettings.recup_factor = value;
// settings_persist(SETTINGS_recup_factor);
// break;
case H_T_IN_MIN:
f = reg2cels(value);
gSettings.t_in_min = f;
settings_persist(SETTINGS_t_in_min);
break;
case H_T_IN_MAX:
f = reg2cels(value);
gSettings.t_in_max = f;
settings_persist(SETTINGS_t_in_max);
break;
case H_T_STOPDELTA_IN:
f = reg2cels(value);
if (f < 0) {
return MB_EXCEPTION_ILLEGAL_DATA_VALUE;
}
gSettings.t_stopdelta_in = f;
settings_persist(SETTINGS_t_stopdelta_in);
break;
case H_T_STOPDELTA_OUT:
f = reg2cels(value);
if (f < 0) {
return MB_EXCEPTION_ILLEGAL_DATA_VALUE; return MB_EXCEPTION_ILLEGAL_DATA_VALUE;
} }
gSettings.recup_factor = value; gSettings.t_stopdelta_out = f;
settings_persist(SETTINGS_recup_factor); settings_persist(SETTINGS_t_stopdelta_out);
break; break;
case H_T_STOP_SPEED:
f = reg2cels(value);
if (f < 0) {
return MB_EXCEPTION_ILLEGAL_DATA_VALUE;
}
gSettings.t_stop_speed = f;
settings_persist(SETTINGS_t_stop_speed);
break;
case H_RAMP_TIME: case H_RAMP_TIME:
gSettings.ramp_time = value; gSettings.ramp_time = value;
settings_persist(SETTINGS_ramp_time); settings_persist(SETTINGS_ramp_time);

@ -17,6 +17,7 @@ static DS18B20_Info *sDevs[2] = {};
volatile float gTempSensors[2] = {}; volatile float gTempSensors[2] = {};
volatile bool tempSensorsOk = false; volatile bool tempSensorsOk = false;
volatile uint16_t gTempsSerial = 0;
static void owtask(void *dummy) { static void owtask(void *dummy) {
while (1) { while (1) {
@ -26,6 +27,7 @@ static void owtask(void *dummy) {
gTempSensors[0] = a; gTempSensors[0] = a;
gTempSensors[1] = b; gTempSensors[1] = b;
gTempsSerial++;
ESP_LOGI(TAG, "t1 %.2f, t2 %.2f C", a, b); ESP_LOGI(TAG, "t1 %.2f, t2 %.2f C", a, b);
} }
} }

@ -14,5 +14,6 @@ int read_onewires(cels_t *a, cels_t *b);
extern volatile cels_t gTempSensors[2]; extern volatile cels_t gTempSensors[2];
extern volatile bool tempSensorsOk; extern volatile bool tempSensorsOk;
extern volatile uint16_t gTempsSerial;
#endif //ONEWIRES_H #endif //ONEWIRES_H

@ -37,7 +37,6 @@ union fu {
uint32_t u; uint32_t u;
}; };
#if 0
/** Read float from NVS. See `nvs_get_u32` for more info. */ /** Read float from NVS. See `nvs_get_u32` for more info. */
static esp_err_t nvs_get_f32 (nvs_handle_t handle, const char* key, float* out_value) { static esp_err_t nvs_get_f32 (nvs_handle_t handle, const char* key, float* out_value) {
uint32_t u = 0; uint32_t u = 0;
@ -61,7 +60,6 @@ static esp_err_t nvs_set_f32 (nvs_handle_t handle, const char* key, float value)
}; };
return nvs_set_u32(handle, key, reinterpret.u); return nvs_set_u32(handle, key, reinterpret.u);
} }
#endif
/** Dummy read from NVS; placeholder for XTABLE entries with manually implemented getters */ /** Dummy read from NVS; placeholder for XTABLE entries with manually implemented getters */
static esp_err_t nvs_get_none(nvs_handle handle, const char* key, void* out_value) { static esp_err_t nvs_get_none(nvs_handle handle, const char* key, void* out_value) {

@ -41,7 +41,6 @@ extern nvs_handle g_nvs_storage;
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 , min_recup_time , , 30 , true , u16 , &) /* seconds */ \
X(uint16_t , max_recup_time , , 180 , true , u16 , &) /* seconds */ \ X(uint16_t , max_recup_time , , 180 , true , u16 , &) /* seconds */ \
X(uint16_t , ramp_time , , 6 , true , u16 , &) /* cas rozjezdu nebo zastaveni motoru (s) */ \ X(uint16_t , ramp_time , , 6 , true , u16 , &) /* cas rozjezdu nebo zastaveni motoru (s) */ \
@ -51,7 +50,14 @@ extern nvs_handle g_nvs_storage;
X(uint16_t , min_power , , 5 , true , u16 , &) /* min power % */ \ X(uint16_t , min_power , , 5 , true , u16 , &) /* min power % */ \
X(bool , summer_mode , , 0 , true , bool , &) /* rezim po zapnuti napajeni */ \ X(bool , summer_mode , , 0 , true , bool , &) /* rezim po zapnuti napajeni */ \
X(bool , swap_temps , , 0 , true , bool , &) /* swap t0/t1 */ \ X(bool , swap_temps , , 0 , true , bool , &) /* swap t0/t1 */ \
X(bool , swap_pwm_dir , , 0 , true , bool , &) /* swap pwm/dir signal */ X(bool , swap_pwm_dir , , 0 , true , bool , &) /* swap pwm/dir signal */ \
X(float , t_in_min , , 10 , true , f32 , &) /* minimalni teplota do mistnosti */ \
X(float , t_in_max , , 27 , true , f32 , &) /* maximalni teplota do mistnosti */ \
X(float , t_stopdelta_in , , 3 , true , f32 , &) /* delta when recuperation stops in IN mode */ \
X(float , t_stopdelta_out , , 1 , true , f32 , &) /* delta when recuperation stops in OUT mode */ \
X(float , t_stop_speed , , 0.025 , true , f32 , &) /* zastav rekuperaci, pokud zmena teploty na vystupni strane roste/klesa pomaleji nez X/sec */
// X(uint16_t , recup_factor , , 80 , true , u16 , &) /* perc */
enum settings_key_enum { enum settings_key_enum {
#undef X #undef X

Loading…
Cancel
Save