safety state and input error detection
This commit is contained in:
102
main/safety.c
102
main/safety.c
@ -1,6 +1,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include <string.h>
|
||||
#include "safety.h"
|
||||
|
||||
#define PERIODIC_INTERVAL 1U // run safety checks every 1sec
|
||||
@ -8,11 +9,12 @@
|
||||
|
||||
static const char *TAG = "smart-oil-heater-control-system-safety";
|
||||
static SemaphoreHandle_t xMutexAccessSafety = NULL;
|
||||
sSensorSanityCheck sanityChecks[NUMBER_OF_SENSOR_SANITY_CHECKS] = {
|
||||
{0U, "chamber_temperature", {95.0f, -10.0f}, 0.0f, 0U, getChamberTemperature},
|
||||
{0U, "outdoor_temperature", {45.0f, -20.0f}, 0.0f, 0U, getOutdoorTemperature},
|
||||
{0U, "inlet_flow_temperature", {95.0f, -10.0f}, 0.0f, 0U, getInletFlowTemperature},
|
||||
{0U, "return_flow_temperature", {95.0f, -10.0f}, 0.0f, 0U, getReturnFlowTemperature}};
|
||||
static sSensorSanityCheck sanityChecks[NUMBER_OF_SENSOR_SANITY_CHECKS] = {
|
||||
{SENSOR_NO_ERROR, "chamber_temperature", {95.0f, -10.0f}, 0.0f, 0U, getChamberTemperature},
|
||||
{SENSOR_NO_ERROR, "outdoor_temperature", {45.0f, -20.0f}, 0.0f, 0U, getOutdoorTemperature},
|
||||
{SENSOR_NO_ERROR, "inlet_flow_temperature", {95.0f, -10.0f}, 0.0f, 0U, getInletFlowTemperature},
|
||||
{SENSOR_NO_ERROR, "return_flow_temperature", {95.0f, -10.0f}, 0.0f, 0U, getReturnFlowTemperature}};
|
||||
static eSafetyState sSafetyState = SAFETY_NO_ERROR;
|
||||
|
||||
void taskSafety(void *pvParameters);
|
||||
void checkSensorSanity(void);
|
||||
@ -30,7 +32,7 @@ void initSafety(void)
|
||||
BaseType_t taskCreated = xTaskCreate(
|
||||
taskSafety, // Function to implement the task
|
||||
"taskSafety", // Task name
|
||||
2048, // Stack size (in words, not bytes)
|
||||
4096, // Stack size (in words, not bytes)
|
||||
NULL, // Parameters to the task function (none in this case)
|
||||
5, // Task priority (higher number = higher priority)
|
||||
NULL // Task handle (optional)
|
||||
@ -52,13 +54,18 @@ void taskSafety(void *pvParameters)
|
||||
{
|
||||
vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS);
|
||||
|
||||
checkSensorSanity();
|
||||
if (xSemaphoreTake(xMutexAccessSafety, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
|
||||
checkSensorSanity();
|
||||
xSemaphoreGive(xMutexAccessSafety);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkSensorSanity(void)
|
||||
{
|
||||
|
||||
sSafetyState = SAFETY_NO_ERROR;
|
||||
for (int i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++)
|
||||
{
|
||||
// printf("Check sanity of sensor %s:\n", sanityChecks[i].name);
|
||||
@ -66,34 +73,47 @@ void checkSensorSanity(void)
|
||||
// printf(" Sensor Limits: Max = %.2f, Min = %.2f\n", sanityChecks[i].sSensorLimit.max, sanityChecks[i].sSensorLimit.min);
|
||||
// printf(" Last Sensor Temperature: %.2f\n", sanityChecks[i].fSensorTemperatureLast);
|
||||
|
||||
const float fSensorTemperatureCurrent = sanityChecks[i].getSensor(CURRENT);
|
||||
if (fSensorTemperatureCurrent == sanityChecks[i].fSensorTemperatureLast)
|
||||
const sMeasurement sCurrentMeasurement = sanityChecks[i].getSensor();
|
||||
|
||||
if (sCurrentMeasurement.state == MEASUREMENT_FAULT)
|
||||
{
|
||||
sanityChecks[i].uUnchangedCounter++;
|
||||
if (sanityChecks[i].uUnchangedCounter >= (SENSOR_GRACE_PERIOD / PERIODIC_INTERVAL))
|
||||
{
|
||||
ESP_LOGE(TAG, "%s Sensor reported unchanged value! %lf == %lf", sanityChecks[i].name, fSensorTemperatureCurrent, sanityChecks[i].fSensorTemperatureLast);
|
||||
sanityChecks[i].status = 1U;
|
||||
}
|
||||
ESP_LOGE(TAG, "%s Sensor not found!", sanityChecks[i].name);
|
||||
sanityChecks[i].status = SENSOR_NOT_FOUND;
|
||||
sSafetyState = SAFETY_SENSOR_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
sanityChecks[i].fSensorTemperatureLast = fSensorTemperatureCurrent;
|
||||
|
||||
if (fSensorTemperatureCurrent > sanityChecks[i].sSensorLimit.max)
|
||||
if (sCurrentMeasurement.fCurrentValue == sanityChecks[i].fSensorTemperatureLast)
|
||||
{
|
||||
ESP_LOGE(TAG, "%s Sensor reported too high value! %lf > %lf", sanityChecks[i].name, fSensorTemperatureCurrent, sanityChecks[i].sSensorLimit.max);
|
||||
sanityChecks[i].status = 1U;
|
||||
}
|
||||
else if (fSensorTemperatureCurrent < sanityChecks[i].sSensorLimit.min)
|
||||
{
|
||||
ESP_LOGE(TAG, "%s Sensor reported too low value! %lf < %lf", sanityChecks[i].name, fSensorTemperatureCurrent, sanityChecks[i].sSensorLimit.min);
|
||||
sanityChecks[i].status = 1U;
|
||||
sanityChecks[i].uUnchangedCounter++;
|
||||
if (sanityChecks[i].uUnchangedCounter >= (SENSOR_GRACE_PERIOD / PERIODIC_INTERVAL))
|
||||
{
|
||||
ESP_LOGE(TAG, "%s Sensor reported unchanged value! %lf == %lf", sanityChecks[i].name, sCurrentMeasurement.fCurrentValue, sanityChecks[i].fSensorTemperatureLast);
|
||||
sanityChecks[i].status = SENSOR_UNCHANGED;
|
||||
sSafetyState = SAFETY_SENSOR_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sanityChecks[i].uUnchangedCounter = 0U;
|
||||
sanityChecks[i].status = 0U;
|
||||
sanityChecks[i].fSensorTemperatureLast = sCurrentMeasurement.fCurrentValue;
|
||||
|
||||
if (sCurrentMeasurement.fCurrentValue > sanityChecks[i].sSensorLimit.max)
|
||||
{
|
||||
ESP_LOGE(TAG, "%s Sensor reported too high value! %lf > %lf", sanityChecks[i].name, sCurrentMeasurement.fCurrentValue, sanityChecks[i].sSensorLimit.max);
|
||||
sanityChecks[i].status = SENSOR_TOO_HIGH;
|
||||
sSafetyState = SAFETY_SENSOR_ERROR;
|
||||
}
|
||||
else if (sCurrentMeasurement.fCurrentValue < sanityChecks[i].sSensorLimit.min)
|
||||
{
|
||||
ESP_LOGE(TAG, "%s Sensor reported too low value! %lf < %lf", sanityChecks[i].name, sCurrentMeasurement.fCurrentValue, sanityChecks[i].sSensorLimit.min);
|
||||
sanityChecks[i].status = SENSOR_TOO_LOW;
|
||||
sSafetyState = SAFETY_SENSOR_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
sanityChecks[i].uUnchangedCounter = 0U;
|
||||
sanityChecks[i].status = SENSOR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
// printf(" Status: %u\n", sanityChecks[i].status);
|
||||
@ -106,9 +126,27 @@ void setSafeState(void)
|
||||
setBurnerState(DISABLED);
|
||||
}
|
||||
|
||||
/*
|
||||
sSafetyStateElement *getSafetyStates(void)
|
||||
void getSensorSanityStates(sSensorSanityCheck *pSensorSanityChecks)
|
||||
{
|
||||
return safetyStates;
|
||||
if (xSemaphoreTake(xMutexAccessSafety, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
for (size_t i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++)
|
||||
{
|
||||
// Copy only the needed attributes
|
||||
pSensorSanityChecks[i].status = sanityChecks[i].status;
|
||||
strcpy(pSensorSanityChecks[i].name, sanityChecks[i].name);
|
||||
}
|
||||
xSemaphoreGive(xMutexAccessSafety);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
eSafetyState getSafetyState(void)
|
||||
{
|
||||
eSafetyState state = SAFETY_NO_ERROR;
|
||||
if (xSemaphoreTake(xMutexAccessSafety, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
state = sSafetyState;
|
||||
xSemaphoreGive(xMutexAccessSafety);
|
||||
}
|
||||
return state;
|
||||
}
|
Reference in New Issue
Block a user