#include "config.h"
#include "interface.h"
#include "comm.h"
+#include "sensors.h"
#include "time.h"
#include "uSD.h"
extern void comm_rx(uint8_t c);
extern void ac_switch_on(uint32_t flags);
extern void zero_cross(uint32_t flags);
-extern void power_track(uint32_t flags);
/* Configure micro-controller internal modules */
void modules_config(void)
extern void handle_cmd_update(uint32_t curent_tick);
-extern void track_isnail_values(uint32_t curent_tick);
extern void handle_dec_request(uint32_t curent_tick);
/* Period (in ms) of the handler for the command value update */
#define CMD_UPD_PERIOD 50
/* RTC and time */
#define RTC_ADDR 0xA2
-/* TMP101 I2C temperature sensor on Power board */
-#define TMP101_ADDR1 0x94 /* Pin Addr0 (pin5 of tmp101) connected to VCC */
-struct tmp101_sensor_config tmp101_sensor_power = {
- .bus_num = I2C0,
- .addr = TMP101_ADDR1,
- .resolution = TMP_RES_ELEVEN_BITS,
-};
-
-/* TMP101 I2C temperature sensor on display board */
-#define TMP101_ADDR0 0x90 /* Pin Addr0 (pin5 of tmp101) connected to GND */
-struct tmp101_sensor_config tmp101_sensor_display = {
- .bus_num = I2C0,
- .addr = TMP101_ADDR0,
- .resolution = TMP_RES_ELEVEN_BITS,
-};
-
-
/* Configure external components */
int external_components_config(uint32_t uart)
{
- int ret = 0;
- int retcode = 0;
-
/* RTC : must be done first to be able to access RTC RAM for uSD init */
scialys_time_config(I2C0, RTC_ADDR);
scialys_time_init_check(uart);
max31855_sensor_config(&thermocouple);
/* TMP101 sensor config on power board */
- power_board_present = 1;
- ret = tmp101_sensor_config(&tmp101_sensor_power);
- if (ret != 0) {
- uprintf(uart, "Temp config error on power board: %d\n", ret);
- power_board_present = 0;
- retcode -= 1;
- } else {
- ret = tmp101_sensor_set_continuous_conversion(&tmp101_sensor_power);
- if (ret != 0) {
- uprintf(uart, "Temp config part 2 error on power board: %d\n", ret);
- power_board_present = 0;
- retcode -= 2;
- }
- }
+ power_board_present = power_board_temp_sensor_config(uart);
/* TMP101 sensor config on display board */
- ret = tmp101_sensor_config(&tmp101_sensor_display);
- 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 part 2 error on display board: %d\n", ret);
- interface_board_present = 0;
- retcode -= 8;
- } else {
- interface_board_present = 1;
- }
- }
+ interface_board_present = interface_board_temp_sensor_config(uart);
/* Configure interface board if present */
if (interface_board_present == 1) {
- ret = interface_config(uart);
- if (ret != 0) {
- retcode -= 16;
- }
+ interface_config(uart);
}
- return retcode;
+ return 0;
}
#include "config.h"
#include "interface.h"
#include "time.h"
+#include "sensors.h"
#include "uSD.h"
/* Max water temperature. Internal protection which cannot be overriden by configuration */
#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 */
/* Number of main loops during which we keep the mosfets ON in order to keep them safe */
#define OVERVOLTAGE_PROTECTION_CYCLES 100
uint32_t forced_heater_time = 0; /* Flag and counter */
uint8_t manual_forced_heater = 0; /* Flag only */
int manual_activation_request = 0; /* Flag and counter */
-uint8_t error_shutdown = 0; /* Flag only */
+int8_t internal_temp_error_shutdown = 0; /* Flag and error code */
#define EXTERNAL_DISABLE_FORCE 0 /* Input is pulled low when external disable is ON */
uint8_t external_disable = 0; /* Flag only */
-uint8_t temp_shutdown = 0; /* Flag only */
+uint8_t mosfet_temp_shutdown = 0; /* Flag only */
uint8_t overvoltage = 0; /* Flag and counter. Used to create a delay when overvoltage is detected,
set to OVERVOLTAGE_PROTECTION_CYCLES and decreases to 0 */
/* Water temperature */
int water_centi_degrees = 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 */
+/* Set to ABSOLUTE_MAX_WATER_TEMP - 1.5°C when enbling max temp hysteresis */
+int max_temp_hysteresys = 0;
+
/* Value in mA computed upon startup from config ext_source_power_limit */
int32_t max_intensity = 0;
}
-/***************************************************************************** */
-/* Power Tracking */
-
-/* Average value computed on the last "NB_VAL" ADC values */
-uint32_t solar_prod_value = 0;
-uint32_t home_conso_value = 0;
-#define NB_VAL 4 /* MUST be a power of 2 */
-#define NB_SHIFT 2
-
-/*
- * Track power production and usage
- * These are obtained by reading the Tore outputs (i-Snail output through ADC 0 and 1)
- */
-void track_isnail_values(uint32_t curent_tick)
-{
- static uint8_t idx = 0;
- static uint16_t solar[NB_VAL];
- static uint16_t home[NB_VAL];
- uint16_t snapval_solar = 0;
- uint16_t snapval_home = 0;
- int cnt, sum_solar = 0, sum_home = 0;
-
- /* Get new values */
- adc_get_value(&snapval_solar, LPC_ADC(1));
- adc_get_value(&snapval_home, LPC_ADC(0));
-
- /* Store values */
- solar[idx] = snapval_solar;
- home[idx] = snapval_home;
- idx++;
- if (idx >= NB_VAL) {
- idx = 0;
- }
-
- /* Compute average value */
- for (cnt = 0; cnt < NB_VAL; cnt++) {
- sum_solar += solar[cnt];
- sum_home += home[cnt];
- }
-
- /* Convert to mA value.
- * ADC range is 0 to 1024 - approx 3.2mV / ADC step
- * Coil convertion is 1000mA -> 50mV : multily mV value by 20 to get mA value
- * x * 3.2 * 20 == x * 32 * 2 == x << 6
- * Increment is 64mA / ADC step */
- solar_prod_value = sum_solar << (6 - NB_SHIFT);
- home_conso_value = sum_home << (6 - NB_SHIFT);
-}
-
-
-/*
- * Track power used by load.
- * These are obtained from ACS711 through ADC 2
- * ADC values are between 0 and 1023, no load value is at about 520
- */
-#define TRACK_MAX 1
-#define TRACK_MIN 0
-static volatile uint16_t load_power_highest = 520;
-static volatile uint16_t load_power_lowest = 520;
-
-void power_track(uint32_t flags)
-{
- /* Start tracking the higest value */
- static int tracking = TRACK_MAX;
- static uint16_t last_value = 0;
- uint16_t val = 0;
-
- /* Get load power usage */
- adc_get_value(&val, LPC_ADC(2));
-
- /* Four possibilities :
- * tracking max and value increasing : nothing to do
- * tracking max and value decreasing : we found the max, store it and change tracking
- * tracking min and value decreasing : nothing to do
- * tracking min and value increasing : we found the min, store it and change tracking
- */
- if (tracking == TRACK_MAX) {
- if (last_value > val) {
- /* Found max */
- load_power_highest = last_value;
- tracking = TRACK_MIN;
- }
- } else {
- if (last_value < val) {
- /* Found min */
- load_power_lowest = last_value;
- tracking = TRACK_MAX;
- }
- }
- last_value = val;
-}
-
/***************************************************************************** */
/* AC control */
}
/* Unable to read internal temperature : turn off heating */
- if ((temp_shutdown == 1) || (error_shutdown == 1)) {
+ if ((mosfet_temp_shutdown == 1) || (internal_temp_error_shutdown < 0)) {
cmd = 0;
force_fan = 1;
goto cmd_update_end;
switch (sc_conf.auto_force_type) {
case FORCE_TYPE_TIMER:
case FORCE_TYPE_TARGET:
+ if (water_centi_degrees > sc_conf.auto_forced_target_heater_temp) {
+ exit_forced = 1;
+ }
+ break;
case FORCE_TYPE_MIN:
+ if (water_centi_degrees > sc_conf.auto_forced_target_heater_temp) {
+ exit_forced = 1;
+ }
case FORCE_TYPE_MAX:
- if ((water_centi_degrees > sc_conf.auto_forced_target_heater_temp) && ()) {
+ if (water_centi_degrees > sc_conf.auto_forced_target_heater_temp) {
+ exit_forced = 1;
}
}
if (exit_forced == 1) {
}
/* Get Over-Temperature information */
- temp_shutdown = (gpio_read(overtemperature_pin) ? 0 : 1);
+ mosfet_temp_shutdown = (gpio_read(overtemperature_pin) ? 0 : 1);
/* Update Over-Voltage information */
if (overvoltage > 0) {
uint8_t ov_tmp = (gpio_read(overvoltage_pin) ? 0 : 1);
/***************************************************************************** */
-void update_internal_temp(void)
-{
- /* Get internal temperatures */
- ret = temp_read(UART0, &deci_degrees_disp, &deci_degrees_power);
- if (ret != CONV_OK) {
- force_fan = 1;
- }
- /* Internal temperature protection */
- if ((deci_degrees_power > MAX_INTERNAL_TEMP) || (deci_degrees_disp > MAX_INTERNAL_TEMP)) {
- error_shutdown = 1;
- uprintf(UART0, "Error shutdown !\n");
- } else if ((deci_degrees_power < ((MAX_INTERNAL_TEMP) / 2)) &&
- (deci_degrees_disp < ((MAX_INTERNAL_TEMP) / 2))) {
- error_shutdown = 0;
- }
-}
-
/* Store data on uSD once every N seconds.
* Note : Once every second requires about 1Go per year.
/* Each flag is set if seen once within the interval */
data.flags |= (fan_on ? 1 : 0) | (force_fan << 1);
- data.flags |= (error_shutdown << 2) | (temp_shutdown << 3) | (overvoltage << 4);
+ data.flags |= (((internal_temp_error_shutdown < 0) ? 1 : 0) << 2);
+ data.flags |= (mosfet_temp_shutdown << 3) | (overvoltage << 4);
data.flags |= (external_disable << 5);
data.flags |= (forced_heater_mode << 6) | (manual_activation_request << 7);
{
uint32_t loop = 0;
uint32_t last_tick_update = 0, cur_tick = 0;
- int ret = 0;
/* Order is important here */
system_init();
}
/* Update internal temperatures */
- update_internal_temp();
+ internal_temp_error_shutdown = update_internal_temp(UART0, &deci_degrees_disp, &deci_degrees_power);
/* Update water tank temperature */
- water_centi_degrees = water_temp_update();
+ water_centi_degrees = water_temp_update(UART0);
/* Update current mode */
mode_update();
/* Store data on uSD once every N seconds. */
store_data(cur_tick);
- /* Debug */
+ /* Data Log */
if (1) {
external_disable |= linky_disable;
uprintf(UART0, "#%c:%d:%d:%d:%d:%d:%d:",
uprintf(UART0, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d$\n",
load_power_lowest, load_power_highest,
zc_cnt, command_val, act_cmd, fan_on, force_fan,
- error_shutdown, temp_shutdown, overvoltage,
+ internal_temp_error_shutdown, mosfet_temp_shutdown, overvoltage,
external_disable, forced_heater_mode, manual_activation_request);
if (msg != NULL) {
uprintf(UART0, (char*)msg);
/***************************************************************************** */
/* External components */
+/* TMP101 I2C temperature sensor on Power board */
+#define TMP101_ADDR1 0x94 /* Pin Addr0 (pin5 of tmp101) connected to VCC */
+static struct tmp101_sensor_config tmp101_sensor_power = {
+ .bus_num = I2C0,
+ .addr = TMP101_ADDR1,
+ .resolution = TMP_RES_ELEVEN_BITS,
+};
+
+/* TMP101 I2C temperature sensor on display board */
+#define TMP101_ADDR0 0x90 /* Pin Addr0 (pin5 of tmp101) connected to GND */
+static struct tmp101_sensor_config tmp101_sensor_display = {
+ .bus_num = I2C0,
+ .addr = TMP101_ADDR0,
+ .resolution = TMP_RES_ELEVEN_BITS,
+};
+
+
+
extern uint8_t interface_board_present ;
extern uint8_t power_board_present;
-int temp_read(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power)
+/*
+ * Read both TMP101 sensors (if present)
+ * Return value :
+ * -2 if a temp sensor is missing
+ * -1 if any temperature is above MAX_INTERNAL_TEMP
+ * 1 if any temperature is above (MAX_INTERNAL_TEMP / 2)
+ * 0 if all temperatures are bellow (MAX_INTERNAL_TEMP / 2)
+ */
+int8_t update_internal_temp(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power)
{
int ret = 0;
int conv = 0;
uprintf(uart, "TMP101 read error on power board : %d\n", ret);
}
}
- return conv;
+
+ if (conv != CONV_OK) {
+ return -2;
+ }
+ /* Internal temperature protection */
+ if ((*deci_degrees_power > MAX_INTERNAL_TEMP) || (*deci_degrees_disp > MAX_INTERNAL_TEMP)) {
+ uprintf(uart, "Internal temp error shutdown !\n");
+ return -1;
+ } else if ((*deci_degrees_power > ((MAX_INTERNAL_TEMP) / 2)) ||
+ (*deci_degrees_disp > ((MAX_INTERNAL_TEMP) / 2))) {
+ return 1;
+ }
+ return 0;
+}
+
+
+/* TMP101 sensor config on power board */
+int power_board_temp_sensor_config(uint32_t uart)
+{
+ int ret = 0;
+
+ ret = tmp101_sensor_config(&tmp101_sensor_power);
+ if (ret != 0) {
+ uprintf(uart, "Temp config error on power board: %d\n", ret);
+ return 0;
+ } else {
+ ret = tmp101_sensor_set_continuous_conversion(&tmp101_sensor_power);
+ if (ret != 0) {
+ uprintf(uart, "Temp config part 2 error on power board: %d\n", ret);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* TMP101 sensor config on display board */
+int interface_board_temp_sensor_config(uint32_t uart)
+{
+ int ret = 0;
+
+ ret = tmp101_sensor_config(&tmp101_sensor_display);
+ if (ret != 0) {
+ uprintf(uart, "Temp config error on display board: %d\n", ret);
+ return 0;
+ } else {
+ ret = tmp101_sensor_set_continuous_conversion(&tmp101_sensor_display);
+ if (ret != 0) {
+ uprintf(uart, "Temp config part 2 error on display board: %d\n", ret);
+ return 0;
+ }
+ }
+ return 1;
}
/***************************************************************************** */
/* Update water tank temperature */
-
-int water_temp_update(void)
+int water_temp_update(uint32_t uart)
{
static int water_centi_average[WTA_NB_VAL];
static int wta_idx = 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);
+ uprintf(uart, "Water Temp read error : %d\n", ret);
} else {
water_centi_average[wta_idx++] = water_centi_degrees;
if (wta_idx >= WTA_NB_VAL) {
}
+/***************************************************************************** */
+/* Power Tracking */
+
+
+/*
+ * Track power production and usage
+ * These are obtained by reading the Tore outputs (i-Snail output through ADC 0 and 1)
+ * Average value computed on the last "NB_VAL" ADC values
+ */
+volatile uint32_t solar_prod_value = 0;
+volatile uint32_t home_conso_value = 0;
+
+void track_isnail_values(uint32_t curent_tick)
+{
+ static uint8_t idx = 0;
+ static uint16_t solar[NB_VAL];
+ static uint16_t home[NB_VAL];
+ uint16_t snapval_solar = 0;
+ uint16_t snapval_home = 0;
+ int cnt, sum_solar = 0, sum_home = 0;
+
+ /* Get new values */
+ adc_get_value(&snapval_solar, LPC_ADC(1));
+ adc_get_value(&snapval_home, LPC_ADC(0));
+
+ /* Store values */
+ solar[idx] = snapval_solar;
+ home[idx] = snapval_home;
+ idx++;
+ if (idx >= NB_VAL) {
+ idx = 0;
+ }
+
+ /* Compute average value */
+ for (cnt = 0; cnt < NB_VAL; cnt++) {
+ sum_solar += solar[cnt];
+ sum_home += home[cnt];
+ }
+
+ /* Convert to mA value.
+ * ADC range is 0 to 1024 - approx 3.2mV / ADC step
+ * Coil convertion is 1000mA -> 50mV : multily mV value by 20 to get mA value
+ * x * 3.2 * 20 == x * 32 * 2 == x << 6
+ * Increment is 64mA / ADC step */
+ solar_prod_value = sum_solar << (6 - NB_SHIFT);
+ home_conso_value = sum_home << (6 - NB_SHIFT);
+}
+
+
+/*
+ * Track power used by load.
+ * These are obtained from ACS711 through ADC 2
+ * ADC values are between 0 and 1023, no load value is at about 516
+ */
+volatile uint16_t load_power_highest = 516;
+volatile uint16_t load_power_lowest = 516;
+
+void power_track(uint32_t flags)
+{
+ /* Start tracking the higest value */
+ static int tracking = TRACK_MAX;
+ static uint16_t last_value = 0;
+ uint16_t val = 0;
+
+ /* Get load power usage */
+ adc_get_value(&val, LPC_ADC(2));
+
+ /* Four possibilities :
+ * tracking max and value increasing : nothing to do
+ * tracking max and value decreasing : we found the max, store it and change tracking
+ * tracking min and value decreasing : nothing to do
+ * tracking min and value increasing : we found the min, store it and change tracking
+ */
+ if (tracking == TRACK_MAX) {
+ if (last_value > val) {
+ /* Found max */
+ load_power_highest = last_value;
+ tracking = TRACK_MIN;
+ }
+ } else {
+ if (last_value < val) {
+ /* Found min */
+ load_power_lowest = last_value;
+ tracking = TRACK_MAX;
+ }
+ }
+ last_value = val;
+}
+
+
/***************************************************************************** */
/* Internal Temperature sensors */
+/* Internal system max temperature : turn off heating when reached */
+#define MAX_INTERNAL_TEMP (80 * 10) /* Tenth of degrees C : 80°C */
+
+/*
+ * Read both TMP101 sensors (if present)
+ * Return value :
+ * -2 if a temp sensor is missing
+ * -1 if any temperature is above MAX_INTERNAL_TEMP
+ * 1 if any temperature is above (MAX_INTERNAL_TEMP / 2)
+ * 0 if all temperatures are bellow (MAX_INTERNAL_TEMP / 2)
+ */
#define CONV_DISPLAY_OK (0x01 << 0)
#define CONV_POWER_OK (0x01 << 1)
#define CONV_OK (CONV_POWER_OK | CONV_DISPLAY_OK)
-int temp_read(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power);
+int8_t update_internal_temp(uint32_t uart, int* deci_degrees_disp, int* deci_degrees_power);
+
+/* TMP101 sensor config on power board */
+int power_board_temp_sensor_config(uint32_t uart);
+/* TMP101 sensor config on display board */
+int interface_board_temp_sensor_config(uint32_t uart);
/***************************************************************************** */
/* 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 */
-int water_temp_update(void);
+int water_temp_update(uint32_t uart);
+/***************************************************************************** */
+/* Power Tracking */
+/*
+ * Track power production and usage
+ * These are obtained by reading the Tore outputs (i-Snail output through ADC 0 and 1)
+ * Average value computed on the last "NB_VAL" ADC values
+ */
+extern volatile uint32_t solar_prod_value;
+extern volatile uint32_t home_conso_value;
+#define NB_VAL 4 /* MUST be a power of 2 */
+#define NB_SHIFT 2
+void track_isnail_values(uint32_t curent_tick);
+
+/*
+ * Track power used by load.
+ * These are obtained from ACS711 through ADC 2
+ * ADC values are between 0 and 1023, no load value is at about 516
+ */
+#define TRACK_MAX 1
+#define TRACK_MIN 0
+extern volatile uint16_t load_power_highest;
+extern volatile uint16_t load_power_lowest;
+void power_track(uint32_t flags);
#endif /* SENSORS_H */
-#define MODULE_VERSION_STR "v0.10"
+#define MODULE_VERSION_STR "v0.10.1"
#define SOFT_VERSION_STR "T"
-#define COMPILE_VERSION "66"
+#define COMPILE_VERSION "67"