From 733dbfa13b89adf9d115627ec98d9ff8a935a56b Mon Sep 17 00:00:00 2001 From: Mateusz Lubecki Date: Fri, 17 Nov 2023 06:57:30 +0100 Subject: [PATCH] dallas temperature sensor: different handling of measurement results depends on quality factor, set qf to degraded if temperature is below or above set treshold. removed modbus rtu status message completely --- STM32L476_ParaMETEO/avstack.pl | 2 +- include/etc/dallas_temperature_limits.h | 23 ++++ include/rte_main.h | 1 - include/rte_wx.h | 1 + include/software_version.h | 2 +- src/main.c | 35 +++-- src/packet_tx_handler.c | 6 +- src/rte_main.c | 1 - src/rte_wx.c | 2 + src/wx_handler_temperature.c | 120 ++++++++++-------- system/include/float_average.h | 1 + system/include/int_average.h | 1 + .../ve_direct_protocol/average_struct.h | 2 +- system/src/drivers/dallas.c | 5 +- system/src/float_average.c | 10 ++ system/src/int_average.c | 10 ++ system/src/modbus_rtu/rtu_serial_io.c | 34 ----- 17 files changed, 143 insertions(+), 113 deletions(-) create mode 100644 include/etc/dallas_temperature_limits.h diff --git a/STM32L476_ParaMETEO/avstack.pl b/STM32L476_ParaMETEO/avstack.pl index 71129fb..c25fbb1 100644 --- a/STM32L476_ParaMETEO/avstack.pl +++ b/STM32L476_ParaMETEO/avstack.pl @@ -51,7 +51,7 @@ use strict; # Configuration: set these as appropriate for your architecture/project. my $objdump = "/usr/local/bin/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-objdump"; -my $call_cost = 12; +my $call_cost = 32; # First, we need to read all object and corresponding .su files. We're # gathering a mapping of functions to callees and functions to frame diff --git a/include/etc/dallas_temperature_limits.h b/include/etc/dallas_temperature_limits.h new file mode 100644 index 0000000..868ddae --- /dev/null +++ b/include/etc/dallas_temperature_limits.h @@ -0,0 +1,23 @@ +/* + * dallas_temperature_limits.h + * + * Created on: Nov 16, 2023 + * Author: mateusz + */ + +#ifndef ETC_DALLAS_TEMPERATURE_LIMITS_H_ +#define ETC_DALLAS_TEMPERATURE_LIMITS_H_ + + +#define DALLAS_TEMPERATURE_LIMITS_LOW -32.0f + +#define DALLAS_TEMPERATURE_LIMITS_HI 64.0f + +#define DALLAS_TEMPERATURE_NEG_SLEW -16 + +#define DALLAS_TEMPERATURE_POS_SLEW 16 + +#define DALLAS_MAX_LIMIT_OF_DEGRADED 64U + + +#endif /* ETC_DALLAS_TEMPERATURE_LIMITS_H_ */ diff --git a/include/rte_main.h b/include/rte_main.h index fb212d2..ce6368c 100644 --- a/include/rte_main.h +++ b/include/rte_main.h @@ -33,7 +33,6 @@ extern uint8_t rte_main_boot_cycles, rte_main_hard_faults; extern uint32_t rte_main_hardfault_lr, rte_main_hardfault_pc; extern uint8_t rte_main_trigger_status; -extern uint8_t rte_main_trigger_modbus_status; extern uint8_t rte_main_trigger_wx_packet; diff --git a/include/rte_wx.h b/include/rte_wx.h index aae0e10..83f9b4b 100644 --- a/include/rte_wx.h +++ b/include/rte_wx.h @@ -81,6 +81,7 @@ extern ms5611_qf_t rte_wx_ms5611_qf; extern bme280_qf_t rte_wx_bme280_qf; extern analog_wind_qf_t rte_wx_wind_qf; extern uint8_t rte_wx_humidity_available; +extern uint8_t rte_wx_dallas_degraded_counter; extern umb_frame_t rte_wx_umb; diff --git a/include/software_version.h b/include/software_version.h index 1842344..865c0f4 100644 --- a/include/software_version.h +++ b/include/software_version.h @@ -9,7 +9,7 @@ #define SOFTWARE_VERSION_H_ #define SW_VER "EB03" -#define SW_DATE "12112023" +#define SW_DATE "16112023" #define SW_KISS_PROTO "B" extern const char software_version_str[5]; diff --git a/src/main.c b/src/main.c index e477d08..17a88ec 100644 --- a/src/main.c +++ b/src/main.c @@ -96,6 +96,8 @@ #include #include +#include + #define SOH 0x01 //#include "variant.h" @@ -188,6 +190,9 @@ int32_t main_two_second_pool_timer = 2000; //! ten second pool interval int32_t main_ten_second_pool_timer = 10000; +//! one hour interval incremented inside one minute +int8_t main_one_hour_pool_timer = 60; + //! serial context for UART used to KISS srl_context_t main_kiss_srl_ctx; @@ -1444,19 +1449,6 @@ int main(int argc, char* argv[]){ wx_get_all_measurements(main_config_data_wx_sources, main_config_data_mode, main_config_data_umb, main_config_data_rtu); } - // check if there is a request to send ModbusRTU error status message - if (rte_main_trigger_modbus_status == 1 && main_modbus_rtu_master_enabled == 1) { - rtu_serial_get_status_string(&rte_rtu_pool_queue, main_wx_srl_ctx_ptr, main_own_aprs_msg, OWN_APRS_MSG_LN, &main_own_aprs_msg_len); - - ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, main_own_aprs_msg, main_own_aprs_msg_len); - - afsk_txStart(&main_afsk); - - rte_main_trigger_modbus_status = 0; - - - } - backup_reg_set_monitor(3); main_wx_sensors_pool_timer = 65500; @@ -1498,6 +1490,23 @@ int main(int argc, char* argv[]){ } #endif + if (rte_wx_dallas_degraded_counter > DALLAS_MAX_LIMIT_OF_DEGRADED) { + rte_main_reboot_req = 1; + } + + /** + * ONE HOUR POOLING + */ + if (--main_one_hour_pool_timer < 0) { + main_one_hour_pool_timer = 60; + + if (system_is_rtc_ok() == 0) { + rte_main_reboot_req = 1; + } + } + + + main_one_minute_pool_timer = 60000; } diff --git a/src/packet_tx_handler.c b/src/packet_tx_handler.c index 8ae3a1a..09ee617 100644 --- a/src/packet_tx_handler.c +++ b/src/packet_tx_handler.c @@ -369,7 +369,7 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con // ASSEMBLY QUALITY FACTORS - // if there weren't any erros related to the communication with DS12B20 from previous function call + // if there weren't any errors related to the communication with DS12B20 from previous function call if (rte_wx_error_dallas_qf == DALLAS_QF_UNKNOWN) { dallas_qf = rte_wx_current_dallas_qf; // it might be DEGRADATED so we need to copy a value directly @@ -579,10 +579,6 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con else { packet_tx_trigger_tcp = 0; } - - if (system_is_rtc_ok() == 0) { - rte_main_reboot_req = 1; - } #endif packet_tx_telemetry_descr_counter = 0; diff --git a/src/rte_main.c b/src/rte_main.c index b956675..721d219 100644 --- a/src/rte_main.c +++ b/src/rte_main.c @@ -14,7 +14,6 @@ uint8_t rte_main_reboot_req = 0; uint8_t rte_main_boot_cycles = 0, rte_main_hard_faults = 0; uint8_t rte_main_trigger_status = 0; -uint8_t rte_main_trigger_modbus_status = 0; uint8_t rte_main_trigger_wx_packet = 0; diff --git a/src/rte_wx.c b/src/rte_wx.c index 6d7b67c..bd90568 100644 --- a/src/rte_wx.c +++ b/src/rte_wx.c @@ -21,6 +21,7 @@ * */ +//float rte_wx_temperature_average_external = 0.0f; // #include +#include + #define WX_MAX_TEMPERATURE_SLEW_RATE 4.0f +inline static int8_t wx_handler_temperature_check_slew(const float last, const float_average_t* average) { + + // 0 -> OK + int8_t result = 0; + + float avg = 0.0f; + + // continue only if average circular buffer is completely full + if (float_get_nonfull(average) == 0) { + + // get current average + avg = float_get_average(average); + + // get difference + avg = avg - last; + + // resuse result variable to save stack space + result = (int8_t)avg; + + if (result < DALLAS_TEMPERATURE_NEG_SLEW) { + result = 1; + } + else if (result > DALLAS_TEMPERATURE_POS_SLEW) { + result = 1; + } + else { + result = 0; + } + } + + return result; +} + int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const config_sources, const config_data_mode_t * const config_mode, const config_data_umb_t * const config_umb, const config_data_rtu_t * const config_rtu, float * output) { @@ -31,6 +66,8 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co float temperature = 0.0f; + float dallas_temperature = 0.0f; + // choose main temperature source from the configuration. main sensor is something which is used to send data though aprs switch(config_sources->temperature) { // controller measures two temperatures @@ -69,7 +106,14 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co // this function has blockin I/O which also adds a delay required by MS5611 // sensor to finish data acquisition after the pressure measurement // is triggered. - wx_get_temperature_dallas(); + dallas_temperature = dallas_query(&rte_wx_current_dallas_qf); + + // check against excessive slew rate + const uint8_t dallas_slew_exceeded = wx_handler_temperature_check_slew(dallas_temperature, &rte_wx_dallas_average); + + if (dallas_slew_exceeded > 0) { + rte_wx_current_dallas_qf = DALLAS_QF_NOT_AVALIABLE; + } #ifdef STM32L471xx // measure temperature from PT100 sensor if it is selected as main temperature sensor @@ -81,11 +125,32 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co } #endif - if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf != DALLAS_QF_NOT_AVALIABLE) { + if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf == DALLAS_QF_FULL) { + // updating last good measurement time + wx_last_good_temperature_time = master_time; + + // include current temperature into the average + float_average(dallas_temperature, &rte_wx_dallas_average); + temperature = float_get_average(&rte_wx_dallas_average); +#if defined(STM32L471xx) + rte_wx_temperature_average_dallas = (int16_t)(temperature * 10.0f); +#endif + parameter_result = parameter_result | WX_HANDLER_PARAMETER_RESULT_TEMPERATURE; } + else if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf == DALLAS_QF_DEGRADATED) { + // if there were a communication error set the error to unavaliable + rte_wx_error_dallas_qf = DALLAS_QF_NOT_AVALIABLE; + + // increase degraded quality factor counter + rte_wx_dallas_degraded_counter++; + } + else if (config_sources->temperature == WX_SOURCE_INTERNAL && rte_wx_current_dallas_qf == DALLAS_QF_NOT_AVALIABLE) { + // if there were a communication error set the error to unavaliable + rte_wx_error_dallas_qf = DALLAS_QF_NOT_AVALIABLE; + } break; } @@ -135,60 +200,9 @@ int32_t wx_get_temperature_measurement(const config_data_wx_sources_t * const co *output = temperature; } -//#if defined(STM32L471xx) -// // get modbus temperature reading regardless if it has been chosen as main -// if (config_mode->wx_modbus == 1) { -// rtu_get_temperature(&rte_wx_temperature_average_modbus, config_rtu); -// } -// -// // get temperature from dallas sensor if this isn't a sensor of choice -// if (config_sources->temperature != WX_SOURCE_INTERNAL) { -// wx_get_temperature_dallas(); -// } -// -// rte_wx_temperature_average_internal = (int16_t)(rte_wx_temperature_internal * 10.0f); -//#endif - return parameter_result; } -int32_t wx_get_temperature_dallas() { - - int32_t output = 0; - - float temperature = 0.0f; - - // get the value from dallas one-wire sensor - temperature = dallas_query(&rte_wx_current_dallas_qf); - - // checking if communication was successfull - if (temperature != -128.0f) { - - // include current temperature into the average - float_average(temperature, &rte_wx_dallas_average); - - // update the current temperature with current average -// rte_wx_temperature_average_external_valid = float_get_average(&rte_wx_dallas_average); - - // updating last good measurement time - wx_last_good_temperature_time = master_time; - -#if defined(STM32L471xx) - rte_wx_temperature_average_dallas = (int16_t)(rte_wx_temperature_average_external_valid * 10.0f); -#endif - - } - else { - // if there were a communication error set the error to unavaliable - rte_wx_error_dallas_qf = DALLAS_QF_NOT_AVALIABLE; - - // set the output value - output = -1; - } - - return output; -} - int32_t wx_get_temperature_ms5611(float * const temperature) { int32_t return_value = 0; diff --git a/system/include/float_average.h b/system/include/float_average.h index 8bc79c8..9e522ae 100644 --- a/system/include/float_average.h +++ b/system/include/float_average.h @@ -21,5 +21,6 @@ void float_average(float in, float_average_t* average); float float_get_average(const float_average_t* average); float float_get_min(const float_average_t* average); float float_get_max(const float_average_t* average); +char float_get_nonfull(const float_average_t* average); #endif /* INCLUDE_FLOAT_AVERAGE_H_ */ diff --git a/system/include/int_average.h b/system/include/int_average.h index ac0aa60..d7ac134 100644 --- a/system/include/int_average.h +++ b/system/include/int_average.h @@ -25,5 +25,6 @@ int32_t int_get_average(const int_average_t* average); int32_t int_get_min(const int_average_t* average); int32_t int_get_max(const int_average_t* average); int32_t int_get_last(const int_average_t* average); +int32_t int_get_nonfull(const int_average_t* average); #endif /* INCLUDE_INT_AVERAGE_H_ */ diff --git a/system/include/ve_direct_protocol/average_struct.h b/system/include/ve_direct_protocol/average_struct.h index 310d18a..0e8cf6a 100644 --- a/system/include/ve_direct_protocol/average_struct.h +++ b/system/include/ve_direct_protocol/average_struct.h @@ -8,7 +8,7 @@ #ifndef VE_DIRECT_PROTOCOL_AVERAGE_STRUCT_H_ #define VE_DIRECT_PROTOCOL_AVERAGE_STRUCT_H_ -#define VE_DIRECT_AVERAGE_LEN 24 +#define VE_DIRECT_AVERAGE_LEN 12 typedef __attribute__ ((aligned(1))) struct ve_direct_average_struct { diff --git a/system/src/drivers/dallas.c b/system/src/drivers/dallas.c index 18a1ffd..b669ceb 100644 --- a/system/src/drivers/dallas.c +++ b/system/src/drivers/dallas.c @@ -18,6 +18,7 @@ #endif #include "drivers/dallas.h" +#include "etc/dallas_temperature_limits.h" #include volatile int delay_5us = 0; @@ -241,9 +242,7 @@ float __attribute__((optimize("O0"))) dallas_query(dallas_qf_t *qf) { return -128.0f; } - if (temperature < -50.0f || temperature > 120.0f) - *qf = DALLAS_QF_NOT_AVALIABLE; - else if (temperature < -25.0f || temperature > 38.75f) + if (temperature < DALLAS_TEMPERATURE_LIMITS_LOW || temperature > DALLAS_TEMPERATURE_LIMITS_HI) *qf = DALLAS_QF_DEGRADATED; else *qf = DALLAS_QF_FULL; diff --git a/system/src/float_average.c b/system/src/float_average.c index 3966331..ad93f65 100644 --- a/system/src/float_average.c +++ b/system/src/float_average.c @@ -71,3 +71,13 @@ float dallas_get_max(const float_average_t* average) { return out; } +char float_get_nonfull(const float_average_t* average) { + for (int i = 0; i < FLOAT_AVERAGE_LN; i++) { + if (average->values[i] == FLOAT_INIT_VALUE) { + return 1; + } + } + + return 0; +} + diff --git a/system/src/int_average.c b/system/src/int_average.c index bae0b62..aa27044 100644 --- a/system/src/int_average.c +++ b/system/src/int_average.c @@ -97,3 +97,13 @@ int32_t int_get_last(const int_average_t* average) { return out; } + +int32_t int_get_nonfull(const int_average_t* average) { + for (int i = 0; i < INT_AVERAGE_LN; i++) { + if (average->values[i] == INT_INIT_VALUE) { + return 1; + } + } + + return 0; +} diff --git a/system/src/modbus_rtu/rtu_serial_io.c b/system/src/modbus_rtu/rtu_serial_io.c index 70577c6..0738767 100644 --- a/system/src/modbus_rtu/rtu_serial_io.c +++ b/system/src/modbus_rtu/rtu_serial_io.c @@ -72,13 +72,6 @@ uint8_t rtu_blocking_io = 0; */ uint32_t rtu_time_of_last_successfull_comm = 0; -/** - * This variable latches the value of 'rtu_time_of_last_successfull_comm' across - * consecutive messages with an error status. If the value is the same as during - * previous transmission the controller is restarted - */ -uint32_t rtu_time_of_last_succ_comm_at_previous_error_status = 0; - /** * CRC value after the last call to rtu_serial_callback */ @@ -217,8 +210,6 @@ int32_t rtu_serial_pool(void) { // check how many serial I/O erros have been detected so far if ((rte_rtu_number_of_serial_io_errors % RTU_NUMBER_OF_ERRORS_TO_TRIG_STATUS) == 0) { - // set the status trigger - rte_main_trigger_modbus_status = 1; // increment the error counter artificially to protect sending status in the loop rte_rtu_number_of_serial_io_errors++; @@ -230,8 +221,6 @@ int32_t rtu_serial_pool(void) { // rte_main_reboot_req = 1; // } - // latch the current value of last successfull communication - rtu_time_of_last_succ_comm_at_previous_error_status = rtu_time_of_last_successfull_comm; } } @@ -541,26 +530,3 @@ int32_t rtu_serial_start(void) { return retval; } -int32_t rtu_serial_get_status_string(rtu_pool_queue_t* queue, srl_context_t* srl_ctx, char* out, uint16_t out_buffer_ln, uint8_t* generated_string_ln) { - - int32_t retval = MODBUS_RET_UNINITIALIZED; - int string_ln = 0; - - memset(out, 0x00, out_buffer_ln); -//#ifdef _MODBUS_RTU - - string_ln = snprintf(out, out_buffer_ln, ">[MT: %lX][LRET: %lX][LSCT: %lX][NSSC: %X][NSE: %X][RXB: %lX][RXI %X][TXB %lX]", - main_get_master_time(), - rte_rtu_last_modbus_rx_error_timestamp, - rtu_time_of_last_successfull_comm, - (int)rte_rtu_number_of_successfull_serial_comm, - (int)rte_rtu_number_of_serial_io_errors, - srl_ctx->total_rx_bytes, - srl_ctx->total_idle_counter, - srl_ctx->total_tx_bytes); - - *generated_string_ln = (uint8_t) string_ln; -//#endif - return retval; -} -