diff -r 000000000000 -r 88d965579617 main/task_ds18b20.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/task_ds18b20.c Tue Oct 08 12:00:31 2019 +0200 @@ -0,0 +1,152 @@ +/** + * @file task_ds18b20.c + * @brief The FreeRTOS task to query the DS18B20 sensors on one or two + * one-wire busses. Each bus must have only one sensor. That way + * we don't need to care about the DS18B20 internal ROM address. + * The task will update the DS18B20_State structure. + */ + + +#include "owb.h" +#include "owb_rmt.h" +#include "ds18b20.h" +#include "config.h" + + +#define GPIO_DS18B20_BUS (CONFIG_ONE_WIRE_BUS) +#define MAX_DEVICES (8) +#define DS18B20_RESOLUTION (DS18B20_RESOLUTION_12_BIT) +#define SAMPLE_PERIOD (2000) // milliseconds + + +static const char *TAG = "task_ds18b20"; +static const char *dsErrors[] = { "Ok", "No sensor", "Too many sensors", "CRC error", "Read error" }; + +SemaphoreHandle_t xSemaphoreDS18B20 = NULL; ///< Semaphire DS18B20 task +EventGroupHandle_t xEventGroupDS18B20; ///< Events DS18B20 task +DS18B20_State *ds18b20_state; ///< Public state for other tasks + + +const int TASK_DS18B20_REQUEST_TEMPS = BIT0; ///< Request temperature measurements +const int TASK_DS18B20_REQUEST_DONE = BIT1; ///< Request is completed + + + +void request_ds18b20(void) +{ + xEventGroupClearBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_DONE); + xEventGroupSetBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS); +} + + + +bool ready_ds18b20(void) +{ + if (xEventGroupGetBits(xEventGroupDS18B20) & TASK_DS18B20_REQUEST_DONE) + return true; + return false; +} + + + +/* + * Task to read temperature sensors on request. + */ +void task_ds18b20(void *pvParameter) +{ + int num_devices = 0; + float readings = 0; + bool found = false; + DS18B20_ERROR errors = 0; + + ESP_LOGI(TAG, "Starting DS18B20 sensors"); + ds18b20_state = malloc(sizeof(DS18B20_State)); + ds18b20_state->bottle_valid = false; + ds18b20_state->bottle_temperature = 0.0; + ds18b20_state->bottle_error = DS18B20_ERR_NOSENSOR; + + /* event handler and event group for the wifi driver */ + xEventGroupDS18B20 = xEventGroupCreate(); + + /* + * Initialize the MLT and HLT one-wire busses. + */ + OneWireBus *owb_bottle; + owb_rmt_driver_info rmt_driver_info_bottle; + owb_bottle = owb_rmt_initialize(&rmt_driver_info_bottle, GPIO_DS18B20_BUS, RMT_CHANNEL_1, RMT_CHANNEL_0); + owb_use_crc(owb_bottle, true); // enable CRC check for ROM code + + DS18B20_Info * ds18b20_info = ds18b20_malloc(); + EventBits_t uxBits; + + /* + * Task loop forever. + */ + while (1) { + + uxBits = xEventGroupWaitBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS, pdFALSE, pdFALSE, portMAX_DELAY ); + + if (uxBits & TASK_DS18B20_REQUEST_TEMPS) { + num_devices = 0; + OneWireBus_SearchState bottle_search_state = {0}; + found = false; + owb_search_first(owb_bottle, &bottle_search_state, &found); + while (found) { + ++num_devices; + owb_search_next(owb_bottle, &bottle_search_state, &found); + } + + if (num_devices == 1) { + ds18b20_init_solo(ds18b20_info, owb_bottle); // only one device on bus + ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings + ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION); // returns true if ok. + + // Read temperatures more efficiently by starting conversions on all devices at the same time + ds18b20_convert_all(owb_bottle); + ds18b20_wait_for_conversion(ds18b20_info); + + errors = ds18b20_read_temp(ds18b20_info, &readings); + + if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { + if (errors == DS18B20_OK) { + ds18b20_state->bottle_error = DS18B20_ERR_NONE; + ds18b20_state->bottle_valid = true; + ds18b20_state->bottle_temperature = readings; + } else { + if (errors == DS18B20_ERROR_CRC) + ds18b20_state->bottle_error = DS18B20_ERR_CRC; + if (errors == DS18B20_ERROR_OWB) + ds18b20_state->bottle_error = DS18B20_ERR_READ; + if (errors == DS18B20_ERROR_DEVICE) + ds18b20_state->bottle_error = DS18B20_ERR_READ; + ds18b20_state->bottle_valid = false; + ds18b20_state->bottle_temperature = 0.0; + } + xSemaphoreGive(xSemaphoreDS18B20); + } + + } else { + /* + * Zero or more then one device, this is an error. + */ + if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { + if (num_devices == 0) + ds18b20_state->bottle_error = DS18B20_ERR_NOSENSOR; + else + ds18b20_state->bottle_error = DS18B20_ERR_TOOMANY; + ds18b20_state->bottle_valid = false; + ds18b20_state->bottle_temperature = 0.0; + xSemaphoreGive(xSemaphoreDS18B20); + } + } // if num_devices == 1 + + xEventGroupClearBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS); + xEventGroupSetBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_DONE); +#if 1 + ESP_LOGI(TAG, "Temperature %.3f %s", ds18b20_state->bottle_temperature, dsErrors[ds18b20_state->bottle_error]); +#endif + } + vTaskDelay( (TickType_t)10); + } +} +