main/task_ds18b20.c

Fri, 08 Nov 2019 22:40:15 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 08 Nov 2019 22:40:15 +0100
changeset 26
8a3696620c0a
parent 23
58a328e91881
child 28
6d825e2962e4
permissions
-rw-r--r--

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);
	}
    }
}

mercurial