Fri, 08 Nov 2019 22:40:15 +0100
Increaded stacksize for the user process. Implemented the network update using the proven brewboard code. Reverted the lock release and display sendbuffer lines to the previous code. The networks status screen uses the wifi lock.
/** * @file task_ds18b20.c * @brief The FreeRTOS task to query the DS18B20 sensors on the * one-wire bus. * 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 DS18B20_RESOLUTION (DS18B20_RESOLUTION_12_BIT) static const char *TAG = "task_ds18b20"; static const char *dsErrors[] = { "Ok", "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 i, num_devices = 0; bool found = false; 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 (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 one-wire bus */ xEventGroupDS18B20 = xEventGroupCreate(); /* * Initialize the one-wire bus. */ 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. */ while (1) { uxBits = xEventGroupWaitBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS, pdFALSE, pdFALSE, portMAX_DELAY ); 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; owb_search_first(owb, &search_state, &found); while (found) { 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) { /* * 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(devices[0]); // Read the results immediatly after conversion. float readings[DS18B20_MAX] = { 0 }; DS18B20_ERROR errors[DS18B20_MAX] = { 0 }; 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->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 if (readings[i] == 85.0) { // Error value ds18b20_state->sensor[i].error = DS18B20_ERR_READ; 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 { ESP_LOGE(TAG, "Missed lock 1"); } } else { 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); } else { ESP_LOGE(TAG, "Missed lock 2"); } xEventGroupClearBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS); xEventGroupSetBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_DONE); } } }