From cec891f0dfaea60289a02ac6a872eb13d74d540e9770f8d2d2c78ecdbd0f46ce Mon Sep 17 00:00:00 2001 From: localhorst Date: Tue, 10 Dec 2024 21:25:36 +0100 Subject: [PATCH] add average --- main/inputs.c | 142 ++++++++++++++++++++++++++++++++++++++++++------- main/inputs.h | 18 +++++-- main/metrics.c | 8 +-- 3 files changed, 140 insertions(+), 28 deletions(-) diff --git a/main/inputs.c b/main/inputs.c index 516863f..33c6656 100644 --- a/main/inputs.c +++ b/main/inputs.c @@ -6,11 +6,28 @@ #include "inputs.h" +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MAX_DN18B20_SENSORS 4U +#define PERIODIC_INTERVAL 1U // read and compute the inputs every 1sec +#define AVG10_SAMPLE_SIZE 10U +#define AVG60_SAMPLE_SIZE 60U + +typedef struct _Measurement +{ + float lastValue; + float average10s; + float average60s; + float samples[MAX(AVG10_SAMPLE_SIZE, AVG60_SAMPLE_SIZE)]; + size_t bufferIndex; + size_t bufferCount; + +} sMeasurement; static const char *TAG = "smart-oil-heater-control-system-inputs"; const uint8_t uBurnerFaultPin = 19U; const uint8_t uDS18B20Pin = 4U; + const onewire_addr_t uChamperTempSensorAddr = 0x3e0000001754be28; const onewire_addr_t uOutdoorTempSensorAddr = 0x880000001648e328; const onewire_addr_t uInletFlowTempSensorAddr = 0xe59cdef51e64ff28; @@ -22,10 +39,10 @@ size_t sSensorCount = 0U; static SemaphoreHandle_t xMutexAccessInputs = NULL; static eBurnerErrorState sBurnerErrorState; -static float fChamperTemperature; -static float fOutdoorTemperature; -static float fInletFlowTemperature; -static float fReturnFlowTemperature; +static sMeasurement fChamperTemperature; +static sMeasurement fOutdoorTemperature; +static sMeasurement fInletFlowTemperature; +static sMeasurement fReturnFlowTemperature; void taskInput(void *pvParameters); @@ -68,12 +85,44 @@ void initInputs(void) } } +// Function to add a new temperature value to the buffer +void updateAverage(sMeasurement* pMeasurement) +{ + pMeasurement->samples[pMeasurement->bufferIndex] = pMeasurement->lastValue; + pMeasurement->bufferIndex = (pMeasurement->bufferIndex + 1) % MAX(AVG10_SAMPLE_SIZE, AVG60_SAMPLE_SIZE); + + if (pMeasurement->bufferCount < MAX(AVG10_SAMPLE_SIZE, AVG60_SAMPLE_SIZE)) + { + pMeasurement->bufferCount++; + } + + if (pMeasurement->bufferCount == 0U) + { + pMeasurement->average10s = pMeasurement->lastValue; + pMeasurement->average60s = pMeasurement->lastValue; + } + + float sum = 0.0; + for (int i = 0; i < MIN(pMeasurement->bufferCount, AVG10_SAMPLE_SIZE); i++) + { + sum += pMeasurement->samples[i]; + } + + pMeasurement->average10s = sum / MIN(pMeasurement->bufferCount, AVG10_SAMPLE_SIZE); + + sum = 0.0; + for (int i = 0; i < MIN(pMeasurement->bufferCount, AVG60_SAMPLE_SIZE); i++) + { + sum += pMeasurement->samples[i]; + } + pMeasurement->average60s = sum / MIN(pMeasurement->bufferCount, AVG60_SAMPLE_SIZE); +} + void taskInput(void *pvParameters) { while (1) { - ESP_LOGI(TAG, "Running task Input..."); - vTaskDelay(1000U / portTICK_PERIOD_MS); + vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS); if (gpio_get_level(uBurnerFaultPin) == 1) { @@ -118,21 +167,24 @@ void taskInput(void *pvParameters) switch ((uint64_t)uOneWireAddresses[j]) { case ((uint64_t)uChamperTempSensorAddr): - fChamperTemperature = temp_c; + fChamperTemperature.lastValue = temp_c; + updateAverage(&fChamperTemperature); break; case ((uint64_t)uOutdoorTempSensorAddr): - fOutdoorTemperature = temp_c; + fOutdoorTemperature.lastValue = temp_c; + updateAverage(&fOutdoorTemperature); break; case ((uint64_t)uInletFlowTempSensorAddr): - fInletFlowTemperature = temp_c; + fInletFlowTemperature.lastValue = temp_c; + updateAverage(&fInletFlowTemperature); break; case ((uint64_t)uReturnFlowTempSensorAddr): - fReturnFlowTemperature = temp_c; + fReturnFlowTemperature.lastValue = temp_c; + updateAverage(&fReturnFlowTemperature); break; default: break; } - xSemaphoreGive(xMutexAccessInputs); } } @@ -141,42 +193,94 @@ void taskInput(void *pvParameters) } } -float getChamberTemperature(void) +float getChamberTemperature(eMeasurementMode mode) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { - ret = fChamperTemperature; + switch (mode) + { + case CURRENT: + ret = fChamperTemperature.lastValue; + break; + case AVERAGE_10S: + ret = fChamperTemperature.average10s; + break; + case AVERAGE_60S: + ret = fChamperTemperature.average60s; + break; + default: + break; + } xSemaphoreGive(xMutexAccessInputs); } return ret; } -float getOutdoorTemperature(void) +float getOutdoorTemperature(eMeasurementMode mode) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { - ret = fOutdoorTemperature; + switch (mode) + { + case CURRENT: + ret = fOutdoorTemperature.lastValue; + break; + case AVERAGE_10S: + ret = fOutdoorTemperature.average10s; + break; + case AVERAGE_60S: + ret = fOutdoorTemperature.average60s; + break; + default: + break; + } xSemaphoreGive(xMutexAccessInputs); } return ret; } -float getInletFlowTemperature(void) +float getInletFlowTemperature(eMeasurementMode mode) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { - ret = fInletFlowTemperature; + switch (mode) + { + case CURRENT: + ret = fInletFlowTemperature.lastValue; + break; + case AVERAGE_10S: + ret = fInletFlowTemperature.average10s; + break; + case AVERAGE_60S: + ret = fInletFlowTemperature.average60s; + break; + default: + break; + } xSemaphoreGive(xMutexAccessInputs); } return ret; } -float getReturnFlowTemperature(void) +float getReturnFlowTemperature(eMeasurementMode mode) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { - ret = fReturnFlowTemperature; + switch (mode) + { + case CURRENT: + ret = fReturnFlowTemperature.lastValue; + break; + case AVERAGE_10S: + ret = fReturnFlowTemperature.average10s; + break; + case AVERAGE_60S: + ret = fReturnFlowTemperature.average60s; + break; + default: + break; + } xSemaphoreGive(xMutexAccessInputs); } return ret; diff --git a/main/inputs.h b/main/inputs.h index a8421f4..0307ffe 100644 --- a/main/inputs.h +++ b/main/inputs.h @@ -1,13 +1,21 @@ #pragma once -typedef enum _BurnerErrorState{ +typedef enum _BurnerErrorState +{ NO_ERROR, FAULT } eBurnerErrorState; +typedef enum _MeasurementMode +{ + CURRENT, + AVERAGE_10S, + AVERAGE_60S +} eMeasurementMode; + void initInputs(void); -float getChamberTemperature(void); -float getOutdoorTemperature(void); -float getInletFlowTemperature(void); -float getReturnFlowTemperature(void); +float getChamberTemperature(eMeasurementMode mode); +float getOutdoorTemperature(eMeasurementMode mode); +float getInletFlowTemperature(eMeasurementMode mode); +float getReturnFlowTemperature(eMeasurementMode mode); eBurnerErrorState getBurnerError(void); \ No newline at end of file diff --git a/main/metrics.c b/main/metrics.c index ebaa00d..cd55c02 100644 --- a/main/metrics.c +++ b/main/metrics.c @@ -124,22 +124,22 @@ void taskMetrics(void *pvParameters) /*Chamber Temperature*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "chamber_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getChamberTemperature(); + aMetrics[u16MetricCounter].fMetricValue = getChamberTemperature(CURRENT); u16MetricCounter++; /*Outdoor Temperature*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "outdoor_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature(); + aMetrics[u16MetricCounter].fMetricValue = getOutdoorTemperature(CURRENT); u16MetricCounter++; /*Chamber Temperature*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "inlet_flow_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature(); + aMetrics[u16MetricCounter].fMetricValue = getInletFlowTemperature(CURRENT); u16MetricCounter++; /*Chamber Temperature*/ strcpy(aMetrics[u16MetricCounter].caMetricName, "return_flow_temperature"); - aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature(); + aMetrics[u16MetricCounter].fMetricValue = getReturnFlowTemperature(CURRENT); u16MetricCounter++; vSetMetrics(aMetrics, u16MetricCounter);