finalizations

This commit is contained in:
2022-08-27 23:55:21 +02:00
parent e274ec0055
commit 752bbecf1c
11 changed files with 190 additions and 275 deletions
+4 -4
View File
@@ -1,14 +1,14 @@
menu "Project configuration"
menu "Pin mapping"
config PIN_BUZZER
int "Buzzer pin"
default 16
config PIN_LED
int "LED pin"
default 17
config PIN_STATUSLED
int "Status LED pin"
default 20
config PIN_BLIND
int "Blind open pin"
default 18
+16 -44
View File
@@ -16,46 +16,14 @@ struct actuators_status gAct = {
.power = 0,
};
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
.speed_mode = LEDC_HIGH_SPEED_MODE, // timer mode
.timer_num = LEDC_TIMER_0, // timer index
.clk_cfg = LEDC_AUTO_CLK, // Auto select the source clock
};
// Set configuration of timer0 for high speed channels
ledc_timer_config(&ledc_timer);
ledc_channel_config_t chan = {
.channel = LEDC_CHANNEL_0,
.duty = 127,
.gpio_num = CONFIG_PIN_BUZZER,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.hpoint = 0,
.timer_sel = LEDC_TIMER_0
};
ledc_channel_config(&chan);
}
void act_buzzer_set(bool on)
{
if (gAct.buzzer == on) {
return;
}
ESP_LOGI(TAG, "set buzzer %d", on);
gAct.buzzer = on;
if (on) {
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 127);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
} else {
ledc_stop(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 0);
}
}
int sPinPwm = 0;
int sPinDir = 0;
static void motor_init()
{
sPinPwm = (gSettings.swap_pwm_dir ? CONFIG_PIN_DIR : CONFIG_PIN_PWM);
sPinDir = (gSettings.swap_pwm_dir ? CONFIG_PIN_PWM : CONFIG_PIN_DIR);
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_10_BIT, // resolution of PWM duty
.freq_hz = 1000, // frequency of PWM signal
@@ -70,7 +38,7 @@ static void motor_init()
ledc_channel_config_t chan = {
.channel = LEDC_CHANNEL_1,
.duty = 512,
.gpio_num = CONFIG_PIN_PWM,
.gpio_num = sPinPwm,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.hpoint = 0,
.timer_sel = LEDC_TIMER_1,
@@ -81,7 +49,7 @@ static void motor_init()
// Direction output
gpio_config_t ioconf = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1 << CONFIG_PIN_DIR,
.pin_bit_mask = 1 << sPinDir,
};
gpio_config(&ioconf);
@@ -123,7 +91,7 @@ void act_motor_direction_set(enum motor_direction dir)
}
ESP_LOGI(TAG, "set dir %d", dir);
gAct.dir = dir;
gpio_set_level(CONFIG_PIN_DIR, (int) dir); // TODO verify polarity
gpio_set_level(sPinDir, (int) dir); // TODO verify polarity
}
static void blind_init()
@@ -150,7 +118,7 @@ static void led_init()
{
gpio_config_t ioconf = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1 << CONFIG_PIN_LED,
.pin_bit_mask = (1 << CONFIG_PIN_LED) | (1 << CONFIG_PIN_STATUSLED),
};
gpio_config(&ioconf);
}
@@ -165,20 +133,24 @@ void act_led_set(bool on)
gpio_set_level(CONFIG_PIN_LED, (int) on); // TODO verify polarity
}
void act_statusled_set(bool on)
{
gpio_set_level(CONFIG_PIN_STATUSLED, (int) on);
}
void act_init()
{
buzzer_init();
motor_init();
blind_init();
led_init();
}
int16_t act_temp_in()
int16_t act_temp1()
{
return gTempSensors[0];
}
int16_t act_temp_out()
int16_t act_temp2()
{
return gTempSensors[1];
}
+3 -4
View File
@@ -17,20 +17,19 @@ struct actuators_status {
enum motor_direction dir;
bool blind;
bool led;
bool buzzer;
uint16_t power;
};
extern struct actuators_status gAct;
void act_init();
void act_buzzer_set(bool on);
void act_motor_power_set(uint16_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_temp_in();
int16_t act_temp_out();
int16_t act_temp1();
int16_t act_temp2();
#endif //FANCTL_ACTUATORS_H
+21 -2
View File
@@ -35,9 +35,27 @@ void settings_blind_time_set(uint16_t blind_time)
static void fanctltask(void *dummy) {
TickType_t last_wake_time = xTaskGetTickCount();
bool statusled = 0;
while (1) {
act_statusled_set(statusled);
statusled ^= 1;
//
timerCallback();
vTaskDelayUntil(&last_wake_time, pdMS_TO_TICKS(1000));
gState.uptime_secs += 1;
if (gState.uptime_secs >= 3600) {
gState.uptime_secs = 0;
gState.uptime_hours += 1;
}
if ((gState.effective_vent_mode & 6) != 0) {
gState.motor_secs += 1;
if (gState.motor_secs >= 3600) {
gState.motor_secs = 0;
gState.motor_hours += 1;
}
}
}
}
@@ -46,6 +64,7 @@ void fancontrol_init()
gState.set_vent_mode = gSettings.initial_mode;
gState.set_power = gSettings.initial_power;
// this doesnt work
// TimerHandle_t hTimer = xTimerCreate("fanctl",
// pdMS_TO_TICKS(1000),
// pdTRUE,
@@ -236,8 +255,8 @@ static void timerCallback()
}
// Measure temperatures
int16_t t1 = act_temp_in();
int16_t t2 = act_temp_out();
int16_t t1 = act_temp1();
int16_t t2 = act_temp2();
gState.t_actual_in = t1;
gState.t_actual_out = t2;
+8
View File
@@ -10,6 +10,7 @@
void fancontrol_init();
/** this is bit-based: IN:OUT:BLIND */
enum ventilation_mode {
VENT_MODE_OFF = 0,
VENT_MODE_FREE = 1,
@@ -84,6 +85,13 @@ struct FanControlState {
int32_t t1_aggr;
int32_t t2_aggr;
uint32_t t_aggr_cnt;
// helper counters that increment hour counters when overflow
uint16_t uptime_secs;
uint16_t motor_secs;
uint16_t uptime_hours;
uint16_t motor_hours;
};
extern struct FanControlState gState;
+106 -37
View File
@@ -9,39 +9,64 @@
static const char * TAG = "mb";
Tcpd_t g_mbifc_server = NULL;
ModbusSlave_t gModbus;
ModbusSlave_t gModbus = {};
#define IDENT_MAGIC 3333
#define REBOOT_MAGIC 0xB007 /* 45063 */
#define INPUT_REG_MIRROR_IN_HOLDING_BASE_ADDR 1000
enum HoldingRegisters {
H_IDENT = 0,
// Control
H_MODE = 1,
H_POWER,
H_SUMMER,
H_INITIAL_MODE,
H_INITIAL_POWER,
H_RECUP_MODE,
H_RECUP_TIME,
H_RECUP_TIME_MIN,
H_RECUP_TIME_MAX,
H_RECUP_FACTOR,
H_RAMP_TIME,
H_BLIND_TIME,
H_MIN_POWER,
H_POWER = 2,
H_SUMMER_MODE = 3,
// Settings
H_INITIAL_MODE = 10,
H_INITIAL_POWER = 11,
H_RECUP_MODE = 12,
H_RECUP_TIME = 13,
H_RECUP_TIME_MIN = 14,
H_RECUP_TIME_MAX = 15,
H_RECUP_FACTOR = 16,
H_MIN_POWER = 17,
// Hardware settings (don't need to change once set correctly)
H_RAMP_TIME = 30,
H_BLIND_TIME = 31,
H_SWAP_TEMPS = 32,
H_SWAP_PWMDIR = 33,
H_REBOOT = 70,
};
enum InputRegisters {
I_RECUP_TIME_IN = 1,
I_RECUP_TIME_OUT,
I_T_VALIDITY,
I_T_IN_INST,
I_T_OUT_INST,
I_T_INDOOR,
I_T_OUTDOOR,
I_T_INFLOW,
I_T_EXHAUST,
I_MODE_INST,
I_MOTOR_RAMP,
I_BLIND_RAMP,
I_T_VALIDITY = 1,
I_T_IN_INST = 2,
I_T_OUT_INST = 3,
I_T_INDOOR = 4,
I_T_OUTDOOR = 5,
I_T_INFLOW = 6,
I_T_EXHAUST = 7,
I_RECUP_TIME_IN = 8,
I_RECUP_TIME_OUT = 9,
I_MODE_INST = 20,
I_MOTOR_RAMP = 21,
I_BLIND_RAMP = 22,
I_MOTOR_SECS = 23,
I_MOTOR_HOURS = 24,
I_UPTIME_SECS = 25,
I_UPTIME_HOURS = 26,
I_FREE_HEAP_KB = 27,
};
static void restartLater() {
vTaskDelay(pdMS_TO_TICKS(100));
esp_restart();
}
/**
* Socket read handler
*/
@@ -74,7 +99,8 @@ void endOfAccess(ModbusSlave_t *ms) {
ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
ESP_LOGD(TAG, "Read input %d", ref);
uint16_t scratch = 0;
uint16_t scratch16 = 0;
uint32_t scratch32 = 0;
switch (ref) {
case I_RECUP_TIME_IN:
@@ -84,13 +110,13 @@ ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
*pValue = gState.real_recup_time_out;
break;
case I_T_VALIDITY:
scratch |= (int)gState.valid_t_actual_in;
scratch |= (int)gState.valid_t_actual_out << 1;
scratch |= (int)gState.valid_t_indoor << 2;
scratch |= (int)gState.valid_t_outdoor << 3;
scratch |= (int)gState.valid_t_inflow << 4;
scratch |= (int)gState.valid_t_exhaust << 5;
*pValue = scratch;
scratch16 |= (int)gState.valid_t_actual_in;
scratch16 |= (int)gState.valid_t_actual_out << 1;
scratch16 |= (int)gState.valid_t_indoor << 2;
scratch16 |= (int)gState.valid_t_outdoor << 3;
scratch16 |= (int)gState.valid_t_inflow << 4;
scratch16 |= (int)gState.valid_t_exhaust << 5;
*pValue = scratch16;
break;
case I_T_IN_INST:
*pValue = gState.t_actual_in;
@@ -119,6 +145,25 @@ ModbusException_t ri(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
case I_BLIND_RAMP:
*pValue = gState.blind_position;
break;
case I_UPTIME_SECS:
*pValue = gState.uptime_secs;
break;
case I_UPTIME_HOURS:
*pValue = gState.uptime_hours;
break;
case I_MOTOR_SECS:
*pValue = gState.motor_secs;
break;
case I_MOTOR_HOURS:
*pValue = gState.motor_hours;
break;
case I_FREE_HEAP_KB:
scratch32 = esp_get_free_heap_size() / 1024;
if (scratch32 > UINT16_MAX) {
scratch32 = UINT16_MAX;
}
*pValue = scratch32;
break;
default:
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
@@ -131,13 +176,16 @@ ModbusException_t rh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
ESP_LOGD(TAG, "Read holding %d", ref);
switch (ref) {
case H_IDENT:
*pValue = IDENT_MAGIC;
break;
case H_MODE:
*pValue = (int) gState.set_vent_mode;
break;
case H_POWER:
*pValue = gState.set_power;
break;
case H_SUMMER:
case H_SUMMER_MODE:
*pValue = (int) gSettings.summer_mode;
break;
case H_INITIAL_MODE:
@@ -170,10 +218,16 @@ ModbusException_t rh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t *pValue) {
case H_MIN_POWER:
*pValue = gSettings.min_power;
break;
case H_SWAP_TEMPS:
*pValue = gSettings.swap_temps;
break;
case H_SWAP_PWMDIR:
*pValue = gSettings.swap_pwm_dir;
break;
default:
// inputs are mapped to the holding address space
if (ref >= 100) {
return ri(pSlave, ref - 100, pValue);
if (ref >= INPUT_REG_MIRROR_IN_HOLDING_BASE_ADDR) {
return ri(pSlave, ref - INPUT_REG_MIRROR_IN_HOLDING_BASE_ADDR, pValue);
}
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
@@ -211,7 +265,7 @@ ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) {
}
fan_set_power(value);
break;
case H_SUMMER:
case H_SUMMER_MODE:
gSettings.summer_mode = (value != 0);
settings_persist(SETTINGS_summer_mode);
break;
@@ -279,6 +333,21 @@ ModbusException_t wh(ModbusSlave_t *pSlave, uint16_t ref, uint16_t value) {
gSettings.min_power = value;
settings_persist(SETTINGS_min_power);
break;
case H_SWAP_TEMPS:
gSettings.swap_temps = value;
settings_persist(SETTINGS_swap_temps);
break;
case H_SWAP_PWMDIR:
gSettings.swap_temps = value;
settings_persist(SETTINGS_swap_pwm_dir);
break;
case H_REBOOT:
if (value == REBOOT_MAGIC) {
// if we restart immediately, the modbus req won't finish and master then sends retries
// and restarts us again and again
xTaskCreate(restartLater, "kill", 2048, NULL, PRIO_HIGH, NULL);
}
break;
default:
return MB_EXCEPTION_ILLEGAL_DATA_ADDRESS;
}
+12 -7
View File
@@ -6,6 +6,7 @@
#include "tasks.h"
#include "owb.h"
#include "ds18b20.h"
#include "settings.h"
static const char* TAG="1w";
@@ -54,17 +55,21 @@ int read_onewires(int16_t *a, int16_t *b)
DS18B20_ERROR errors[2] = { 0 };
ds18b20_wait_for_conversion(sDevs[0]);
vTaskDelay(pdMS_TO_TICKS(10)); // to be sure its done
vTaskDelay(pdMS_TO_TICKS(15)); // to be sure it's done
for (int i = 0; i < 2; i++) {
errors[i] = ds18b20_read_temp(sDevs[i], &readings[i]);
}
if (errors[0] != DS18B20_OK || errors[1] != DS18B20_OK) {
return -1;
}
int16_t val1 = (int16_t) roundf(readings[0] * 10);
int16_t val2 = (int16_t) roundf(readings[1] * 10);
*a = (int16_t) roundf(readings[0] * 10);
*b = (int16_t) roundf(readings[1] * 10);
return 0;
if (gSettings.swap_temps) {
*a = val2;
*b = val1;
} else {
*a = val1;
*b = val2;
}
return (errors[0] == DS18B20_OK) && (errors[1] != DS18B20_OK);
}
+3 -1
View File
@@ -49,7 +49,9 @@ extern nvs_handle g_nvs_storage;
X(uint16_t , initial_mode , , 0 , true , u16 , &) /* rezim po zapnuti napajeni */ \
X(uint16_t , initial_power , , 50 , true , u16 , &) /* vychozi vykon */ \
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_pwm_dir , , 0 , true , bool , &) /* swap pwm/dir signal */
enum settings_key_enum {
#undef X
+5 -3
View File
@@ -33,6 +33,11 @@ void app_main(void) {
settings_init();
settings_load();
// do it ASAP so the fan maybe doesn't have time to start
onewires_setup();
act_init();
fancontrol_init();
// Start IDF service for pin change interrupts
ESP_ERROR_CHECK(gpio_install_isr_service(0));
@@ -58,10 +63,7 @@ void app_main(void) {
console_setup_uart_stdio();
ESP_ERROR_CHECK(console_start_stdio(NULL, NULL));
onewires_setup();
act_init();
mbiface_setup();
fancontrol_init();
telnetsrv_start(CONSOLE_TELNET_PORT);
ESP_LOGI(TAG, "Startup finished, free heap = %u, cmds %"PRIu32, esp_get_free_heap_size(), console_count_commands());