#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_log.h" #include #include "inputs.h" #define MAX_DN18B20_SENSORS 4U 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; const onewire_addr_t uReturnFlowTempSensorAddr = 0xa7a8e1531f64ff28; onewire_addr_t uOneWireAddresses[MAX_DN18B20_SENSORS]; float fDS18B20Temps[MAX_DN18B20_SENSORS]; size_t sSensorCount = 0U; static SemaphoreHandle_t xMutexAccessInputs = NULL; static eBurnerErrorState sBurnerErrorState; static float fChamperTemperature; static float fOutdoorTemperature; static float fInletFlowTemperature; static float fReturnFlowTemperature; void taskInput(void *pvParameters); void initInputs(void) { gpio_config_t ioConfBurnerFault = { .pin_bit_mask = (1ULL << uBurnerFaultPin), // Pin mask .mode = GPIO_MODE_INPUT, // Set as inout .pull_up_en = GPIO_PULLUP_ENABLE, // Enable pull-up .pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down .intr_type = GPIO_INTR_DISABLE // Disable interrupts }; gpio_config(&ioConfBurnerFault); xMutexAccessInputs = xSemaphoreCreateBinary(); if (xMutexAccessInputs == NULL) { ESP_LOGE(TAG, "Unable to create mutex"); } xSemaphoreGive(xMutexAccessInputs); BaseType_t taskCreated = xTaskCreate( taskInput, // Function to implement the task "taskInput", // Task name 2048, // 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) ); if (taskCreated == pdPASS) { ESP_LOGI(TAG, "Task created successfully!"); } else { ESP_LOGE(TAG, "Failed to create task"); } } void taskInput(void *pvParameters) { while (1) { ESP_LOGI(TAG, "Running task Input..."); vTaskDelay(1000U / portTICK_PERIOD_MS); if (gpio_get_level(uBurnerFaultPin) == 1) { sBurnerErrorState = FAULT; } else { sBurnerErrorState = NO_ERROR; } if (ds18x20_scan_devices(uDS18B20Pin, uOneWireAddresses, MAX_DN18B20_SENSORS, &sSensorCount) != ESP_OK) { ESP_LOGE(TAG, "1-Wire device scan error!"); } if (!sSensorCount) { ESP_LOGW(TAG, "No 1-Wire devices detected!"); } else { ESP_LOGI(TAG, "%d 1-Wire devices detected", sSensorCount); if (sSensorCount > MAX_DN18B20_SENSORS) { sSensorCount = MAX_DN18B20_SENSORS; ESP_LOGW(TAG, "More 1-Wire devices found than expected!"); } if (ds18x20_measure_and_read_multi(uDS18B20Pin, uOneWireAddresses, sSensorCount, fDS18B20Temps) != ESP_OK) { ESP_LOGE(TAG, "1-Wire devices read error"); } else { for (int j = 0; j < sSensorCount; j++) { float temp_c = fDS18B20Temps[j]; ESP_LOGI(TAG, "Sensor: %08" PRIx64 " reports %.3f°C", (uint64_t)uOneWireAddresses[j], temp_c); if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { switch ((uint64_t)uOneWireAddresses[j]) { case ((uint64_t)uChamperTempSensorAddr): fChamperTemperature = temp_c; break; case ((uint64_t)uOutdoorTempSensorAddr): fOutdoorTemperature = temp_c; break; case ((uint64_t)uInletFlowTempSensorAddr): fInletFlowTemperature = temp_c; break; case ((uint64_t)uReturnFlowTempSensorAddr): fReturnFlowTemperature = temp_c; break; default: break; } xSemaphoreGive(xMutexAccessInputs); } } } } } } float getChamberTemperature(void) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { ret = fChamperTemperature; xSemaphoreGive(xMutexAccessInputs); } return ret; } float getOutdoorTemperature(void) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { ret = fOutdoorTemperature; xSemaphoreGive(xMutexAccessInputs); } return ret; } float getInletFlowTemperature(void) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { ret = fInletFlowTemperature; xSemaphoreGive(xMutexAccessInputs); } return ret; } float getReturnFlowTemperature(void) { float ret = 0.0f; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { ret = fReturnFlowTemperature; xSemaphoreGive(xMutexAccessInputs); } return ret; } eBurnerErrorState getBurnerError(void) { eBurnerErrorState ret = FAULT; if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) { ret = sBurnerErrorState; xSemaphoreGive(xMutexAccessInputs); } return ret; }