diff --git a/main/actuators.c b/main/actuators.c index bcdc71d..184f3e4 100644 --- a/main/actuators.c +++ b/main/actuators.c @@ -145,12 +145,12 @@ void act_init() led_init(); } -int16_t act_temp1() +cels_t act_temp1() { return gTempSensors[0]; } -int16_t act_temp2() +cels_t act_temp2() { return gTempSensors[1]; } diff --git a/main/actuators.h b/main/actuators.h index 2096aa6..abebf97 100644 --- a/main/actuators.h +++ b/main/actuators.h @@ -7,6 +7,7 @@ #include #include +#include "recup_types.h" enum motor_direction { MOTOR_DIR_IN = 0, @@ -17,19 +18,19 @@ struct actuators_status { enum motor_direction dir; bool blind; bool led; - uint16_t power; + perc_t power; }; extern struct actuators_status gAct; void act_init(); -void act_motor_power_set(uint16_t perc); +void act_motor_power_set(perc_t perc); void act_motor_direction_set(enum motor_direction dir); void act_blind_set(bool open); void act_led_set(bool on); void act_statusled_set(bool on); -int16_t act_temp1(); -int16_t act_temp2(); +cels_t act_temp1(); +cels_t act_temp2(); #endif //FANCTL_ACTUATORS_H diff --git a/main/fancontrol.c b/main/fancontrol.c index ec86ba7..54bd839 100644 --- a/main/fancontrol.c +++ b/main/fancontrol.c @@ -13,7 +13,7 @@ const char *TAG = "fc"; -#define UNIDIR_T_MEAS_PERIOD 15 /* s */ +#define UNIDIR_T_MEAS_PERIOD 60 struct FanControlState gState = {}; static void timerCallback(); @@ -85,10 +85,10 @@ static const char * vent_mode_labels[] = { [VENT_MODE_RECUP] = "RECUP", }; -static const char * recup_mode_labels[] = { - [RECUP_MODE_TIME] = "TIME", - [RECUP_MODE_TEMP] = "TEMP", -}; +//static const char * recup_mode_labels[] = { +// [RECUP_MODE_TIME] = "TIME", +// [RECUP_MODE_TEMP] = "TEMP", +//}; static void timerCallback() { @@ -115,7 +115,9 @@ static void timerCallback() gState.ramp++; } } - gState.run_time++; + if (gState.run_time < 0xFFFF) { + gState.run_time++; + } } else { if (gState.ramp > 0) { gState.ramp--; @@ -141,7 +143,8 @@ static void timerCallback() if (gState.blind_position >= gSettings.blind_time) { act_motor_power_set(gState.set_power); } - if (gState.ramp >= gSettings.ramp_time * 2) { + // some time is needed before the temperature means anything + if (gState.run_time >= UNIDIR_T_MEAS_PERIOD) { end_temp_meas = true; } break; @@ -151,7 +154,7 @@ static void timerCallback() if (gState.blind_position >= gSettings.blind_time) { act_motor_power_set(gState.set_power); } - if (gState.ramp >= gSettings.ramp_time * 2) { + if (gState.run_time >= UNIDIR_T_MEAS_PERIOD) { end_temp_meas = true; } break; @@ -164,54 +167,14 @@ static void timerCallback() // Stop condition 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) - // Delta = IN - OUT - const int16_t ideal_delta = gState.t_indoor - gState.t_outdoor; - int16_t stop_delta = ((int32_t) ideal_delta - * (int32_t) (100 - gSettings.recup_factor)) / 100; - int16_t delta = 0; - bool allow_temp_switch = false; - - if (gState.real_direction == MOTOR_DIR_OUT) { - if (gState.valid_t_indoor && gState.valid_t_exhaust && gState.valid_t_outdoor) { - delta = gState.t_indoor - gState.t_exhaust; - allow_temp_switch = true; - } + if (gState.run_time >= gSettings.max_recup_time) { + // Max time elapsed, switch even if the condition was not reached + do_switch = true; } else { - // IN - if (gState.valid_t_inflow && gState.valid_t_indoor && gState.valid_t_outdoor) { - delta = gState.t_inflow - gState.t_outdoor; - allow_temp_switch = true; - } - } - - ESP_LOGI(TAG, "Delta now %d, max %d, stop %d (RF %d%%), allow_switch %d Cx10", delta, ideal_delta, stop_delta, gSettings.recup_factor, allow_temp_switch); - - 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) - } + // TODO } } @@ -243,8 +206,8 @@ static void timerCallback() } // Measure temperatures - int16_t t1 = act_temp1(); - int16_t t2 = act_temp2(); + cels_t t1 = act_temp1(); + cels_t t2 = act_temp2(); gState.t_actual_in = t1; gState.t_actual_out = t2; @@ -273,29 +236,24 @@ static void timerCallback() } ESP_LOGI(TAG, - "%s (ef %s, inst %s), rt %ds %d%%m, Tid %d%s, Tod %d%s, Tit %d%s, Teh %d%s, T1 %d%s, T2 %d%s Cx10", - vent_mode_labels[gState.set_vent_mode], vent_mode_labels[gState.effective_vent_mode], vent_mode_labels[gState.instantaneous_vent_mode], + "%s (%s), B%ds, M%ds, %d%%, Tid %.2f%s, Tod %.2f%s, Tit %.2f%s, Teh %.2f%s, T1 %.2f%s, T2 %.2f%s C", + vent_mode_labels[gState.set_vent_mode], vent_mode_labels[gState.instantaneous_vent_mode], + gState.blind_position, gState.run_time, gAct.power, - gState.t_indoor, - gState.valid_t_indoor ? "" : "!", - gState.t_outdoor, - gState.valid_t_outdoor ? "" : "!", - gState.t_inflow, - gState.valid_t_inflow ? "" : "!", - gState.t_exhaust, - gState.valid_t_exhaust ? "" : "!", - gState.t_actual_in, - gState.valid_t_actual_in ? "" : "!", - gState.t_actual_out, - gState.valid_t_actual_out ? "" : "!" + gState.t_indoor, gState.valid_t_indoor ? "" : "!", + gState.t_outdoor, gState.valid_t_outdoor ? "" : "!", + gState.t_inflow, gState.valid_t_inflow ? "" : "!", + gState.t_exhaust, gState.valid_t_exhaust ? "" : "!", + gState.t_actual_in, gState.valid_t_actual_in ? "" : "!", + gState.t_actual_out, gState.valid_t_actual_out ? "" : "!" ); } void fan_set_vent_mode(enum ventilation_mode mode) { - ESP_LOGI(TAG, "Set vent mode = %d", mode); + ESP_LOGI(TAG, "Set vent mode = %s", vent_mode_labels[mode]); if (mode == gState.set_vent_mode) { return; @@ -323,7 +281,7 @@ static void invalidate_temps() gState.valid_t_actual_out = false; } -void fan_set_power(uint16_t power) +void fan_set_power(perc_t power) { ESP_LOGI(TAG, "Set power = %d%%", power); diff --git a/main/fancontrol.h b/main/fancontrol.h index a488a6d..2b398d6 100644 --- a/main/fancontrol.h +++ b/main/fancontrol.h @@ -33,7 +33,7 @@ struct FanControlState { * Power requested trough register or as the default value. * This value stays unchanged even if stopped, unlike gAct.power which reflects the actual output. */ - uint16_t set_power; + perc_t set_power; /** * rezim ventilace. Use fan_set_vent_mode() to change it! */ @@ -49,16 +49,16 @@ struct FanControlState { bool valid_t_actual_in; bool valid_t_actual_out; - int16_t t_indoor; - int16_t t_outdoor; - int16_t t_inflow; - int16_t t_exhaust; + cels_t t_indoor; + cels_t t_outdoor; + cels_t t_inflow; + cels_t t_exhaust; - int16_t t_actual_in; - int16_t t_actual_out; + cels_t t_actual_in; + cels_t t_actual_out; - uint16_t real_recup_time_in; - uint16_t real_recup_time_out; + secs_t real_recup_time_in; + secs_t real_recup_time_out; // Private /** @@ -73,27 +73,27 @@ struct FanControlState { * Poloha roletky, 0<->blind_time, inkrement/dekrement 1 za sekundu. * Pri zmene blind_time se musi hodnota aktualizovat, pokud je na doraze nebo za. */ - uint16_t blind_position; + secs_t blind_position; /** * Cas chodu motoru v aktualnim smeru, inkrement 1 za sekundu. */ - uint16_t run_time; + secs_t run_time; /** * "stav chodu motoru". 0=stop, ramp_time = jede. */ - uint16_t ramp; + secs_t ramp; // helper counters that increment hour counters when overflow - uint16_t uptime_secs; - uint16_t motor_secs; + secs_t uptime_secs; + hours_t motor_secs; - uint16_t uptime_hours; - uint16_t motor_hours; + secs_t uptime_hours; + hours_t motor_hours; }; extern struct FanControlState gState; void fan_set_vent_mode(enum ventilation_mode mode); -void fan_set_power(uint16_t power); +void fan_set_power(perc_t power); #endif //FANCTL_FANCONTROL_H diff --git a/main/mbiface.c b/main/mbiface.c index a020872..0fcb261 100644 --- a/main/mbiface.c +++ b/main/mbiface.c @@ -1,4 +1,5 @@ #include +#include #include "mbiface.h" #include "socket_server.h" #include "tasks.h" @@ -97,6 +98,8 @@ void endOfAccess(ModbusSlave_t *ms) { // } +#define cels2reg(cels) ((uint16_t) roundf((cels) * 100)) + ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { ESP_LOGD(TAG, "Read input %d", ref); uint16_t scratch16 = 0; @@ -119,22 +122,22 @@ ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { *pValue = scratch16; break; case I_T_IN_INST: - *pValue = gState.t_actual_in; + *pValue = cels2reg(gState.t_actual_in); break; case I_T_OUT_INST: - *pValue = gState.t_actual_out; + *pValue = cels2reg(gState.t_actual_out); break; case I_T_INDOOR: - *pValue = gState.t_indoor; + *pValue = cels2reg(gState.t_indoor); break; case I_T_OUTDOOR: - *pValue = gState.t_outdoor; + *pValue = cels2reg(gState.t_outdoor); break; case I_T_INFLOW: - *pValue = gState.t_inflow; + *pValue = cels2reg(gState.t_inflow); break; case I_T_EXHAUST: - *pValue = gState.t_exhaust; + *pValue = cels2reg(gState.t_exhaust); break; case I_MODE_INST: *pValue = gState.instantaneous_vent_mode; @@ -166,7 +169,9 @@ ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { break; default: - return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; + // this allows Bridge reading + return 0; + //return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; } return MB_EXCEPTION_OK; @@ -230,7 +235,8 @@ ModbusException_t rh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) { return ri(pSlave, ref - INPUT_REG_MIRROR_IN_HOLDING_BASE_ADDR, pValue); } - return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; + return 0; + //return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; } return MB_EXCEPTION_OK; diff --git a/main/onewires.c b/main/onewires.c index e626320..6e92670 100644 --- a/main/onewires.c +++ b/main/onewires.c @@ -7,6 +7,7 @@ #include "owb.h" #include "ds18b20.h" #include "settings.h" +#include "recup_types.h" static const char* TAG="1w"; @@ -14,18 +15,18 @@ static owb_rmt_driver_info s_rmt_driver_info[2] = {}; static OneWireBus * sBuses[2] = {}; static DS18B20_Info *sDevs[2] = {}; -volatile int16_t gTempSensors[2] = {}; +volatile float gTempSensors[2] = {}; volatile bool tempSensorsOk = false; static void owtask(void *dummy) { while (1) { - int16_t a = 0, b = 0; + cels_t a = 0, b = 0; int rv = read_onewires(&a, &b); tempSensorsOk = (rv == 0); - ESP_LOGI(TAG, "t1 %d, t2 %d Cx10", a, b); gTempSensors[0] = a; gTempSensors[1] = b; + ESP_LOGI(TAG, "t1 %.2f, t2 %.2f C", a, b); } } @@ -45,7 +46,7 @@ void onewires_setup() xTaskCreate(owtask, "1w", ONEWIRES_TASK_STACK, NULL, ONEWIRES_TASK_PRIO, NULL); } -int read_onewires(int16_t *a, int16_t *b) +int read_onewires(cels_t *a, cels_t *b) { for (int i = 0; i < 2; i++) { ds18b20_convert_all(sBuses[i]); @@ -61,8 +62,8 @@ int read_onewires(int16_t *a, int16_t *b) errors[i] = ds18b20_read_temp(sDevs[i], &readings[i]); } - int16_t val1 = (int16_t) roundf(readings[0] * 10); - int16_t val2 = (int16_t) roundf(readings[1] * 10); + cels_t val1 = (cels_t) readings[0]; + cels_t val2 = (cels_t) readings[1]; if (gSettings.swap_temps) { *a = val2; diff --git a/main/onewires.h b/main/onewires.h index 1ec3a2c..7df6421 100644 --- a/main/onewires.h +++ b/main/onewires.h @@ -6,12 +6,13 @@ #define ONEWIRES_H #include +#include "recup_types.h" void onewires_setup(); -int read_onewires(int16_t *a, int16_t *b); +int read_onewires(cels_t *a, cels_t *b); -extern volatile int16_t gTempSensors[2]; +extern volatile cels_t gTempSensors[2]; extern volatile bool tempSensorsOk; #endif //ONEWIRES_H diff --git a/main/recup_types.h b/main/recup_types.h new file mode 100644 index 0000000..a9a4e8e --- /dev/null +++ b/main/recup_types.h @@ -0,0 +1,15 @@ +/** + * Commonly used types + */ + +#ifndef REKUPERATOR_RECUP_TYPES_H +#define REKUPERATOR_RECUP_TYPES_H + +#include + +typedef float cels_t; +typedef uint16_t perc_t; +typedef uint16_t secs_t; +typedef uint16_t hours_t; + +#endif //REKUPERATOR_RECUP_TYPES_H