From: Nathael Pajani Date: Fri, 12 Jun 2020 23:31:56 +0000 (+0200) Subject: Updated v10 Adding max temps hysteresys Working on configuration menu X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=b64c6d94138efc6262cff0f9762aa9e816836738;p=soft%2Flpc122x%2Fscialys Updated v10 Adding max temps hysteresys Working on configuration menu --- diff --git a/v10/.version b/v10/.version index 7facc89..e1617e8 100644 --- a/v10/.version +++ b/v10/.version @@ -1 +1 @@ -36 +57 diff --git a/v10/Makefile b/v10/Makefile index 4c5c637..4813728 100644 --- a/v10/Makefile +++ b/v10/Makefile @@ -14,9 +14,10 @@ endif .PHONY: $(NAME).bin $(NAME).bin: - @$(shell ../../../update_version.sh && touch interface.c) @make -C ../../.. ${PRINT_DIRECTORY} NAME=$(NAME) MODULE=$(MODULE) apps/$(MODULE)/$(NAME)/$@ clean mrproper: @make -C ../../.. ${PRINT_DIRECTORY} $@ +temp: + @$(shell ../../../update_version.sh && touch interface.c) diff --git a/v10/config.c b/v10/config.c index 976dd95..fd10a18 100644 --- a/v10/config.c +++ b/v10/config.c @@ -233,6 +233,7 @@ void read_internal_config(void) conf = get_user_info(); memcpy(&sc_conf, conf, sizeof(struct scialys_config)); if (sc_conf.config_ok != CONFIG_OK) { + uprintf(UART0, "User config read from flash does not have magic : 0x%04x.\n", sc_conf.config_ok); memset(&sc_conf, 0, sizeof(struct scialys_config)); } /* Checksum */ @@ -243,10 +244,12 @@ void read_internal_config(void) if (sum != 0) { /* Checksum error : erase config in order to start with a default one */ memset(&sc_conf, 0, sizeof(struct scialys_config)); + uprintf(UART0, "User config read from flash has bad checksum.\n"); } /* Config version error ? */ if (sc_conf.conf_version != CONFIG_VERSION) { sc_conf.config_ok = 0; + uprintf(UART0, "User config read from flash has bad config version : %d.\n", sc_conf.conf_version); } } @@ -256,6 +259,7 @@ int user_flash_update(void) uint8_t* mem = NULL; int ret = 0; uint8_t sum = 0, i = 0; + uint32_t size = 0; /* Compute and store checksum */ sc_conf.checksum = 0; @@ -271,28 +275,36 @@ int user_flash_update(void) uprintf(UART0, "User config update error: %d\n", ret); return -1; } - ret = iap_copy_ram_to_flash((uint32_t)get_user_info(), (uint32_t)&sc_conf, sizeof(struct scialys_config)); + size = ((sizeof(struct scialys_config) + 3) & ~0x03); + ret = iap_copy_ram_to_flash((uint32_t)get_user_info(), (uint32_t)&sc_conf, size); if (ret != 0) { uprintf(UART0, "User config update error: %d\n", ret); return -2; } + uprintf(UART0, "Scialys module user config update done\n"); return 0; } /* Maximum power which can be used from the external (paid) power source, specified in kW or kVA */ -#define EXT_SOURCE_POWER_LIMIT 6 +#define GRID_POWER_LIMIT 6 + +#define SOURCE_POWER_MAX 3000 /* in Watt */ + +#define LOAD_POWER_MAX 2700 /* in Watt */ /* mA prod value above which the system will not enter forced mode, waiting for home * to stop using power in order to start automatic heating */ -#define SUNNY_DAYS_PROD_VALUE 3000 +uint32_t sunny_days_prod_value = 0; + +#define MAX_TEMP_CONFIG (80 * 100) /* 80 °C */ -/* If temperature falls bellow FORCE_HEATER_TEMP value, we enter forced heater mode, until +/* If temperature falls bellow ENTER_FORCE_HEATER_TEMP value, we enter forced heater mode, until * TARGET_FORCED_HEATER_TEMP is reached. * When in forced heater mode, the heater is controlled to heat at FORCED_MODE_VALUE which * is between 0 and 100. */ -#define FORCE_HEATER_TEMP (30 * 100) /* 30 °C */ +#define ENTER_FORCE_HEATER_TEMP (30 * 100) /* 30 °C */ #define TARGET_FORCED_HEATER_TEMP (50 * 100) /* 50 °C */ #define FORCED_MODE_VALUE 100 /* A fraction of 100 */ /* Delay before automatic forced heating */ @@ -312,28 +324,23 @@ int user_flash_update(void) #define MANUAL_TYPE_TARGET 2 #define DEFAULT_MANUAL_FORCE_TYPE MANUAL_TYPE_TARGET - -/* Read main configuration - or set to default one */ -void read_scialys_main_config(void) +void check_config(void) { - read_internal_config(); - /* Check that config read from flash is OK */ - if (sc_conf.config_ok == CONFIG_OK) { - uprintf(UART0, "Internal config read OK\n"); - return; - } /* If config version error (old config) then only update new fields */ switch (sc_conf.conf_version) { /* Do not change order. * Do not add breaks. */ default: + case 0x00: /* Set base default config */ uprintf(UART0, "Fallback to default config\n"); - sc_conf.ext_source_power_limit = EXT_SOURCE_POWER_LIMIT; - sc_conf.sunny_days_prod_value = SUNNY_DAYS_PROD_VALUE; - sc_conf.force_heater_temp = FORCE_HEATER_TEMP; - sc_conf.target_forced_heater_temp = TARGET_FORCED_HEATER_TEMP; + sc_conf.grid_power_limit = GRID_POWER_LIMIT; + sc_conf.source_power_max = SOURCE_POWER_MAX; + sc_conf.load_power_max = LOAD_POWER_MAX; + sc_conf.conf_max_temp = MAX_TEMP_CONFIG; + sc_conf.enter_force_heater_temp = ENTER_FORCE_HEATER_TEMP; + sc_conf.auto_forced_target_heater_temp = TARGET_FORCED_HEATER_TEMP; sc_conf.auto_forced_mode_value = FORCED_MODE_VALUE; sc_conf.forced_heater_delay = FORCED_HEATER_DELAY; sc_conf.forced_heater_duration = FORCED_HEATER_DURATION; @@ -348,6 +355,22 @@ void read_scialys_main_config(void) sc_conf.conf_version = CONFIG_VERSION; sc_conf.config_ok = CONFIG_OK; } + + /* Update sunny_days_prod_value (Watt to mA) */ + sunny_days_prod_value = (((uint32_t)(sc_conf.load_power_max / 3) * 1000) / 230); +} + +/* Read main configuration - or set to default one */ +void read_scialys_main_config(void) +{ + read_internal_config(); + /* Check that config read from flash is OK */ + if (sc_conf.config_ok == CONFIG_OK) { + uprintf(UART0, "Internal config read OK\n"); + return; + } + /* Check that it is up to date */ + check_config(); } @@ -411,6 +434,7 @@ uint8_t power_board_present = 0; int external_config(uint32_t uart) { int ret = 0; + int retcode = 0; /* uSD card */ uSD_config((struct pio *)&uSD_cs, SSP_BUS_0); @@ -429,13 +453,14 @@ int external_config(uint32_t uart) if (ret != 0) { uprintf(uart, "Temp config error on power board: %d\n", ret); power_board_present = 0; - return -1; - } - ret = tmp101_sensor_set_continuous_conversion(&tmp101_sensor_power); - if (ret != 0) { - uprintf(uart, "Temp config error on power board: %d\n", ret); - power_board_present = 0; - return -2; + retcode -= 1; + } else { + ret = tmp101_sensor_set_continuous_conversion(&tmp101_sensor_power); + if (ret != 0) { + uprintf(uart, "Temp config error on power board: %d\n", ret); + power_board_present = 0; + retcode -= 2; + } } /* TMP101 sensor config on display board */ @@ -443,11 +468,13 @@ int external_config(uint32_t uart) if (ret != 0) { uprintf(uart, "Temp config error on display board: %d\n", ret); interface_board_present = 0; + retcode -= 4; } else { ret = tmp101_sensor_set_continuous_conversion(&tmp101_sensor_display); if (ret != 0) { uprintf(uart, "Temp config error on display board: %d\n", ret); interface_board_present = 0; + retcode -= 8; } else { interface_board_present = 1; } @@ -457,9 +484,9 @@ int external_config(uint32_t uart) if (interface_board_present == 1) { ret = interface_config(uart); if (ret != 0) { - return -3; + retcode -= 16; } } - return 0; + return retcode; } diff --git a/v10/config.h b/v10/config.h index 67eb71f..2ef3e5c 100644 --- a/v10/config.h +++ b/v10/config.h @@ -35,7 +35,6 @@ #include "extdrv/status_led.h" #include "extdrv/max31855_thermocouple.h" -#include "extdrv/ws2812.h" #include "lib/stdio.h" @@ -50,13 +49,14 @@ * Default values are defined within config.c * * Meaning of fields : - * ext_source_power_limit : - * Maximum power which can be used from the external (paid) power source, specified in kW/h + * grid_power_limit : + * Maximum power which can be used from the external (paid) power source, specified in kWatt * sunny_days_prod_value : * in milli Amps - * force_heater_temp : + * enter_force_heater_temp : + * temperature bellow which the system enters auto forced heating mode * degrees centigrade - * target_forced_heater_temp : + * auto_forced_target_heater_temp : * * auto_forced_mode_value : * @@ -80,22 +80,33 @@ struct scialys_config { uint8_t conf_version; uint8_t checksum; - uint16_t ext_source_power_limit; /* specified in kW/h */ - uint16_t sunny_days_prod_value; /* in milli Amps */ - uint16_t force_heater_temp; /* degrees centigrade */ - uint16_t target_forced_heater_temp; - uint16_t auto_forced_mode_value; + /* Config limits */ + uint16_t grid_power_limit; /* specified in kWatt */ + uint16_t source_power_max; /* specified in Watt */ + uint16_t load_power_max; /* specified in Watt */ + uint16_t conf_max_temp; /* degrees centigrade (0 - 90°C) */ + uint16_t load_type; /* LOAD_TYPE_AC or LOAD_TYPE_DC */ + uint16_t force_command_value; /* % : 0 - 100 */ + /* Manual Force limits */ + uint16_t enter_force_heater_temp; /* degrees centigrade (0 - 90°C) */ + uint16_t auto_forced_target_heater_temp; /* degrees centigrade (0 - 90°C) */ + uint16_t auto_forced_mode_value; /* % : 0 - 100 */ uint16_t forced_heater_delay; uint16_t forced_heater_duration; - uint16_t manual_forced_mode_value; - uint16_t manual_target_heater_temp; + uint16_t manual_forced_mode_value; /* % : 0 - 100 */ + uint16_t manual_target_heater_temp; /* degrees centigrade (0 - 90°C) */ uint16_t manual_activation_duration; - uint8_t manual_force_type; - uint8_t never_force; + uint8_t manual_force_type; /* Off, Min, Max */ + uint8_t never_force; /* 0 or 1 */ + /* Other */ uint16_t config_ok; } __attribute__((packed)); extern struct scialys_config sc_conf; +extern uint32_t sunny_days_prod_value; + +/* Check that current config is valid */ +void check_config(void); /* Read main configuration from internal user flash - or set to default one */ void read_scialys_main_config(void); diff --git a/v10/interface.c b/v10/interface.c index 3ebc2da..c3da842 100644 --- a/v10/interface.c +++ b/v10/interface.c @@ -154,6 +154,14 @@ void button_callback(uint32_t gpio) } } +#define SCIALYS_WS2812_NB_LEDS 2 +uint8_t ws2812_leds_data[SCIALYS_WS2812_NB_LEDS * 3]; +struct ws2812_conf ws2812_leds = { + .nb_leds = SCIALYS_WS2812_NB_LEDS, + .led_data = ws2812_leds_data, + .inverted = 0, +}; + int interface_config(uint32_t uart) { /* Buttons inputs on front panel */ @@ -165,7 +173,7 @@ int interface_config(uint32_t uart) set_gpio_callback(button_callback, &button_ok, EDGE_RISING); /* WS2812B Leds on display board */ - ws2812_config(&ws2812_data_out_pin); + ws2812_config(&ws2812_leds, &ws2812_data_out_pin); /* Configure and start display */ config_gpio(&oled_reset, 0, GPIO_DIR_OUT, 1); /* Release reset signal */ @@ -173,8 +181,8 @@ int interface_config(uint32_t uart) erase_screen_content(); ssd130x_display_full_screen(&display); - ws2812_set_pixel(0, 0x05, 0x15, 0x08); - ws2812_send_frame(0); + ws2812_set_pixel(&ws2812_leds, 0, 0x05, 0x15, 0x08); + ws2812_send_frame(&ws2812_leds, 0); uprintf(uart, "Interface config OK\n"); @@ -196,53 +204,57 @@ volatile int manual_activation_request = 0; enum menu_list { MAIN_MENU, - MANUAL_MODE, + FORCE_MODE, DATE_CONFIG, LIMITS, - FUNCTIONS, - TEST_MODE, + RESET_CONFIG, SAVE_CONFIG, + TEST_MODE, NB_MENU, /* This one must be the last */ }; static const char* menu_titles[] = { [MAIN_MENU] = "Menu principal", - [MANUAL_MODE] = "Marche Forcee", + [FORCE_MODE] = "Marche Forcee", [DATE_CONFIG] = "Regl. Heure", - [LIMITS] = "Limites", - [FUNCTIONS] = "Reglages", - [TEST_MODE] = "Test mode", + [LIMITS] = "Regl. Limites", [SAVE_CONFIG] = "Save config", + [RESET_CONFIG] = "Reset config", + [TEST_MODE] = "Test mode", }; static uint8_t current_menu = MAIN_MENU; -static uint8_t current_entry = MANUAL_MODE; +static uint8_t current_entry = FORCE_MODE; -enum func_menu_list { - FUNC_LOAD_TYPE, - FUNC_CMD_TYPE, - FUNC_NB_MENU, /* This one must be the last */ +enum force_mode_list { + MANUAL_FORCE_MODE, + AUTO_FORCE_MODE, + FORCE_NB_MENU, /* This one must be the last */ }; -static const char* func_modes_titles[] = { - [FUNC_LOAD_TYPE] = "Load Type", - [FUNC_CMD_TYPE] = "CMD type", +static const char* force_modes_titles[] = { + [MANUAL_FORCE_MODE] = "Manuelle", + [AUTO_FORCE_MODE] = "Automatique", }; -static uint8_t func_cur_menu = FUNC_LOAD_TYPE; -static uint8_t func_cur_entry = FUNC_LOAD_TYPE; +static uint8_t force_cur_menu = MANUAL_FORCE_MODE; +static uint8_t force_cur_entry = MANUAL_FORCE_MODE; enum limits_menu_list { - TEMP_FORCED_START, - TEMP_FORCED_TARGET, + TEMP_MAX, + PMAX_GRID, + PMAX_PROD, + PMAX_CONSO, + LOAD_TYPE, FORCED_MODE_VAL, - SUNNY_DAY_VALUE, LIM_NB_MENU, /* This one must be the last */ }; static const char* limits_modes_titles[] = { - [TEMP_FORCED_START] = "Water Min", - [TEMP_FORCED_TARGET] = "Water Target", + [TEMP_MAX] = "Temp Max", + [PMAX_GRID] = "Pmax Abon.", + [PMAX_PROD] = "Pmax Prod.", + [PMAX_CONSO] = "P Charge", + [LOAD_TYPE] = "Type Charge", [FORCED_MODE_VAL] = "Force Val", - [SUNNY_DAY_VALUE] = "Sun Prod", }; -static uint8_t limits_cur_menu = TEMP_FORCED_START; -static uint8_t limits_cur_entry = TEMP_FORCED_START; +static uint8_t limits_cur_menu = TEMP_MAX; +static uint8_t limits_cur_entry = TEMP_MAX; enum test_menu_list { TEST_FAN, @@ -287,9 +299,9 @@ void config_interface_handle(void) int i = 0; for (i = 1; i < NB_MENU; i++) { if (i != current_entry) { - display_line(i + 1, 3, menu_titles[i]); + display_line(i + 1, 2, menu_titles[i]); } else { - snprintf(line, DISP_LLEN, " ->%s", menu_titles[i]); + snprintf(line, DISP_LLEN, " >%s", menu_titles[i]); display_line(i + 1, 0, line); } } @@ -316,12 +328,12 @@ void config_interface_handle(void) case DATE_CONFIG: { static uint8_t date_idx = 0; struct rtc_time now; - snprintf(line, DISP_LLEN, "^"); + snprintf(line, DISP_LLEN, "%c", 0x60); display_line(3, 6 + (date_idx * 3), line); rtc_pcf85363_time_read(&rtc_conf, &now); snprintf(line, DISP_LLEN, "%02xh%02x:%02x", now.hour, now.min, now.sec); display_line(4, 6, line); - snprintf(line, DISP_LLEN, "V"); + snprintf(line, DISP_LLEN, "%c", 0x7F); display_line(5, 6 + (date_idx * 3), line); if ((button & BUTTON_RIGHT) && (date_idx < 2)) { date_idx++; @@ -364,7 +376,7 @@ void config_interface_handle(void) if (i != limits_cur_entry) { display_line(i + 2, 3, limits_modes_titles[i]); } else { - snprintf(line, DISP_LLEN, " ->%s", limits_modes_titles[i]); + snprintf(line, DISP_LLEN, " >%s", limits_modes_titles[i]); display_line(i + 2, 0, line); } } @@ -387,34 +399,78 @@ void config_interface_handle(void) sub_menu_level = 0; current_menu = MAIN_MENU; } - } else { + } else { /* sub_menu_level == 2 */ + display_line(1, 1, limits_modes_titles[limits_cur_menu]); + switch (limits_cur_menu) { + case TEMP_MAX: + snprintf(line, DISP_LLEN, " %c", 0x60); + display_line(3, 1, line); + snprintf(line, DISP_LLEN, "Abs. max: %d %cC", sc_conf.conf_max_temp / 100, 0x24); + display_line(4, 1, line); + snprintf(line, DISP_LLEN, " %c", 0x7f); + display_line(5, 1, line); + if (button & BUTTON_UP) { + if (sc_conf.conf_max_temp <= 8500) { + sc_conf.conf_max_temp += 500; + } else { + sc_conf.conf_max_temp = 9000; + } + } + if (button & BUTTON_DOWN) { + if (sc_conf.conf_max_temp > 500) { + sc_conf.conf_max_temp -= 500; + } else { + sc_conf.conf_max_temp = 0; + } + } + if (button & BUTTON_LEFT) { + sub_menu_level = 1; + } + if (button & BUTTON_OK) { + sub_menu_level = 0; + current_menu = MAIN_MENU; + } + break; + case FORCED_MODE_VAL: + break; + case PMAX_GRID: + /* remember to update max_intensity */ + break; + case PMAX_PROD: + /* remember to update sunny_days_prod_value */ + break; + case PMAX_CONSO: + break; + case LOAD_TYPE: + break; + } } } break; - case FUNCTIONS: { + case FORCE_MODE: { if (sub_menu_level == 1) { int i = 0; - for (i = 0; i < FUNC_NB_MENU; i++) { - if (i != func_cur_entry) { - display_line(i + 2, 3, func_modes_titles[i]); + for (i = 0; i < FORCE_NB_MENU; i++) { + if (i != force_cur_entry) { + display_line(i + 2, 3, force_modes_titles[i]); } else { - snprintf(line, DISP_LLEN, " ->%s", func_modes_titles[i]); + snprintf(line, DISP_LLEN, " ->%s", force_modes_titles[i]); display_line(i + 2, 0, line); } } if (button & BUTTON_UP) { - func_cur_entry -= 1; + force_cur_entry -= 1; } if (button & BUTTON_DOWN) { - func_cur_entry += 1; + force_cur_entry += 1; } - if (func_cur_entry >= FUNC_NB_MENU) { - func_cur_entry = 0; - } else if (func_cur_entry == 0xFF) { - func_cur_entry = FUNC_NB_MENU - 1; + if (force_cur_entry >= FORCE_NB_MENU) { + force_cur_entry = 0; + } else if (force_cur_entry == 0xFF) { + force_cur_entry = FORCE_NB_MENU - 1; } if (button & (BUTTON_OK | BUTTON_RIGHT)) { - func_cur_menu = func_cur_entry; + force_cur_menu = force_cur_entry; sub_menu_level = 2; } if (button & BUTTON_LEFT) { @@ -465,7 +521,7 @@ void config_interface_handle(void) if (force_cmd >= 0) { force_cmd = -1; } else { - force_cmd = 0; + force_cmd = 50; } default: break; @@ -478,12 +534,55 @@ void config_interface_handle(void) } break; case SAVE_CONFIG: { - user_flash_update(); + snprintf(line, DISP_LLEN, "Sauver config ?"); + display_line(2, 1, line); + snprintf(line, DISP_LLEN, "Valider = OK"); + display_line(5, 1, line); + snprintf(line, DISP_LLEN, "Gauche = Annul"); + display_line(6, 1, line); + if (button & BUTTON_LEFT) { + sub_menu_level = 0; + current_menu = MAIN_MENU; + } + if (button & BUTTON_OK) { + int ret = 0; + erase_screen_content(); + snprintf(line, DISP_LLEN, "Saving ..."); + display_line(4, 2, line); + ssd130x_display_full_screen(&display); + ret = user_flash_update(); + uprintf(UART0, "\nFlash update from menu: %d\n", ret); + msleep(1500); + sub_menu_level = 0; + current_menu = MAIN_MENU; + } + } + break; + case RESET_CONFIG: { + snprintf(line, DISP_LLEN, "Efface Config ?"); + display_line(2, 1, line); + snprintf(line, DISP_LLEN, "Valider = OK"); + display_line(5, 1, line); + snprintf(line, DISP_LLEN, "Gauche = Annul"); + display_line(6, 1, line); + if (button & BUTTON_LEFT) { + sub_menu_level = 0; + current_menu = MAIN_MENU; + } + if (button & BUTTON_OK) { + erase_screen_content(); + snprintf(line, DISP_LLEN, "Chargement ..."); + display_line(4, 8, line); + ssd130x_display_full_screen(&display); + sc_conf.conf_version = 0x00; + check_config(); + uprintf(UART0, "\nSystem defaults reloaded from menu\n"); + msleep(500); + sub_menu_level = 0; + current_menu = MAIN_MENU; + } } break; - case MANUAL_MODE: - manual_activation_request = -1; - /* Fallback */ default: interface_mode = MODE_RUN; current_menu = MAIN_MENU; @@ -548,7 +647,7 @@ void interface_update(char heat_mode) display_line(0, 0, line); /* Display info */ - snprintf(line, DISP_LLEN, "Water:% 2d.%03d %cC", (water_centi_degrees / 100), (abs_centi % 100), 0x1F); + snprintf(line, DISP_LLEN, "Water:% 2d.%03d %cC", (water_centi_degrees / 100), (abs_centi % 100), 0x24); display_line(2, 0, line); snprintf(line, DISP_LLEN, "Prod :% 2d,%03dA", (solar_prod_value / 1000), ((solar_prod_value % 1000) / 10)); display_line(3, 0, line); @@ -565,9 +664,9 @@ void interface_update(char heat_mode) /* Update RGB leds */ /* FIXME : use for error signal */ - ws2812_set_pixel(0, (home_conso_value / 2000), (solar_prod_value / 2000), 0); - ws2812_set_pixel(1, 0, 0, command_val); - ws2812_send_frame(0); + ws2812_set_pixel(&ws2812_leds, 0, (home_conso_value / 2000), (solar_prod_value / 2000), 0); + ws2812_set_pixel(&ws2812_leds, 1, 0, 0, command_val); + ws2812_send_frame(&ws2812_leds, 0); } else { /* Config mode. Mode entered by button action, which implies that interface board is present. */ config_interface_handle(); diff --git a/v10/main.c b/v10/main.c index 81d81e1..173a17e 100644 --- a/v10/main.c +++ b/v10/main.c @@ -45,7 +45,7 @@ #define T_MULT (3600 * 1000 / DEC_PERIOD) /* Max water temperature. Internal protection which cannot be overriden by configuration */ -#define MAX_WATER_TEMP (90 * 100) /* Hundredth of degrees C : 90°C */ +#define ABSOLUTE_MAX_WATER_TEMP (90 * 100) /* Hundredth of degrees C : 90°C */ /* Internal system max temperature : turn off heating when reached */ #define MAX_INTERNAL_TEMP (80 * 10) /* Tenth of degrees C : 80°C */ @@ -78,8 +78,13 @@ enum modes { /* Water and internaltemperature */ int water_centi_degrees = 0; -int deci_degrees_power = 0; -int deci_degrees_disp = 0; + +/* Set to ABSOLUTE_MAX_WATER_TEMP - 1.5°C when enbling max temp hysteresis */ +int max_temp_hysteresys = 0; + +/* Internal temperatures */ +int deci_degrees_power = 0; /* Power board sensor */ +int deci_degrees_disp = 0; /* Display board sensor */ /* Value in mA computed upon startup from config ext_source_power_limit */ static int32_t max_intensity = 0; @@ -258,10 +263,19 @@ void handle_cmd_update(uint32_t curent_tick) goto cmd_update_end; } - /* Water max temperature protection */ - if (water_centi_degrees > MAX_WATER_TEMP) { + /* Water max temperature protection with hysteresys */ + if ((water_centi_degrees > ABSOLUTE_MAX_WATER_TEMP) || + (water_centi_degrees > sc_conf.conf_max_temp) || + (water_centi_degrees > max_temp_hysteresys)) { cmd = 0; + max_temp_hysteresys = (ABSOLUTE_MAX_WATER_TEMP - 150); /* 1.5 °C */ + if (max_temp_hysteresys > sc_conf.conf_max_temp) { + max_temp_hysteresys = (sc_conf.conf_max_temp - 150); /* still 1.5°C */ + } goto cmd_update_end; + } else if (water_centi_degrees < max_temp_hysteresys) { + /* Remove Hysteresys */ + max_temp_hysteresys = ABSOLUTE_MAX_WATER_TEMP; } /* Forced over-voltage protection or test mode */ @@ -393,14 +407,14 @@ void mode_update(uint32_t unused) mode = heat; /* Need to enter Forced heating mode ? */ - if (water_centi_degrees < sc_conf.force_heater_temp) { + if (water_centi_degrees < sc_conf.enter_force_heater_temp) { if (forced_heater_mode == 0) { msg = "Water temp low, entering forced mode\n"; forced_heater_mode = 1; } status_led(red_on); mode = forced; - } else if ((water_centi_degrees > sc_conf.target_forced_heater_temp) && (forced_heater_mode == 1)) { + } else if ((water_centi_degrees > sc_conf.auto_forced_target_heater_temp) && (forced_heater_mode == 1)) { status_led(red_off); msg = "Water temp OK, forced mode exit\n"; forced_heater_mode = 0; @@ -408,7 +422,7 @@ void mode_update(uint32_t unused) } /* Do not force if there is a lot of sun, it may be enough to heat again soon */ - if ((solar_prod_value > sc_conf.sunny_days_prod_value) && (forced_heater_mode == 1)) { + if ((solar_prod_value > sunny_days_prod_value) && (forced_heater_mode == 1)) { mode = delayed_heat_prod; forced_heater_mode = 0; } @@ -550,13 +564,16 @@ int main(void) board_io_config(); modules_config(); external_config(UART0); + read_scialys_main_config(); - /* Compute max_intensity from config ext_source_power_limit. - * ext_source_power_limit is in kVA, max_intensity in mA */ - max_intensity = sc_conf.ext_source_power_limit * 1000 * 1000 / 230; + /* Compute max_intensity from config grid_power_limit. + * grid_power_limit is in kVA, max_intensity in mA */ + max_intensity = sc_conf.grid_power_limit * 1000 * 1000 / 230; + scialys_systick_and_timers_config(); - uprintf(UART0, "System setup complete. %d\n", -max_intensity); + uprintf(UART0, "System setup complete.\n"); + uprintf(UART0, "Max intensity: %d\n", max_intensity); msleep(500); status_led(green_only); @@ -591,16 +608,28 @@ int main(void) } /* Update water tank temperature */ + #define WTA_NB_VAL 8 /* Choose a multiple of 2 */ + #define WTA_SHIFT 3 /* Set shift according to WTA_NB_VAL */ if (1) { - int ret = 0, old_water_temp = 0; - old_water_temp = water_centi_degrees; - /* Get thermocouple value */ + static int water_centi_average[WTA_NB_VAL]; + static int wta_idx = 0; + int ret = 0, i = 0; + /* Get thermocouple value, store in table only if valid */ ret = max31855_sensor_read(&thermocouple, NULL, &water_centi_degrees); if (ret != 0) { uprintf(UART0, "Water Temp read error : %d\n", ret); - /* Do not act upon iinvalid temp value */ - water_centi_degrees = old_water_temp; + } else { + water_centi_average[wta_idx++] = water_centi_degrees; + if (wta_idx >= WTA_NB_VAL) { + wta_idx = 0; + } + } + water_centi_degrees = 0; + /* Average water tank temperature */ + for (i = 0; i < WTA_NB_VAL; i++) { + water_centi_degrees += water_centi_average[i]; } + water_centi_degrees >>= WTA_SHIFT; } /* Update current mode */ diff --git a/v10/version.h b/v10/version.h index 7eeaa2b..949853a 100644 --- a/v10/version.h +++ b/v10/version.h @@ -1,3 +1,3 @@ #define MODULE_VERSION_STR "v0.10" #define SOFT_VERSION_STR "T" -#define COMPILE_VERSION "36" +#define COMPILE_VERSION "57"