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