convert all temp measurements to float, add newtypes for units

fix-tempmode
Ondřej Hruška 2 years ago
parent ebc4f7b165
commit 01b94ff604
  1. 4
      main/actuators.c
  2. 9
      main/actuators.h
  3. 98
      main/fancontrol.c
  4. 34
      main/fancontrol.h
  5. 22
      main/mbiface.c
  6. 13
      main/onewires.c
  7. 5
      main/onewires.h
  8. 15
      main/recup_types.h

@ -145,12 +145,12 @@ void act_init()
led_init(); led_init();
} }
int16_t act_temp1() cels_t act_temp1()
{ {
return gTempSensors[0]; return gTempSensors[0];
} }
int16_t act_temp2() cels_t act_temp2()
{ {
return gTempSensors[1]; return gTempSensors[1];
} }

@ -7,6 +7,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "recup_types.h"
enum motor_direction { enum motor_direction {
MOTOR_DIR_IN = 0, MOTOR_DIR_IN = 0,
@ -17,19 +18,19 @@ struct actuators_status {
enum motor_direction dir; enum motor_direction dir;
bool blind; bool blind;
bool led; bool led;
uint16_t power; perc_t power;
}; };
extern struct actuators_status gAct; extern struct actuators_status gAct;
void act_init(); 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_motor_direction_set(enum motor_direction dir);
void act_blind_set(bool open); void act_blind_set(bool open);
void act_led_set(bool on); void act_led_set(bool on);
void act_statusled_set(bool on); void act_statusled_set(bool on);
int16_t act_temp1(); cels_t act_temp1();
int16_t act_temp2(); cels_t act_temp2();
#endif //FANCTL_ACTUATORS_H #endif //FANCTL_ACTUATORS_H

@ -13,7 +13,7 @@
const char *TAG = "fc"; const char *TAG = "fc";
#define UNIDIR_T_MEAS_PERIOD 15 /* s */ #define UNIDIR_T_MEAS_PERIOD 60
struct FanControlState gState = {}; struct FanControlState gState = {};
static void timerCallback(); static void timerCallback();
@ -85,10 +85,10 @@ static const char * vent_mode_labels[] = {
[VENT_MODE_RECUP] = "RECUP", [VENT_MODE_RECUP] = "RECUP",
}; };
static const char * recup_mode_labels[] = { //static const char * recup_mode_labels[] = {
[RECUP_MODE_TIME] = "TIME", // [RECUP_MODE_TIME] = "TIME",
[RECUP_MODE_TEMP] = "TEMP", // [RECUP_MODE_TEMP] = "TEMP",
}; //};
static void timerCallback() static void timerCallback()
{ {
@ -115,7 +115,9 @@ static void timerCallback()
gState.ramp++; gState.ramp++;
} }
} }
gState.run_time++; if (gState.run_time < 0xFFFF) {
gState.run_time++;
}
} else { } else {
if (gState.ramp > 0) { if (gState.ramp > 0) {
gState.ramp--; gState.ramp--;
@ -141,7 +143,8 @@ static void timerCallback()
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.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; end_temp_meas = true;
} }
break; break;
@ -151,7 +154,7 @@ static void timerCallback()
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.ramp >= gSettings.ramp_time * 2) { if (gState.run_time >= UNIDIR_T_MEAS_PERIOD) {
end_temp_meas = true; end_temp_meas = true;
} }
break; break;
@ -164,54 +167,14 @@ static void timerCallback()
// Stop condition // Stop condition
bool do_switch = false; bool do_switch = false;
// TODO questionable logic, verify
if (gSettings.recup_mode == RECUP_MODE_TIME) { if (gSettings.recup_mode == RECUP_MODE_TIME) {
do_switch = gState.run_time >= gSettings.recup_time; do_switch = gState.run_time >= gSettings.recup_time;
} else if (gState.run_time >= gSettings.max_recup_time) {
do_switch = true;
} else { } else {
// temp-based switching - magic(tm) if (gState.run_time >= gSettings.max_recup_time) {
// Delta = IN - OUT // Max time elapsed, switch even if the condition was not reached
const int16_t ideal_delta = gState.t_indoor - gState.t_outdoor; do_switch = true;
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;
}
} else { } else {
// IN // TODO
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)
}
} }
} }
@ -243,8 +206,8 @@ static void timerCallback()
} }
// Measure temperatures // Measure temperatures
int16_t t1 = act_temp1(); cels_t t1 = act_temp1();
int16_t t2 = act_temp2(); cels_t t2 = act_temp2();
gState.t_actual_in = t1; gState.t_actual_in = t1;
gState.t_actual_out = t2; gState.t_actual_out = t2;
@ -273,29 +236,24 @@ static void timerCallback()
} }
ESP_LOGI(TAG, 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", "%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.effective_vent_mode], vent_mode_labels[gState.instantaneous_vent_mode], vent_mode_labels[gState.set_vent_mode], vent_mode_labels[gState.instantaneous_vent_mode],
gState.blind_position,
gState.run_time, gState.run_time,
gAct.power, gAct.power,
gState.t_indoor, gState.t_indoor, gState.valid_t_indoor ? "" : "!",
gState.valid_t_indoor ? "" : "!", gState.t_outdoor, gState.valid_t_outdoor ? "" : "!",
gState.t_outdoor, gState.t_inflow, gState.valid_t_inflow ? "" : "!",
gState.valid_t_outdoor ? "" : "!", gState.t_exhaust, gState.valid_t_exhaust ? "" : "!",
gState.t_inflow, gState.t_actual_in, gState.valid_t_actual_in ? "" : "!",
gState.valid_t_inflow ? "" : "!", gState.t_actual_out, gState.valid_t_actual_out ? "" : "!"
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) 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) { if (mode == gState.set_vent_mode) {
return; return;
@ -323,7 +281,7 @@ static void invalidate_temps()
gState.valid_t_actual_out = false; 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); ESP_LOGI(TAG, "Set power = %d%%", power);

@ -33,7 +33,7 @@ struct FanControlState {
* Power requested trough register or as the default value. * Power requested trough register or as the default value.
* This value stays unchanged even if stopped, unlike gAct.power which reflects the actual output. * 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! * 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_in;
bool valid_t_actual_out; bool valid_t_actual_out;
int16_t t_indoor; cels_t t_indoor;
int16_t t_outdoor; cels_t t_outdoor;
int16_t t_inflow; cels_t t_inflow;
int16_t t_exhaust; cels_t t_exhaust;
int16_t t_actual_in; cels_t t_actual_in;
int16_t t_actual_out; cels_t t_actual_out;
uint16_t real_recup_time_in; secs_t real_recup_time_in;
uint16_t real_recup_time_out; secs_t real_recup_time_out;
// Private // Private
/** /**
@ -73,27 +73,27 @@ struct FanControlState {
* Poloha roletky, 0<->blind_time, inkrement/dekrement 1 za sekundu. * Poloha roletky, 0<->blind_time, inkrement/dekrement 1 za sekundu.
* Pri zmene blind_time se musi hodnota aktualizovat, pokud je na doraze nebo za. * 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. * 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. * "stav chodu motoru". 0=stop, ramp_time = jede.
*/ */
uint16_t ramp; secs_t ramp;
// helper counters that increment hour counters when overflow // helper counters that increment hour counters when overflow
uint16_t uptime_secs; secs_t uptime_secs;
uint16_t motor_secs; hours_t motor_secs;
uint16_t uptime_hours; secs_t uptime_hours;
uint16_t motor_hours; hours_t motor_hours;
}; };
extern struct FanControlState gState; extern struct FanControlState gState;
void fan_set_vent_mode(enum ventilation_mode mode); 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 #endif //FANCTL_FANCONTROL_H

