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 |