Tue, 08 Oct 2019 12:00:31 +0200
Initial import of the CO2 meter application.
/** * @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); } }