Wed, 03 Jul 2024 20:01:31 +0200
Version 0.4.2. Removed the components/websocket server and switched to the official http and websockets server. This server will also recover if the wifi connection disconnects and reconnects.
0 | 1 | /** |
2 | * @file task_ds18b20.c | |
4 | 3 | * @brief The FreeRTOS task to query the DS18B20 sensors on one or two |
4 | * one-wire busses. Each bus must have only one sensor. That way | |
5 | * we don't need to care about the DS18B20 internal ROM address. | |
6 | * The task will update the DS18B20_State structure. | |
0 | 7 | */ |
8 | ||
9 | ||
10 | #include "owb.h" | |
11 | #include "owb_rmt.h" | |
12 | #include "ds18b20.h" | |
13 | #include "config.h" | |
14 | ||
15 | ||
16 | #ifdef CONFIG_TEMP_SENSORS_ONEWIRE | |
17 | #define GPIO_DS18B20_MLT (CONFIG_ONE_WIRE_MLT) | |
18 | #define GPIO_DS18B20_HLT (CONFIG_ONE_WIRE_HLT) | |
19 | #define MAX_DEVICES (8) | |
20 | #define DS18B20_RESOLUTION (DS18B20_RESOLUTION_12_BIT) | |
21 | #define SAMPLE_PERIOD (2000) // milliseconds | |
22 | #endif | |
23 | ||
24 | #ifdef CONFIG_TEMP_SENSORS_SIMULATOR | |
25 | #define SAMPLE_PERIOD (750) // milliseconds | |
26 | ||
27 | float Fake_MLT = 18.90; | |
28 | float Fake_HLT = 18.70; | |
103
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
29 | extern double Output; |
142
1f7069278fe7
Version 0.4.2. Removed the components/websocket server and switched to the official http and websockets server. This server will also recover if the wifi connection disconnects and reconnects.
Michiel Broek <mbroek@mbse.eu>
parents:
103
diff
changeset
|
30 | extern my_equipment_t equipment; |
0 | 31 | #endif |
32 | ||
33 | static const char *TAG = "task_ds18b20"; | |
34 | ||
35 | SemaphoreHandle_t xSemaphoreDS18B20 = NULL; | |
36 | DS18B20_State *ds18b20_state; | |
37 | ||
38 | ||
39 | /* | |
40 | * Task to read temperature sensors. | |
41 | */ | |
42 | void task_ds18b20(void *pvParameter) | |
43 | { | |
44 | #ifdef CONFIG_TEMP_SENSORS_ONEWIRE | |
45 | int num_devices = 0; | |
46 | float readings = 0; | |
47 | bool found = false; | |
48 | DS18B20_ERROR errors = 0; | |
49 | TickType_t last_wake_time = xTaskGetTickCount(); | |
50 | ||
51 | ESP_LOGI(TAG, "Starting DS18B20 sensors"); | |
52 | ds18b20_state = malloc(sizeof(DS18B20_State)); | |
53 | ds18b20_state->mlt_valid = ds18b20_state->hlt_valid = false; | |
54 | ds18b20_state->mlt_temperature = ds18b20_state->hlt_temperature = 0.0; | |
55 | ds18b20_state->mlt_error = ds18b20_state->hlt_error = DS18B20_ERR_NOSENSOR; | |
56 | ||
57 | /* | |
58 | * Initialize the MLT and HLT one-wire busses. | |
59 | */ | |
60 | OneWireBus *owb_mlt; | |
61 | OneWireBus *owb_hlt; | |
62 | owb_rmt_driver_info rmt_driver_info_mlt; | |
63 | owb_rmt_driver_info rmt_driver_info_hlt; | |
64 | owb_mlt = owb_rmt_initialize(&rmt_driver_info_mlt, GPIO_DS18B20_MLT, RMT_CHANNEL_1, RMT_CHANNEL_0); | |
65 | owb_hlt = owb_rmt_initialize(&rmt_driver_info_hlt, GPIO_DS18B20_HLT, RMT_CHANNEL_3, RMT_CHANNEL_2); | |
66 | owb_use_crc(owb_mlt, true); // enable CRC check for ROM code | |
67 | owb_use_crc(owb_hlt, true); | |
68 | ||
69 | DS18B20_Info * ds18b20_info = ds18b20_malloc(); | |
70 | ||
71 | /* | |
72 | * Task loop forever. | |
73 | */ | |
74 | while (1) { | |
75 | ||
76 | last_wake_time = xTaskGetTickCount(); | |
77 | ||
78 | num_devices = 0; | |
79 | OneWireBus_SearchState mlt_search_state = {0}; | |
80 | found = false; | |
81 | owb_search_first(owb_mlt, &mlt_search_state, &found); | |
82 | while (found) { | |
83 | ++num_devices; | |
84 | owb_search_next(owb_mlt, &mlt_search_state, &found); | |
85 | } | |
86 | ||
87 | if (num_devices == 1) { | |
88 | ds18b20_init_solo(ds18b20_info, owb_mlt); // only one device on bus | |
89 | ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings | |
90 | ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION); // returns true if ok. | |
91 | ||
92 | // Read temperatures more efficiently by starting conversions on all devices at the same time | |
93 | ds18b20_convert_all(owb_mlt); | |
94 | ds18b20_wait_for_conversion(ds18b20_info); | |
95 | ||
96 | errors = ds18b20_read_temp(ds18b20_info, &readings); | |
97 | ||
98 | if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { | |
99 | if (errors == DS18B20_OK) { | |
100 | ds18b20_state->mlt_error = DS18B20_ERR_NONE; | |
101 | ds18b20_state->mlt_valid = true; | |
102 | ds18b20_state->mlt_temperature = readings; | |
103 | } else { | |
104 | if (errors == DS18B20_ERROR_CRC) | |
105 | ds18b20_state->mlt_error = DS18B20_ERR_CRC; | |
106 | if (errors == DS18B20_ERROR_OWB) | |
107 | ds18b20_state->mlt_error = DS18B20_ERR_READ; | |
108 | if (errors == DS18B20_ERROR_DEVICE) | |
109 | ds18b20_state->mlt_error = DS18B20_ERR_READ; | |
110 | ds18b20_state->mlt_valid = false; | |
111 | ds18b20_state->mlt_temperature = 0.0; | |
112 | } | |
113 | xSemaphoreGive(xSemaphoreDS18B20); | |
114 | } | |
115 | ||
116 | } else { | |
117 | /* | |
118 | * Zero or more then one device, this is an error. | |
119 | */ | |
120 | if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { | |
121 | if (num_devices == 0) | |
122 | ds18b20_state->mlt_error = DS18B20_ERR_NOSENSOR; | |
123 | else | |
124 | ds18b20_state->mlt_error = DS18B20_ERR_TOOMANY; | |
125 | ds18b20_state->mlt_valid = false; | |
126 | ds18b20_state->mlt_temperature = 0.0; | |
127 | xSemaphoreGive(xSemaphoreDS18B20); | |
128 | } | |
129 | } // if num_devices == 1 | |
130 | ||
131 | num_devices = 0; | |
132 | OneWireBus_SearchState hlt_search_state = {0}; | |
133 | found = false; | |
134 | owb_search_first(owb_hlt, &hlt_search_state, &found); | |
135 | while (found) { | |
136 | ++num_devices; | |
137 | owb_search_next(owb_hlt, &hlt_search_state, &found); | |
138 | } | |
139 | ||
140 | if (num_devices == 1) { | |
141 | ds18b20_init_solo(ds18b20_info, owb_hlt); // only one device on bus | |
142 | ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings | |
143 | ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION); | |
144 | ||
145 | // Read temperatures more efficiently by starting conversions on all devices at the same time | |
146 | ds18b20_convert_all(owb_hlt); | |
147 | ds18b20_wait_for_conversion(ds18b20_info); | |
148 | ||
149 | errors = ds18b20_read_temp(ds18b20_info, &readings); | |
150 | ||
151 | if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { | |
152 | if (errors == DS18B20_OK) { | |
153 | ds18b20_state->hlt_error = DS18B20_ERR_NONE; | |
154 | ds18b20_state->hlt_valid = true; | |
155 | ds18b20_state->hlt_temperature = readings; | |
156 | } else { | |
157 | if (errors == DS18B20_ERROR_CRC) | |
158 | ds18b20_state->hlt_error = DS18B20_ERR_CRC; | |
159 | if (errors == DS18B20_ERROR_OWB) | |
160 | ds18b20_state->hlt_error = DS18B20_ERR_READ; | |
161 | if (errors == DS18B20_ERROR_DEVICE) | |
162 | ds18b20_state->hlt_error = DS18B20_ERR_READ; | |
163 | ds18b20_state->hlt_valid = false; | |
164 | ds18b20_state->hlt_temperature = 0.0; | |
165 | } | |
166 | xSemaphoreGive(xSemaphoreDS18B20); | |
167 | } | |
168 | } else { | |
169 | /* | |
170 | * Zero or more then one device, this is an error. | |
171 | */ | |
172 | if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { | |
173 | if (num_devices == 0) | |
174 | ds18b20_state->hlt_error = DS18B20_ERR_NOSENSOR; | |
175 | else | |
176 | ds18b20_state->hlt_error = DS18B20_ERR_TOOMANY; | |
177 | ds18b20_state->hlt_valid = false; | |
178 | ds18b20_state->hlt_temperature = 0.0; | |
179 | xSemaphoreGive(xSemaphoreDS18B20); | |
180 | } | |
181 | } // if num_devices == 1 | |
182 | ||
183 | #if 0 | |
184 | printf("MLT %.3f %d err %s, HLT %.3f, %d err %s\n", | |
185 | ds18b20_state->mlt_temperature, ds18b20_state->mlt_error, (ds18b20_state->mlt_valid) ? "valid":" N/A ", | |
186 | ds18b20_state->hlt_temperature, ds18b20_state->hlt_error, (ds18b20_state->hlt_valid) ? "valid":" N/A "); | |
187 | #endif | |
188 | vTaskDelayUntil(&last_wake_time, SAMPLE_PERIOD / portTICK_PERIOD_MS); | |
189 | } | |
190 | #endif | |
191 | ||
192 | #ifdef CONFIG_TEMP_SENSORS_SIMULATOR | |
193 | ||
194 | float Plate_MLT = 18.90; | |
195 | extern int MLT_pin, HLT_pin; | |
196 | ||
88
7f02dbee58d0
Fix missing log entries. More code space saving.
Michiel Broek <mbroek@mbse.eu>
parents:
4
diff
changeset
|
197 | ESP_LOGI(TAG, "Start Fake sensors"); |
0 | 198 | ds18b20_state = malloc(sizeof(DS18B20_State)); |
199 | ds18b20_state->mlt_valid = ds18b20_state->hlt_valid = true; | |
200 | ds18b20_state->mlt_temperature = 18.90; | |
201 | ds18b20_state->hlt_temperature = 18.70; | |
202 | ds18b20_state->mlt_error = ds18b20_state->hlt_error = DS18B20_ERR_NONE; | |
203 | ||
204 | /* | |
205 | * Task loop forever. Update the temperatures each 750 mSeconds. | |
206 | */ | |
207 | while (1) { | |
208 | ||
209 | /* | |
210 | * Make this fake heater a bit more real by using a simulated heatplate. | |
211 | * We heatup that plate and then transfer the heat to the water. | |
212 | * That way we get a nice overshoot like in real life. | |
213 | */ | |
214 | if (MLT_pin) { | |
215 | if (Plate_MLT < 250.0) | |
216 | Plate_MLT += SAMPLE_PERIOD * 0.001; // Simulate plate upto 250 degrees | |
217 | } else { | |
218 | if (Plate_MLT > Fake_MLT) | |
219 | Plate_MLT -= SAMPLE_PERIOD * 0.00002 * (Plate_MLT - Fake_MLT); | |
220 | } | |
221 | // If plate is hotter then the water with a offset so that cooling later works. | |
222 | if (Plate_MLT > (Fake_MLT + 5.0)) { | |
103
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
223 | if (Fake_MLT < 100.05) { |
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
224 | if (equipment.Hendi) |
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
225 | Fake_MLT += SAMPLE_PERIOD * 0.000001 * (Plate_MLT - Fake_MLT) * (Output / 255.0) * 2; |
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
226 | else |
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
227 | Fake_MLT += SAMPLE_PERIOD * 0.000001 * (Plate_MLT - Fake_MLT); |
1885d0c75c48
Default equipment max_watt set to 2750. Added defaults for new equipment record. Switched PWM timer to high-speed. Implemented the safety timer to prevent the MLT + HLT will draw too much power in shared mode. Removed some code ideas that were not used. The fake heater now uses the faked PWM power.
Michiel Broek <mbroek@mbse.eu>
parents:
88
diff
changeset
|
228 | } |
0 | 229 | } |
230 | // Allways loose heat to the air | |
231 | if (Fake_MLT > 16.0) { | |
232 | Fake_MLT -= SAMPLE_PERIOD * 0.00000010 * (Fake_MLT - 16.0); | |
233 | } | |
234 | ||
235 | if ((equipment.SSR2 == SSR2_HLT_SHARE) || (equipment.SSR2 == SSR2_HLT_IND)) { | |
236 | /* | |
237 | * There is a HLT function configured. | |
238 | */ | |
239 | if (HLT_pin) { | |
240 | if (Fake_HLT < 100.05) | |
241 | Fake_HLT += SAMPLE_PERIOD * 0.000055; | |
242 | } else { | |
243 | if (Fake_HLT > 16.0) | |
244 | Fake_HLT -= SAMPLE_PERIOD * 0.00000006 * (Fake_HLT - 16.0); | |
245 | } | |
246 | } | |
247 | ||
248 | if (xSemaphoreTake(xSemaphoreDS18B20, 25) == pdTRUE) { | |
249 | ds18b20_state->mlt_temperature = ((int)(Fake_MLT * 16)) / 16.0; | |
250 | ds18b20_state->hlt_temperature = ((int)(Fake_HLT * 16)) / 16.0; | |
251 | xSemaphoreGive(xSemaphoreDS18B20); | |
252 | } | |
253 | ||
254 | vTaskDelay(SAMPLE_PERIOD / portTICK_PERIOD_MS); | |
255 | } | |
256 | ||
257 | #endif | |
258 | } | |
259 | ||
260 |