@ -1,4 +1,5 @@
#include <esp_log.h> #include <esp_log.h>
#include <math.h>
#include "mbiface.h" #include "mbiface.h"
#include "socket_server.h" #include "socket_server.h"
#include "tasks.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) { 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);
uint16_t scratch16 = 0; uint16_t scratch16 = 0;
@ -119,22 +122,22 @@ ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
*pValue = scratch16; *pValue = scratch16;
break; break;
case I_T_IN_INST: case I_T_IN_INST:
*pValue = gState.t_actual_in; *pValue = cels2reg(gState.t_actual_in);
break; break;
case I_T_OUT_INST: case I_T_OUT_INST:
*pValue = gState.t_actual_out; *pValue = cels2reg(gState.t_actual_out);
break; break;
case I_T_INDOOR: case I_T_INDOOR:
*pValue = gState.t_indoor; *pValue = cels2reg(gState.t_indoor);
break; break;
case I_T_OUTDOOR: case I_T_OUTDOOR:
*pValue = gState.t_outdoor; *pValue = cels2reg(gState.t_outdoor);
break; break;
case I_T_INFLOW: case I_T_INFLOW:
*pValue = gState.t_inflow; *pValue = cels2reg(gState.t_inflow);
break; break;
case I_T_EXHAUST: case I_T_EXHAUST:
*pValue = gState.t_exhaust; *pValue = cels2reg(gState.t_exhaust);
break; break;
case I_MODE_INST: case I_MODE_INST:
*pValue = gState.instantaneous_vent_mode; *pValue = gState.instantaneous_vent_mode;
@ -166,7 +169,9 @@ ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
break; break;
default: default:
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS; // this allows Bridge reading
return 0;
//return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
} }
return MB_EXCEPTION_OK; 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 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; return MB_EXCEPTION_OK;

