From aebce5ac44d6c145ee2d6fbffba79aa606e9f8e5 Mon Sep 17 00:00:00 2001 From: Tobias Maier Date: Wed, 25 Mar 2026 20:52:23 +0100 Subject: [PATCH] fix water --- src/global_data/water_data_queue.cpp | 43 +++++++++++++++++----------- src/global_data/water_data_queue.h | 18 +++++++----- src/main.cpp | 4 +-- src/sensor/sensor.cpp | 8 ++---- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/global_data/water_data_queue.cpp b/src/global_data/water_data_queue.cpp index df79729..fd87c9b 100644 --- a/src/global_data/water_data_queue.cpp +++ b/src/global_data/water_data_queue.cpp @@ -1,30 +1,39 @@ #include "water_data_queue.h" #include -QueueHandle_t waterDataQueue = nullptr; +SemaphoreHandle_t waterDataMutex = nullptr; +WaterData latestWaterDataCache = {0.0f, 0.0f, 0.0f}; -void initWaterDataQueue() { - // Create queue that can hold 5 WaterData structures - waterDataQueue = xQueueCreate(5, sizeof(WaterData)); +void initWaterDataSync() { + // Create mutex for thread-safe access to latest data cache + waterDataMutex = xSemaphoreCreateMutex(); - if (waterDataQueue == nullptr) { - Serial.println("Failed to create water data queue"); + if (waterDataMutex == nullptr) { + Serial.println("Failed to create water data mutex"); + } +} + +void updateLatestWaterData(const WaterData& newData) { + // Update the cache with new data (called by producer) + if (xSemaphoreTake(waterDataMutex, pdMS_TO_TICKS(10)) == pdTRUE) { + latestWaterDataCache = newData; + xSemaphoreGive(waterDataMutex); } } WaterData getLatestWaterData() { - WaterData latestData; + WaterData result; - // Try to receive the latest data without blocking - if (xQueueReceive(waterDataQueue, &latestData, 0) == pdPASS) { - // Put the data back in the queue so other consumers can get it too - xQueueSendToBack(waterDataQueue, &latestData, 0); - return latestData; + // Always return the latest cached data + if (xSemaphoreTake(waterDataMutex, pdMS_TO_TICKS(10)) == pdTRUE) { + result = latestWaterDataCache; // Copy the latest data + xSemaphoreGive(waterDataMutex); + return result; } - // Return default values if queue is empty - latestData.level = 0.0f; - latestData.liters = 0.0f; - latestData.percentage = 0.0f; - return latestData; + // Fallback: if mutex fails, return default values + result.level = 0.0f; + result.liters = 0.0f; + result.percentage = 0.0f; + return result; } \ No newline at end of file diff --git a/src/global_data/water_data_queue.h b/src/global_data/water_data_queue.h index e9ab5b6..c0e13fa 100644 --- a/src/global_data/water_data_queue.h +++ b/src/global_data/water_data_queue.h @@ -1,12 +1,16 @@ #pragma once #include "global_data.h" -#include "freertos/queue.h" +#include "freertos/semphr.h" -// Create a queue handle for WaterData -extern QueueHandle_t waterDataQueue; +// Mutex and cache for thread-safe water data access +extern SemaphoreHandle_t waterDataMutex; +extern WaterData latestWaterDataCache; -// Initialize the water data queue -void initWaterDataQueue(); +// Initialize the water data synchronization +void initWaterDataSync(); -// Helper function to get latest water data -WaterData getLatestWaterData(); \ No newline at end of file +// Helper function to get latest water data (always returns most recent) +WaterData getLatestWaterData(); + +// Internal function for producer to update latest data +void updateLatestWaterData(const WaterData& newData); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f293d34..ea376a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,8 +60,8 @@ void setup() LOG(ELOG_LEVEL_DEBUG, "Init Sensor"); init_sensor(); - LOG(ELOG_LEVEL_DEBUG, "Init Water Data Queue"); - initWaterDataQueue(); + LOG(ELOG_LEVEL_DEBUG, "Init Water Data Sync"); + initWaterDataSync(); LOG(ELOG_LEVEL_DEBUG, "Beginning LittleFS"); LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED); diff --git a/src/sensor/sensor.cpp b/src/sensor/sensor.cpp index f974b3a..3cdebba 100644 --- a/src/sensor/sensor.cpp +++ b/src/sensor/sensor.cpp @@ -106,16 +106,14 @@ void read_sensor_task(void* parameter) shunt_data.shunt_voltage = shunt_voltage; shunt_data.shunt_current = shunt_current; - // Create water data structure and send to queue + // Create water data structure and update latest data WaterData current_water_data; current_water_data.level = cm_over_zero; current_water_data.liters = liters; current_water_data.percentage = percentage_rounded; - // Send to queue, don't block if queue is full - if (waterDataQueue != nullptr) { - xQueueSendToBack(waterDataQueue, ¤t_water_data, 0); - } + // Update the latest water data (thread-safe) + updateLatestWaterData(current_water_data); delay(20000); }