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

master
Mateusz Lubecki 2023-11-17 06:57:30 +01:00
rodzic 654540fcf3
commit 733dbfa13b
17 zmienionych plików z 143 dodań i 113 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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];

Wyświetl plik

@ -96,6 +96,8 @@
#include <kiss_communication/kiss_communication.h>
#include <etc/kiss_configuation.h>
#include <etc/dallas_temperature_limits.h>
#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;
}

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -21,6 +21,7 @@
*
*/
//float rte_wx_temperature_average_external = 0.0f; //<! This name should be refactored
float rte_wx_temperature_average_external_valid = 0.0f; //<! This name should be refactored
float rte_wx_temperature_internal = 0.0f, rte_wx_temperature_internal_valid = 0.0f;
float rte_wx_pressure = 0.0f, rte_wx_pressure_valid = 0.0f;
@ -66,6 +67,7 @@ ms5611_qf_t rte_wx_ms5611_qf = MS5611_QF_UNKNOWN;
bme280_qf_t rte_wx_bme280_qf = BME280_QF_UKNOWN;
analog_wind_qf_t rte_wx_wind_qf = AN_WIND_QF_UNKNOWN;
uint8_t rte_wx_humidity_available = 0;
uint8_t rte_wx_dallas_degraded_counter = 0;
umb_frame_t rte_wx_umb;

Wyświetl plik

@ -19,8 +19,43 @@
#include <modbus_rtu/rtu_getters.h>
#include <modbus_rtu/rtu_return_values.h>
#include <etc/dallas_temperature_limits.h>
#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;

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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 {

Wyświetl plik

@ -18,6 +18,7 @@
#endif
#include "drivers/dallas.h"
#include "etc/dallas_temperature_limits.h"
#include <string.h>
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;

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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;
}