forked from electro/esp-irblaster
new logic for temp based mode
This commit is contained in:
@@ -154,3 +154,7 @@ cels_t act_temp2()
|
||||
{
|
||||
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_temp2();
|
||||
uint16_t act_temps_serial();
|
||||
|
||||
#endif //FANCTL_ACTUATORS_H
|
||||
|
||||
+66
-11
@@ -20,6 +20,8 @@ static void timerCallback();
|
||||
|
||||
static void invalidate_temps();
|
||||
|
||||
static float absf(float f);
|
||||
|
||||
void settings_blind_time_set(uint16_t blind_time)
|
||||
{
|
||||
// if the blind is surely at the end
|
||||
@@ -92,6 +94,18 @@ static const char * vent_mode_labels[] = {
|
||||
|
||||
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
|
||||
if (gAct.blind) {
|
||||
if (gState.blind_position < gSettings.blind_time) {
|
||||
@@ -167,14 +181,55 @@ static void timerCallback()
|
||||
// Stop condition
|
||||
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) {
|
||||
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 {
|
||||
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
|
||||
do_switch = true;
|
||||
} 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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
switch (gState.real_direction) {
|
||||
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)
|
||||
{
|
||||
ESP_LOGI(TAG, "Set vent mode = %s", vent_mode_labels[mode]);
|
||||
|
||||
@@ -54,6 +54,7 @@ struct FanControlState {
|
||||
cels_t t_inflow;
|
||||
cels_t t_exhaust;
|
||||
|
||||
uint16_t lastTempsSerial;
|
||||
cels_t t_actual_in;
|
||||
cels_t t_actual_out;
|
||||
|
||||
|
||||
+73
-8
@@ -30,8 +30,13 @@ enum HoldingRegisters {
|
||||
H_RECUP_TIME = 13,
|
||||
H_RECUP_TIME_MIN = 14,
|
||||
H_RECUP_TIME_MAX = 15,
|
||||
H_RECUP_FACTOR = 16,
|
||||
// H_RECUP_FACTOR = 16,
|
||||
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)
|
||||
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) {
|
||||
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:
|
||||
*pValue = gSettings.max_recup_time;
|
||||
break;
|
||||
case H_RECUP_FACTOR:
|
||||
*pValue = gSettings.recup_factor;
|
||||
// case H_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;
|
||||
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:
|
||||
*pValue = gSettings.ramp_time;
|
||||
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) {
|
||||
ESP_LOGD(TAG, "Write holding %d := %02x", ref, value);
|
||||
float f;
|
||||
|
||||
switch (ref) {
|
||||
case H_MODE:
|
||||
@@ -317,13 +346,49 @@ ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) {
|
||||
gSettings.max_recup_time = value;
|
||||
settings_persist(SETTINGS_max_recup_time);
|
||||
break;
|
||||
case H_RECUP_FACTOR:
|
||||
if (value > 100) {
|
||||
// case H_RECUP_FACTOR:
|
||||
// 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.recup_factor = value;
|
||||
settings_persist(SETTINGS_recup_factor);
|
||||
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;
|
||||
}
|
||||
gSettings.t_stopdelta_out = f;
|
||||
settings_persist(SETTINGS_t_stopdelta_out);
|
||||
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:
|
||||
gSettings.ramp_time = value;
|
||||
settings_persist(SETTINGS_ramp_time);
|
||||
|
||||
@@ -17,6 +17,7 @@ static DS18B20_Info *sDevs[2] = {};
|
||||
|
||||
volatile float gTempSensors[2] = {};
|
||||
volatile bool tempSensorsOk = false;
|
||||
volatile uint16_t gTempsSerial = 0;
|
||||
|
||||
static void owtask(void *dummy) {
|
||||
while (1) {
|
||||
@@ -26,6 +27,7 @@ static void owtask(void *dummy) {
|
||||
|
||||
gTempSensors[0] = a;
|
||||
gTempSensors[1] = b;
|
||||
gTempsSerial++;
|
||||
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 bool tempSensorsOk;
|
||||
extern volatile uint16_t gTempsSerial;
|
||||
|
||||
#endif //ONEWIRES_H
|
||||
|
||||
@@ -37,7 +37,6 @@ union fu {
|
||||
uint32_t u;
|
||||
};
|
||||
|
||||
#if 0
|
||||
/** 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) {
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** 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) {
|
||||
|
||||
+8
-2
@@ -41,7 +41,6 @@ extern nvs_handle g_nvs_storage;
|
||||
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_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 , , 180 , true , u16 , &) /* seconds */ \
|
||||
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(bool , summer_mode , , 0 , true , bool , &) /* rezim po zapnuti napajeni */ \
|
||||
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 {
|
||||
#undef X
|
||||
|
||||
Reference in New Issue
Block a user