kopia lustrzana https://github.com/SP8EBC/ParaTNC
modbus-rtu: sensor power control and quality factors adjusted to modbus-rtu com errors, changed value returned from getters when parameters is not conf
rodzic
a54e904efe
commit
6df0aff814
|
@ -5,7 +5,7 @@
|
|||
#include "drivers/serial.h"
|
||||
|
||||
#define SW_VER "DF09"
|
||||
#define SW_DATE "03112020"
|
||||
#define SW_DATE "05112020"
|
||||
|
||||
#define SYSTICK_TICKS_PER_SECONDS 100
|
||||
#define SYSTICK_TICKS_PERIOD 10
|
||||
|
|
|
@ -93,6 +93,8 @@ extern "C"
|
|||
|
||||
void rte_wx_init(void);
|
||||
void rte_wx_update_last_measuremenet_timers(uint16_t measurement_type);
|
||||
void rte_wx_reset_last_measuremenet_timers(uint16_t measurement_type);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
10
src/rte_wx.c
10
src/rte_wx.c
|
@ -84,3 +84,13 @@ void rte_wx_update_last_measuremenet_timers(uint16_t parameter_type) {
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
void rte_wx_reset_last_measuremenet_timers(uint16_t parameter_type) {
|
||||
if (parameter_type == RTE_WX_MEASUREMENT_WIND)
|
||||
wx_last_good_wind_time = 0xFFFFFFFF;
|
||||
else if (parameter_type == RTE_WX_MEASUREMENT_TEMPERATURE)
|
||||
wx_last_good_temperature_time = 0xFFFFFFFF;
|
||||
else {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
134
src/wx_handler.c
134
src/wx_handler.c
|
@ -45,8 +45,7 @@ void wx_get_all_measurements(void) {
|
|||
int8_t j = 0;
|
||||
int32_t i = 0;
|
||||
int32_t return_value = 0;
|
||||
int8_t not_avaliable = 0;
|
||||
int8_t degraded = 0;
|
||||
int8_t modbus_qf = 0;
|
||||
float pressure_average_sum = 0.0f;
|
||||
|
||||
#if defined(_UMB_MASTER) && !defined(_DAVIS_SERIAL) && !defined(_MODBUS_RTU)
|
||||
|
@ -57,10 +56,51 @@ void wx_get_all_measurements(void) {
|
|||
#endif
|
||||
|
||||
#if !defined(_UMB_MASTER) && !defined(_DAVIS_SERIAL) && defined(_MODBUS_RTU)
|
||||
// modbus rtu
|
||||
// modbus rtu TEMPERATURE
|
||||
return_value = rtu_get_temperature(&rte_wx_temperature_average_dallas_valid);
|
||||
|
||||
// if temperature has been uploaded by the modbus sensor correctly
|
||||
if (return_value == MODBUS_RET_OK) {
|
||||
// update the last measurement timestamp to prevent relay clicking
|
||||
rte_wx_update_last_measuremenet_timers(RTE_WX_MEASUREMENT_TEMPERATURE);
|
||||
|
||||
// set the first bit to signalize QF_FULL
|
||||
modbus_qf |= 1;
|
||||
}
|
||||
else if (return_value == MODBUS_RET_DEGRADED) {
|
||||
// update the last measurement timestamp to prevent relay clicking
|
||||
rte_wx_update_last_measuremenet_timers(RTE_WX_MEASUREMENT_TEMPERATURE);
|
||||
|
||||
// set the second bit to signalize QF_DEGRADED
|
||||
modbus_qf |= (1 << 1);
|
||||
}
|
||||
else {
|
||||
// set third bit if there is something wrong (like not avaliable or
|
||||
// not configured
|
||||
modbus_qf |= (1 << 2);
|
||||
}
|
||||
|
||||
// modbus rtu HUMIDITY
|
||||
return_value = rtu_get_humidity(&rte_wx_humidity_valid);
|
||||
|
||||
// do simmilar things but for humidity
|
||||
if (return_value == MODBUS_RET_OK) {
|
||||
modbus_qf |= (1 << 3);
|
||||
}
|
||||
else {
|
||||
modbus_qf |= (1 << 4);
|
||||
}
|
||||
|
||||
// modbus rtu PRESSURE
|
||||
return_value = rtu_get_pressure(&rte_wx_pressure_valid);
|
||||
|
||||
// do simmilar things but for pressure
|
||||
if (return_value == MODBUS_RET_OK) {
|
||||
modbus_qf |= (1 << 5);
|
||||
}
|
||||
else {
|
||||
modbus_qf |= (1 << 6);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (!defined(_UMB_MASTER) && !defined(_DAVIS_SERIAL) && !defined(_MODBUS_RTU) && defined (_SENSOR_MS5611)) || (defined (_SENSOR_MS5611) && defined(_INTERNAL_AS_BACKUP))
|
||||
|
@ -229,6 +269,48 @@ void wx_get_all_measurements(void) {
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(_MODBUS_RTU)
|
||||
|
||||
// unify quality factor across Modbus-RTU sensor and embedded
|
||||
// ones.
|
||||
|
||||
// BME280 (or MS5611) has a prioryty over the Modbus-RTU
|
||||
if (rte_wx_bme280_qf == BME280_QF_NOT_AVAILABLE ||
|
||||
rte_wx_bme280_qf == BME280_QF_UKNOWN)
|
||||
{
|
||||
// if an internal sensor is not responding check the result of modbus RTU
|
||||
// this is an a little bit of complicated case as BME280 is a pressure
|
||||
// and humidity sensor at once, so changing this QF will also influence
|
||||
// the pressure one, but at this point we might agree that we won't use
|
||||
// BME280 and external, RTU pressure sensor as it would make no sense to do so
|
||||
if ((modbus_qf & (1 << 3)) > 0) {
|
||||
rte_wx_bme280_qf = BME280_QF_FULL;
|
||||
}
|
||||
else {
|
||||
rte_wx_bme280_qf = BME280_QF_UKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// Dallas temperature qualiy factor
|
||||
if (rte_wx_error_dallas_qf == DALLAS_QF_NOT_AVALIABLE) {
|
||||
|
||||
// if an internal sensor is not responding check the result of modbus RTU
|
||||
if ((modbus_qf & 1) > 0) {
|
||||
rte_wx_error_dallas_qf = DALLAS_QF_UNKNOWN;
|
||||
rte_wx_current_dallas_qf = DALLAS_QF_FULL;
|
||||
|
||||
}
|
||||
else if ((modbus_qf & (1 << 1)) > 0) {
|
||||
rte_wx_error_dallas_qf = DALLAS_QF_DEGRADATED;
|
||||
rte_wx_current_dallas_qf = DALLAS_QF_DEGRADATED;
|
||||
}
|
||||
else if ((modbus_qf & (1 << 2)) > 0) {
|
||||
rte_wx_error_dallas_qf = DALLAS_QF_DEGRADATED;
|
||||
rte_wx_current_dallas_qf = DALLAS_QF_NOT_AVALIABLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _METEO
|
||||
// if humidity sensor is idle trigger the communiction & measuremenets
|
||||
if (dht22State == DHT22_STATE_DONE || dht22State == DHT22_STATE_TIMEOUT)
|
||||
|
@ -302,7 +384,7 @@ void wx_pool_anemometer(void) {
|
|||
rte_wx_max_windspeed = umb_get_windgusts();
|
||||
#else
|
||||
|
||||
#if defined(_MODBUS_RTU) && !defined(_RTU_SLAVE_FULL_WIND_DATA)
|
||||
#if defined(_MODBUS_RTU) && defined(_RTU_SLAVE_WIND_DIRECTION_SORUCE) && defined(_RTU_SLAVE_WIND_SPEED_SOURCE) && !defined(_RTU_SLAVE_FULL_WIND_DATA)
|
||||
// get the value from modbus registers
|
||||
modbus_retval = rtu_get_wind_speed(&scaled_windspeed);
|
||||
|
||||
|
@ -322,7 +404,7 @@ void wx_pool_anemometer(void) {
|
|||
scaled_windspeed = analog_anemometer_get_ms_from_pulse(rte_wx_windspeed_pulses);
|
||||
#endif
|
||||
}
|
||||
#elif defined(_MODBUS_RTU) && defined(_RTU_SLAVE_FULL_WIND_DATA)
|
||||
#elif defined(_MODBUS_RTU) && defined(_RTU_SLAVE_WIND_DIRECTION_SORUCE) && defined(_RTU_SLAVE_WIND_SPEED_SOURCE) && defined(_RTU_SLAVE_FULL_WIND_DATA)
|
||||
// get the value from modbus registers
|
||||
modbus_retval = rtu_get_wind_direction(&rte_wx_average_winddirection);
|
||||
|
||||
|
@ -333,6 +415,8 @@ void wx_pool_anemometer(void) {
|
|||
modbus_retval = rtu_get_wind_speed(&rte_wx_winddirection_last);
|
||||
|
||||
}
|
||||
#else
|
||||
rte_wx_reset_last_measuremenet_timers(RTE_WX_MEASUREMENT_WIND);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -473,22 +557,38 @@ void wx_pwr_init(void) {
|
|||
}
|
||||
|
||||
void wx_pwr_periodic_handle(void) {
|
||||
// check when last measuremenets was sent by wind or temperature sensor
|
||||
if ( (master_time - wx_last_good_temperature_time >= WX_WATCHDOG_PERIOD ||
|
||||
master_time - wx_last_good_wind_time >= WX_WATCHDOG_PERIOD) &&
|
||||
wx_pwr_state == WX_PWR_ON) {
|
||||
|
||||
// if timeout watchod expired there is a time to reset the supply voltage
|
||||
wx_pwr_state = WX_PWR_UNDER_RESET;
|
||||
// do a last valid measuremenets timestamps only if power is currently applied
|
||||
if (wx_pwr_state == WX_PWR_ON) {
|
||||
|
||||
// pulling the output down to switch the relay and disable +5V_ISOL (VDD_SW)
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
|
||||
// the value of 0xFFFFFFFF is a magic word which disables the check for this parameter
|
||||
if (wx_last_good_temperature_time != 0xFFFFFFFF &&
|
||||
master_time - wx_last_good_temperature_time >= WX_WATCHDOG_PERIOD)
|
||||
{
|
||||
wx_pwr_state = WX_PWR_UNDER_RESET;
|
||||
}
|
||||
|
||||
// setting the last_good timers to current value to prevent reset loop
|
||||
wx_last_good_temperature_time = master_time;
|
||||
wx_last_good_wind_time = master_time;
|
||||
// as the weather station could be configured not to perform wind measurements at all
|
||||
if (wx_last_good_wind_time != 0xFFFFFFFF &&
|
||||
master_time - wx_last_good_wind_time >= WX_WATCHDOG_PERIOD)
|
||||
{
|
||||
wx_pwr_state = WX_PWR_UNDER_RESET;
|
||||
}
|
||||
|
||||
if (wx_pwr_state == WX_PWR_UNDER_RESET) {
|
||||
// if timeout watchod expired there is a time to reset the supply voltage
|
||||
wx_pwr_state = WX_PWR_UNDER_RESET;
|
||||
|
||||
// pull the output down to switch the relay and disable +5V_ISOL (VDD_SW)
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
|
||||
|
||||
// setting the last_good timers to current value to prevent reset loop
|
||||
wx_last_good_temperature_time = master_time;
|
||||
wx_last_good_wind_time = master_time;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// service actual supply state
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define RTU_GETTERS_F5_NAME rte_wx_modbus_rtu_f5
|
||||
#define RTU_GETTERS_F6_NAME rte_wx_modbus_rtu_f6
|
||||
|
||||
#define RTU_NUMBER_OF_ERRORS_TO_TRIG_STATUS 25
|
||||
#define RTU_NUMBER_OF_ERRORS_TO_TRIG_STATUS 32
|
||||
|
||||
#define RTU_POOL_QUEUE_LENGHT 6
|
||||
|
||||
|
@ -23,6 +23,6 @@
|
|||
|
||||
#define RTU_MAXIMUM_DATA_LN 64
|
||||
|
||||
#define RTU_MAXIMUM_VALUE_AGE 600000
|
||||
#define RTU_MAXIMUM_VALUE_AGE 300000
|
||||
|
||||
#endif /* INCLUDE_MODBUS_RTU_RTU_CONFIGURATION_H_ */
|
||||
|
|
|
@ -17,5 +17,6 @@
|
|||
#define MODBUS_RET_NOT_AVALIABLE 5
|
||||
#define MODBUS_RET_DEGRADED 6
|
||||
#define MODBUS_RET_UNEXP_SLAVE_ADR 7
|
||||
#define MODBUS_RET_NOT_CONFIGURED 8
|
||||
|
||||
#endif /* INCLUDE_MODBUS_RTU_RTU_RETURN_VALUES_H_ */
|
||||
|
|
|
@ -80,7 +80,7 @@ int32_t rtu_get_temperature(float* out) {
|
|||
#error "Wrong Modbus Configuration"
|
||||
#endif
|
||||
#else
|
||||
retval = MODBUS_RET_NOT_AVALIABLE;
|
||||
retval = MODBUS_RET_NOT_CONFIGURED;
|
||||
#endif
|
||||
|
||||
if (retval == MODBUS_RET_UNINITIALIZED && source != 0) {
|
||||
|
@ -175,7 +175,7 @@ int32_t rtu_get_pressure(float* out) {
|
|||
#error "Wrong Modbus Configuration"
|
||||
#endif
|
||||
#else
|
||||
retval = MODBUS_RET_NOT_AVALIABLE;
|
||||
retval = MODBUS_RET_NOT_CONFIGURED;
|
||||
#endif
|
||||
|
||||
if (retval == MODBUS_RET_UNINITIALIZED && source != 0) {
|
||||
|
@ -269,7 +269,7 @@ int32_t rtu_get_wind_direction(uint16_t* out) {
|
|||
#error "Wrong Modbus Configuration"
|
||||
#endif
|
||||
#else
|
||||
retval = MODBUS_RET_NOT_AVALIABLE;
|
||||
retval = MODBUS_RET_NOT_CONFIGURED;
|
||||
#endif
|
||||
|
||||
if (retval == MODBUS_RET_UNINITIALIZED && source != 0) {
|
||||
|
@ -363,7 +363,7 @@ int32_t rtu_get_wind_speed(uint16_t* out) {
|
|||
#error "Wrong Modbus Configuration"
|
||||
#endif
|
||||
#else
|
||||
retval = MODBUS_RET_NOT_AVALIABLE;
|
||||
retval = MODBUS_RET_NOT_CONFIGURED;
|
||||
#endif
|
||||
|
||||
if (retval == MODBUS_RET_UNINITIALIZED && source != 0) {
|
||||
|
@ -456,7 +456,7 @@ int32_t rtu_get_wind_gusts(uint16_t* out) {
|
|||
#error "Wrong Modbus Configuration"
|
||||
#endif
|
||||
#else
|
||||
retval = MODBUS_RET_NOT_AVALIABLE;
|
||||
retval = MODBUS_RET_NOT_CONFIGURED;
|
||||
#endif
|
||||
|
||||
if (retval == MODBUS_RET_UNINITIALIZED && source != 0) {
|
||||
|
@ -536,7 +536,7 @@ int32_t rtu_get_humidity(int8_t* out) {
|
|||
#error "Wrong Modbus Configuration"
|
||||
#endif
|
||||
#else
|
||||
retval = MODBUS_RET_NOT_AVALIABLE;
|
||||
retval = MODBUS_RET_NOT_CONFIGURED;
|
||||
#endif
|
||||
|
||||
if (retval == MODBUS_RET_UNINITIALIZED && source != 0) {
|
||||
|
|
|
@ -242,7 +242,7 @@ int32_t rtu_serial_pool(void) {
|
|||
|
||||
// stupid workaround. If there is a lot of I/O errors reset the controller
|
||||
|
||||
if (rte_rtu_number_of_serial_io_errors >= (RTU_NUMBER_OF_ERRORS_TO_TRIG_STATUS * 7) ||
|
||||
if (rte_rtu_number_of_serial_io_errors >= (RTU_NUMBER_OF_ERRORS_TO_TRIG_STATUS * 3) ||
|
||||
rtu_time_of_last_succ_comm_at_previous_error_status == rtu_time_of_last_successfull_comm)
|
||||
{
|
||||
rte_main_reboot_req = 1;
|
||||
|
|
Ładowanie…
Reference in New Issue