main/task_ds18b20.c

Tue, 03 Oct 2023 17:24:06 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 03 Oct 2023 17:24:06 +0200
changeset 77
15dc572a7fcb
parent 61
a322cfcff6b8
permissions
-rw-r--r--

Version 0.3.0. Backported network code from experimental roaming project. Will now connect after reset to the strongest AP. Id the signal level drops below -67, extra scans are done to see for a better AP. Nothing is done yet. Removed config.conf file, all info is taken from the project menu and live tests. Better log the board type and send it via json mqtt. Send bssid and current channel too.

/**
 * @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)		///< GPIO pin for the one-wire bus.
#define DS18B20_RESOLUTION	(DS18B20_RESOLUTION_12_BIT)	///< Desired DS18B20 resolution.


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

extern uint32_t			err_temp;

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, "Start 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_LOGD(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
        	ESP_LOGI(TAG, "  %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;
			    err_temp++;
			} 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;
			    err_temp++;
			} 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