# HG changeset patch # User Michiel Broek # Date 1570907109 -7200 # Node ID d08c7466bb407a540216b539eee2466b8d6d3338 # Parent a85995941d0d11dabe8ea96f62639d29f70f09c3 One-wire bus can now handle multiple sensors. diff -r a85995941d0d -r d08c7466bb40 main/task_ds18b20.c --- a/main/task_ds18b20.c Fri Oct 11 15:56:30 2019 +0200 +++ b/main/task_ds18b20.c Sat Oct 12 21:05:09 2019 +0200 @@ -52,35 +52,32 @@ */ void task_ds18b20(void *pvParameter) { - int num_devices = 0; - float readings = 0; + int i, num_devices = 0; bool found = false; - DS18B20_ERROR errors = 0; + EventBits_t uxBits; ESP_LOGI(TAG, "Starting DS18B20 sensors"); ds18b20_state = malloc(sizeof(DS18B20_State)); ds18b20_state->valid = false; ds18b20_state->num_sensors = 0; - for (int i = 0; i < DS18B20_MAX; i++) { + for (i = 0; i < DS18B20_MAX; i++) { ds18b20_state->sensor[i].temperature = 0.0; ds18b20_state->sensor[i].rom_code[0] = '\0'; ds18b20_state->sensor[i].error = DS18B20_ERR_READ; } - /* event handler and event group for the wifi driver */ + /* + * event handler and event group for the one-wire bus + */ xEventGroupDS18B20 = xEventGroupCreate(); /* - * Initialize the MLT and HLT one-wire busses. + * Initialize the one-wire bus. */ - OneWireBus *owb; - owb_rmt_driver_info rmt_driver_info_bottle; - owb = owb_rmt_initialize(&rmt_driver_info_bottle, GPIO_DS18B20_BUS, RMT_CHANNEL_1, RMT_CHANNEL_0); - owb_use_crc(owb, true); // enable CRC check for ROM code - - DS18B20_Info * ds18b20_info = ds18b20_malloc(); - EventBits_t uxBits; + owb_rmt_driver_info rmt_driver_info_bottle; + OneWireBus *owb = owb_rmt_initialize(&rmt_driver_info_bottle, GPIO_DS18B20_BUS, RMT_CHANNEL_1, RMT_CHANNEL_0); + owb_use_crc(owb, true); /* * Task loop forever. @@ -88,8 +85,10 @@ while (1) { uxBits = xEventGroupWaitBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS, pdFALSE, pdFALSE, portMAX_DELAY ); + if (uxBits & TASK_DS18B20_REQUEST_TEMPS) { - if (uxBits & TASK_DS18B20_REQUEST_TEMPS) { + ESP_LOGI(TAG, "Requested DS18B20 readings"); + OneWireBus_ROMCode device_rom_codes[DS18B20_MAX] = {0}; num_devices = 0; OneWireBus_SearchState search_state = {0}; found = false; @@ -98,62 +97,90 @@ char rom_code_s[17]; owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s)); rom_code_s[16] = '\0'; +#if 0 printf(" %d : %s %d\n", num_devices + 1, rom_code_s, strlen(rom_code_s)); +#endif + device_rom_codes[num_devices] = search_state.rom_code; strncpy(ds18b20_state->sensor[num_devices].rom_code, rom_code_s, 17); ++num_devices; owb_search_next(owb, &search_state, &found); } - if (num_devices == 1) { - ds18b20_init_solo(ds18b20_info, owb); // 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. + if (num_devices) { + /* + * Create DS18B20 devices on the bus + */ + DS18B20_Info * devices[DS18B20_MAX] = {0}; + for (i = 0; i < num_devices; ++i) { + DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation + devices[i] = ds18b20_info; + + if (num_devices == 1) { + ds18b20_init_solo(ds18b20_info, owb); // only one device on bus + } else { + ds18b20_init(ds18b20_info, owb, device_rom_codes[i]); // associate with bus and device + } + ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings + ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION); + } // Read temperatures more efficiently by starting conversions on all devices at the same time ds18b20_convert_all(owb); - ds18b20_wait_for_conversion(ds18b20_info); + ds18b20_wait_for_conversion(devices[0]); + + // Read the results immediatly after conversion. + float readings[DS18B20_MAX] = { 0 }; + DS18B20_ERROR errors[DS18B20_MAX] = { 0 }; - errors = ds18b20_read_temp(ds18b20_info, &readings); + for (i = 0; i < num_devices; ++i) { + errors[i] = ds18b20_read_temp(devices[i], &readings[i]); + } + // Process the results with a locked semaphore if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { - ds18b20_state->num_sensors = 1; - if (errors == DS18B20_OK) { - ds18b20_state->sensor[0].error = DS18B20_ERR_NONE; - ds18b20_state->valid = true; - ds18b20_state->sensor[0].temperature = readings; - } else { - if (errors == DS18B20_ERROR_CRC) - ds18b20_state->sensor[0].error = DS18B20_ERR_CRC; - else - ds18b20_state->sensor[0].error = DS18B20_ERR_READ; // All other errors - ds18b20_state->valid = false; - ds18b20_state->sensor[0].temperature = 0.0; - } + ds18b20_state->valid = true; + for (i = 0; i < num_devices; ++i) { + if (errors[i] != DS18B20_OK) { + if (errors[i] == DS18B20_ERROR_CRC) + ds18b20_state->sensor[i].error = DS18B20_ERR_CRC; + else + ds18b20_state->sensor[i].error = DS18B20_ERR_READ; // All other errors + ds18b20_state->valid = false; + ds18b20_state->sensor[i].temperature = 0.0; + } else { + ds18b20_state->sensor[i].error = DS18B20_ERR_NONE; + ds18b20_state->sensor[i].temperature = readings[i]; + } +#if 1 + ESP_LOGI(TAG, "Temperature %d %s %.4f %s", i, ds18b20_state->sensor[i].rom_code, + ds18b20_state->sensor[i].temperature, dsErrors[ds18b20_state->sensor[i].error]); +#endif + } + ds18b20_state->num_sensors = num_devices; xSemaphoreGive(xSemaphoreDS18B20); - } - + } } else { - /* - * Zero or more then one device, this is an error. - */ - if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { - if (num_devices == 0) - ds18b20_state->sensor[0].error = DS18B20_ERR_READ; - else - ds18b20_state->sensor[0].error = DS18B20_ERR_READ; - ds18b20_state->valid = false; - ds18b20_state->num_sensors = 0; - xSemaphoreGive(xSemaphoreDS18B20); - } - } // if num_devices == 1 + + ESP_LOGW(TAG, "No temperature sensors found."); + } + + /* + * Set the remainder of the ds18b20 entries + */ + if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { + ds18b20_state->num_sensors = num_devices; + for (i = num_devices; i < DS18B20_MAX; i++) { + ds18b20_state->sensor[i].temperature = 0.0; + ds18b20_state->sensor[i].rom_code[0] = '\0'; + ds18b20_state->sensor[i].error = DS18B20_ERR_READ; + } + xSemaphoreGive(xSemaphoreDS18B20); + } xEventGroupClearBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS); xEventGroupSetBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_DONE); -#if 1 - ESP_LOGI(TAG, "Temperature %.3f %s", ds18b20_state->sensor[0].temperature, dsErrors[ds18b20_state->sensor[0].error]); -#endif } - vTaskDelay( (TickType_t)10); + vTaskDelay(10 / portTICK_PERIOD_MS); } }