master
Ondřej Hruška 2 years ago
parent 475478aea4
commit 0753dce6b1
  1. 46
      main/actuators.c
  2. 3
      main/actuators.h
  3. 61
      main/fancontrol.c
  4. 6
      main/fancontrol.h
  5. 4
      main/settings.c
  6. 2
      main/settings.h

@ -12,7 +12,8 @@ struct actuators_status gAct = {
.power = 0,
};
static void buzzer_init() {
static void buzzer_init()
{
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_8_BIT, // resolution of PWM duty
.freq_hz = 4400, // frequency of PWM signal
@ -34,7 +35,8 @@ static void buzzer_init() {
ledc_channel_config(&chan);
}
void act_buzzer_set(bool on) {
void act_buzzer_set(bool on)
{
gAct.buzzer = on;
if (on) {
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 127);
@ -44,7 +46,8 @@ void act_buzzer_set(bool on) {
}
}
static void motor_init() {
static void motor_init()
{
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_10_BIT, // resolution of PWM duty
.freq_hz = 1000, // frequency of PWM signal
@ -75,14 +78,15 @@ static void motor_init() {
gpio_config(&ioconf);
}
void act_motor_power_set(uint16_t perc) {
if (gAct.power == perc) return;
void act_motor_power_set(uint16_t perc)
{
if (gAct.power == perc) { return; }
if (perc > 0) {
if (perc < gSettings.min_power) {
perc = gSettings.min_power;
}
gAct.power = perc;
uint16_t duty = (uint16_t) (10.23f * (float)perc);
uint16_t duty = (uint16_t) (10.23f * (float) perc);
if (duty > 1023) {
duty = 1023;
}
@ -94,12 +98,14 @@ void act_motor_power_set(uint16_t perc) {
}
}
void act_motor_direction_set(enum motor_direction dir) {
void act_motor_direction_set(enum motor_direction dir)
{
gAct.dir = dir;
gpio_set_level(CONFIG_PIN_DIR, (int) dir); // TODO verify polarity
}
static void blind_init() {
static void blind_init()
{
// Blind output
gpio_config_t ioconf = {
.mode = GPIO_MODE_OUTPUT,
@ -108,12 +114,14 @@ static void blind_init() {
gpio_config(&ioconf);
}
void act_blind_set(bool open) {
void act_blind_set(bool open)
{
gAct.blind = open;
gpio_set_level(CONFIG_PIN_BLIND, (int) open); // TODO verify polarity
}
static void led_init() {
static void led_init()
{
gpio_config_t ioconf = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1 << CONFIG_PIN_LED,
@ -121,14 +129,28 @@ static void led_init() {
gpio_config(&ioconf);
}
void act_led_set(bool on) {
void act_led_set(bool on)
{
gAct.led = on;
gpio_set_level(CONFIG_PIN_LED, (int) on); // TODO verify polarity
}
void act_init() {
void act_init()
{
buzzer_init();
motor_init();
blind_init();
led_init();
}
int16_t act_temp_in()
{
// TODO
return 200;
}
int16_t act_temp_out()
{
// TODO
return 40;
}

@ -30,4 +30,7 @@ void act_motor_direction_set(enum motor_direction dir);
void act_blind_set(bool open);
void act_led_set(bool on);
int16_t act_temp_in();
int16_t act_temp_out();
#endif //FANCTL_ACTUATORS_H

@ -12,9 +12,11 @@
struct FanControlState gState = {};
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);
gSettings.blind_time = blind_time;
@ -26,7 +28,8 @@ void settings_blind_time_set(uint16_t blind_time) {
settings_persist(SETTINGS_blind_time);
}
void fancontrol_init() {
void fancontrol_init()
{
gState.set_vent_mode = gSettings.initial_mode;
gState.set_power = gSettings.initial_power;
@ -38,7 +41,8 @@ void fancontrol_init() {
}
static void timerCallback(TimerHandle_t xTimer) {
static void timerCallback(TimerHandle_t xTimer)
{
// posun rolety
if (gAct.blind) {
if (gState.blind_position < gSettings.blind_time) {
@ -119,26 +123,22 @@ static void timerCallback(TimerHandle_t xTimer) {
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 delta, stop_delta;
int16_t stop_delta = ((int32_t) ideal_delta
* (int32_t) (100 - gSettings.recup_factor)) / 100;
int16_t delta;
bool allow_temp_switch = false;
if (gState.real_direction == MOTOR_DIR_OUT) {
delta = gState.t_indoor - gState.t_exhaust;
// 100% factor = nadoraz
stop_delta = ((int32_t)ideal_delta
* (int32_t)(100 - gSettings.recup_factor)) / 100;
// Delta = IN - 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 {
// IN
delta = gState.t_inflow - gState.t_outdoor;
// 100% factor = nadoraz
stop_delta = ((int32_t)ideal_delta
* (int32_t)(gSettings.recup_factor)) / 100;
// Delta = IN - OUT
if (gState.valid_t_intake && gState.valid_t_indoor && gState.valid_t_outdoor) {
if (gState.valid_t_inflow && gState.valid_t_indoor && gState.valid_t_outdoor) {
delta = gState.t_inflow - gState.t_outdoor;
allow_temp_switch = true;
}
}
@ -188,13 +188,13 @@ static void timerCallback(TimerHandle_t xTimer) {
if (end_temp_meas) {
if (gState.t_aggr_cnt > 0) {
uint16_t t1 = (uint16_t) (gState.t1_aggr / gState.t_aggr_cnt);
uint16_t t2 = (uint16_t) (gState.t2_aggr / gState.t_aggr_cnt);
int16_t t1 = (int16_t) (gState.t1_aggr / (int32_t)gState.t_aggr_cnt);
int16_t t2 = (int16_t) (gState.t2_aggr / (int32_t)gState.t_aggr_cnt);
switch (gState.real_direction) {
case MOTOR_DIR_IN:
gState.t_outdoor = t2;
gState.t_inflow = t1;
gState.valid_t_outdoor = gState.valid_t_intake = true;
gState.valid_t_outdoor = gState.valid_t_inflow = true;
if (gState.effective_vent_mode == VENT_MODE_IN) {
gState.valid_t_indoor = gState.valid_t_exhaust = false;
}
@ -204,20 +204,21 @@ static void timerCallback(TimerHandle_t xTimer) {
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;
gState.valid_t_outdoor = gState.valid_t_inflow = false;
}
break;
}
}
gState.t1_aggr = gState.t2_aggr = gState.t_aggr_cnt = 0;
gState.t1_aggr = gState.t2_aggr = 0;
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
int16_t t1 = act_temp_in();
int16_t t2 = act_temp_out();
gState.t_actual_1 = t1;
gState.t_actual_2 = t2;
@ -225,7 +226,8 @@ static void timerCallback(TimerHandle_t xTimer) {
gState.valid_t_actual_1 = gState.valid_t_actual_2 = true;
if (gAct.dir == gState.real_direction
&& gState.ramp >= gSettings.ramp_time) {
&& gState.ramp >= gSettings.ramp_time)
{
gState.t1_aggr += t1;
gState.t2_aggr += t2;
gState.t_aggr_cnt++;
@ -235,7 +237,8 @@ static void timerCallback(TimerHandle_t xTimer) {
}
}
void fan_set_vent_mode(enum ventilation_mode mode) {
void fan_set_vent_mode(enum ventilation_mode mode)
{
if (mode == gState.set_vent_mode) {
return;
}
@ -253,16 +256,18 @@ void fan_set_vent_mode(enum ventilation_mode mode) {
}
}
static void invalidate_temps() {
static void invalidate_temps()
{
gState.valid_t_indoor = false;
gState.valid_t_outdoor = false;
gState.valid_t_intake = false;
gState.valid_t_inflow = 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) {
void fan_set_power(uint16_t power)
{
gState.set_power = power;
if (power == 0) {
gState.effective_vent_mode = VENT_MODE_OFF;
@ -270,4 +275,4 @@ void fan_set_power(uint16_t power) {
} else {
gState.effective_vent_mode = gState.set_vent_mode;
}
}
}

@ -43,7 +43,7 @@ struct FanControlState {
/* sensors */
bool valid_t_indoor;
bool valid_t_outdoor;
bool valid_t_intake;
bool valid_t_inflow;
bool valid_t_exhaust;
bool valid_t_actual_1;
bool valid_t_actual_2;
@ -78,8 +78,8 @@ struct FanControlState {
* "stav chodu motoru". 0=stop, ramp_time = jede.
*/
uint16_t ramp;
uint32_t t1_aggr;
uint32_t t2_aggr;
int32_t t1_aggr;
int32_t t2_aggr;
uint32_t t_aggr_cnt;
};

@ -37,6 +37,7 @@ 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;
@ -60,6 +61,7 @@ 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) {
@ -123,7 +125,7 @@ void settings_load(void)
void settings_persist(enum settings_key_enum what)
{
esp_err_t rv;
char name[24];
//char name[24];
#undef NVSCHECK
#define NVSCHECK(callback) \

@ -44,7 +44,7 @@ extern nvs_handle g_nvs_storage;
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 , , 120 , true , u16 , &) /* seconds */ \
X(uint16_t , ramp_time , , 3 , true , u16 , &) /* cas rozjezdu nebo zastaveni motoru (s) */ \
X(uint16_t , ramp_time , , 5 , true , u16 , &) /* cas rozjezdu nebo zastaveni motoru (s) */ \
X(uint16_t , blind_time , , 30 , true , u16 , &) /* cas otevreni nebo zavreni rolety (s) */ \
X(uint16_t , initial_mode , , 0 , true , u16 , &) /* rezim po zapnuti napajeni */ \
X(uint16_t , initial_power , , 100 , true , u16 , &) /* vychozi vykon */ \

Loading…
Cancel
Save