@ -7,6 +7,7 @@
#include "owb.h" #include "owb.h"
#include "ds18b20.h" #include "ds18b20.h"
#include "settings.h" #include "settings.h"
#include "recup_types.h"
static const char* TAG="1w"; static const char* TAG="1w";
@ -14,18 +15,18 @@ static owb_rmt_driver_info s_rmt_driver_info[2] = {};
static OneWireBus * sBuses[2] = {}; static OneWireBus * sBuses[2] = {};
static DS18B20_Info *sDevs[2] = {}; static DS18B20_Info *sDevs[2] = {};
volatile int16_t gTempSensors[2] = {}; volatile float gTempSensors[2] = {};
volatile bool tempSensorsOk = false; volatile bool tempSensorsOk = false;
static void owtask(void *dummy) { static void owtask(void *dummy) {
while (1) { while (1) {
int16_t a = 0, b = 0; cels_t a = 0, b = 0;
int rv = read_onewires(&a, &b); int rv = read_onewires(&a, &b);
tempSensorsOk = (rv == 0); tempSensorsOk = (rv == 0);
ESP_LOGI(TAG, "t1 %d, t2 %d Cx10", a, b);
gTempSensors[0] = a; gTempSensors[0] = a;
gTempSensors[1] = b; 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); 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++) { for (int i = 0; i < 2; i++) {
ds18b20_convert_all(sBuses[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]); errors[i] = ds18b20_read_temp(sDevs[i], &readings[i]);
} }
int16_t val1 = (int16_t) roundf(readings[0] * 10); cels_t val1 = (cels_t) readings[0];
int16_t val2 = (int16_t) roundf(readings[1] * 10); cels_t val2 = (cels_t) readings[1];
if (gSettings.swap_temps) { if (gSettings.swap_temps) {
*a = val2; *a = val2;

@ -6,12 +6,13 @@
#define ONEWIRES_H #define ONEWIRES_H
#include <stdint.h> #include <stdint.h>
#include "recup_types.h"
void onewires_setup(); 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; extern volatile bool tempSensorsOk;
#endif //ONEWIRES_H #endif //ONEWIRES_H

@ -0,0 +1,15 @@
/**
* Commonly used types
*/
#ifndef REKUPERATOR_RECUP_TYPES_H
#define REKUPERATOR_RECUP_TYPES_H
#include <stdint.h>
typedef float cels_t;
typedef uint16_t perc_t;
typedef uint16_t secs_t;
typedef uint16_t hours_t;
#endif //REKUPERATOR_RECUP_TYPES_H
Loading…
Cancel
Save