main/task_ds18b20.c

changeset 10
d08c7466bb40
parent 5
4b1c65e4d863
child 12
7dc9003f86a8
equal deleted inserted replaced
9:a85995941d0d 10:d08c7466bb40
50 /* 50 /*
51 * Task to read temperature sensors on request. 51 * Task to read temperature sensors on request.
52 */ 52 */
53 void task_ds18b20(void *pvParameter) 53 void task_ds18b20(void *pvParameter)
54 { 54 {
55 int num_devices = 0; 55 int i, num_devices = 0;
56 float readings = 0;
57 bool found = false; 56 bool found = false;
58 DS18B20_ERROR errors = 0; 57 EventBits_t uxBits;
59 58
60 ESP_LOGI(TAG, "Starting DS18B20 sensors"); 59 ESP_LOGI(TAG, "Starting DS18B20 sensors");
61 ds18b20_state = malloc(sizeof(DS18B20_State)); 60 ds18b20_state = malloc(sizeof(DS18B20_State));
62 ds18b20_state->valid = false; 61 ds18b20_state->valid = false;
63 ds18b20_state->num_sensors = 0; 62 ds18b20_state->num_sensors = 0;
64 63
65 for (int i = 0; i < DS18B20_MAX; i++) { 64 for (i = 0; i < DS18B20_MAX; i++) {
66 ds18b20_state->sensor[i].temperature = 0.0; 65 ds18b20_state->sensor[i].temperature = 0.0;
67 ds18b20_state->sensor[i].rom_code[0] = '\0'; 66 ds18b20_state->sensor[i].rom_code[0] = '\0';
68 ds18b20_state->sensor[i].error = DS18B20_ERR_READ; 67 ds18b20_state->sensor[i].error = DS18B20_ERR_READ;
69 } 68 }
70 69
71 /* event handler and event group for the wifi driver */ 70 /*
71 * event handler and event group for the one-wire bus
72 */
72 xEventGroupDS18B20 = xEventGroupCreate(); 73 xEventGroupDS18B20 = xEventGroupCreate();
73 74
74 /* 75 /*
75 * Initialize the MLT and HLT one-wire busses. 76 * Initialize the one-wire bus.
76 */ 77 */
77 OneWireBus *owb; 78 owb_rmt_driver_info rmt_driver_info_bottle;
78 owb_rmt_driver_info rmt_driver_info_bottle; 79 OneWireBus *owb = owb_rmt_initialize(&rmt_driver_info_bottle, GPIO_DS18B20_BUS, RMT_CHANNEL_1, RMT_CHANNEL_0);
79 owb = owb_rmt_initialize(&rmt_driver_info_bottle, GPIO_DS18B20_BUS, RMT_CHANNEL_1, RMT_CHANNEL_0); 80 owb_use_crc(owb, true);
80 owb_use_crc(owb, true); // enable CRC check for ROM code
81
82 DS18B20_Info * ds18b20_info = ds18b20_malloc();
83 EventBits_t uxBits;
84 81
85 /* 82 /*
86 * Task loop forever. 83 * Task loop forever.
87 */ 84 */
88 while (1) { 85 while (1) {
89 86
90 uxBits = xEventGroupWaitBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS, pdFALSE, pdFALSE, portMAX_DELAY ); 87 uxBits = xEventGroupWaitBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS, pdFALSE, pdFALSE, portMAX_DELAY );
88 if (uxBits & TASK_DS18B20_REQUEST_TEMPS) {
91 89
92 if (uxBits & TASK_DS18B20_REQUEST_TEMPS) { 90 ESP_LOGI(TAG, "Requested DS18B20 readings");
91 OneWireBus_ROMCode device_rom_codes[DS18B20_MAX] = {0};
93 num_devices = 0; 92 num_devices = 0;
94 OneWireBus_SearchState search_state = {0}; 93 OneWireBus_SearchState search_state = {0};
95 found = false; 94 found = false;
96 owb_search_first(owb, &search_state, &found); 95 owb_search_first(owb, &search_state, &found);
97 while (found) { 96 while (found) {
98 char rom_code_s[17]; 97 char rom_code_s[17];
99 owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s)); 98 owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s));
100 rom_code_s[16] = '\0'; 99 rom_code_s[16] = '\0';
100 #if 0
101 printf(" %d : %s %d\n", num_devices + 1, rom_code_s, strlen(rom_code_s)); 101 printf(" %d : %s %d\n", num_devices + 1, rom_code_s, strlen(rom_code_s));
102 #endif
103 device_rom_codes[num_devices] = search_state.rom_code;
102 strncpy(ds18b20_state->sensor[num_devices].rom_code, rom_code_s, 17); 104 strncpy(ds18b20_state->sensor[num_devices].rom_code, rom_code_s, 17);
103 ++num_devices; 105 ++num_devices;
104 owb_search_next(owb, &search_state, &found); 106 owb_search_next(owb, &search_state, &found);
105 } 107 }
106 108
107 if (num_devices == 1) { 109 if (num_devices) {
108 ds18b20_init_solo(ds18b20_info, owb); // only one device on bus 110 /*
109 ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings 111 * Create DS18B20 devices on the bus
110 ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION); // returns true if ok. 112 */
113 DS18B20_Info * devices[DS18B20_MAX] = {0};
114 for (i = 0; i < num_devices; ++i) {
115 DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation
116 devices[i] = ds18b20_info;
117
118 if (num_devices == 1) {
119 ds18b20_init_solo(ds18b20_info, owb); // only one device on bus
120 } else {
121 ds18b20_init(ds18b20_info, owb, device_rom_codes[i]); // associate with bus and device
122 }
123 ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings
124 ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION);
125 }
111 126
112 // Read temperatures more efficiently by starting conversions on all devices at the same time 127 // Read temperatures more efficiently by starting conversions on all devices at the same time
113 ds18b20_convert_all(owb); 128 ds18b20_convert_all(owb);
114 ds18b20_wait_for_conversion(ds18b20_info); 129 ds18b20_wait_for_conversion(devices[0]);
115 130
116 errors = ds18b20_read_temp(ds18b20_info, &readings); 131 // Read the results immediatly after conversion.
132 float readings[DS18B20_MAX] = { 0 };
133 DS18B20_ERROR errors[DS18B20_MAX] = { 0 };
117 134
135 for (i = 0; i < num_devices; ++i) {
136 errors[i] = ds18b20_read_temp(devices[i], &readings[i]);
137 }
138
139 // Process the results with a locked semaphore
118 if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { 140 if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) {
119 ds18b20_state->num_sensors = 1; 141 ds18b20_state->valid = true;
120 if (errors == DS18B20_OK) { 142 for (i = 0; i < num_devices; ++i) {
121 ds18b20_state->sensor[0].error = DS18B20_ERR_NONE; 143 if (errors[i] != DS18B20_OK) {
122 ds18b20_state->valid = true; 144 if (errors[i] == DS18B20_ERROR_CRC)
123 ds18b20_state->sensor[0].temperature = readings; 145 ds18b20_state->sensor[i].error = DS18B20_ERR_CRC;
124 } else { 146 else
125 if (errors == DS18B20_ERROR_CRC) 147 ds18b20_state->sensor[i].error = DS18B20_ERR_READ; // All other errors
126 ds18b20_state->sensor[0].error = DS18B20_ERR_CRC; 148 ds18b20_state->valid = false;
127 else 149 ds18b20_state->sensor[i].temperature = 0.0;
128 ds18b20_state->sensor[0].error = DS18B20_ERR_READ; // All other errors 150 } else {
129 ds18b20_state->valid = false; 151 ds18b20_state->sensor[i].error = DS18B20_ERR_NONE;
130 ds18b20_state->sensor[0].temperature = 0.0; 152 ds18b20_state->sensor[i].temperature = readings[i];
131 } 153 }
154 #if 1
155 ESP_LOGI(TAG, "Temperature %d %s %.4f %s", i, ds18b20_state->sensor[i].rom_code,
156 ds18b20_state->sensor[i].temperature, dsErrors[ds18b20_state->sensor[i].error]);
157 #endif
158 }
159 ds18b20_state->num_sensors = num_devices;
132 xSemaphoreGive(xSemaphoreDS18B20); 160 xSemaphoreGive(xSemaphoreDS18B20);
133 } 161 }
162 } else {
134 163
135 } else { 164 ESP_LOGW(TAG, "No temperature sensors found.");
136 /* 165 }
137 * Zero or more then one device, this is an error. 166
138 */ 167 /*
139 if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { 168 * Set the remainder of the ds18b20 entries
140 if (num_devices == 0) 169 */
141 ds18b20_state->sensor[0].error = DS18B20_ERR_READ; 170 if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) {
142 else 171 ds18b20_state->num_sensors = num_devices;
143 ds18b20_state->sensor[0].error = DS18B20_ERR_READ; 172 for (i = num_devices; i < DS18B20_MAX; i++) {
144 ds18b20_state->valid = false; 173 ds18b20_state->sensor[i].temperature = 0.0;
145 ds18b20_state->num_sensors = 0; 174 ds18b20_state->sensor[i].rom_code[0] = '\0';
146 xSemaphoreGive(xSemaphoreDS18B20); 175 ds18b20_state->sensor[i].error = DS18B20_ERR_READ;
147 } 176 }
148 } // if num_devices == 1 177 xSemaphoreGive(xSemaphoreDS18B20);
178 }
149 179
150 xEventGroupClearBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS); 180 xEventGroupClearBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_TEMPS);
151 xEventGroupSetBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_DONE); 181 xEventGroupSetBits(xEventGroupDS18B20, TASK_DS18B20_REQUEST_DONE);
152 #if 1
153 ESP_LOGI(TAG, "Temperature %.3f %s", ds18b20_state->sensor[0].temperature, dsErrors[ds18b20_state->sensor[0].error]);
154 #endif
155 } 182 }
156 vTaskDelay( (TickType_t)10); 183 vTaskDelay(10 / portTICK_PERIOD_MS);
157 } 184 }
158 } 185 }
159 186

mercurial