Thu, 25 Oct 2018 21:10:29 +0200
Version 0.2.5. Removed debug console messages during recipe import. Removed old SyncDirs code to install /spiffs from the SD card since we now do this via the internet.
0 | 1 | /** |
2 | * @file task_tft.c | |
4 | 3 | * @brief BrewBoard TFT and Touch screen driver for a 320x240 ILI9341 based display. |
4 | * But because the application is controlled using the touch screen, all the | |
5 | * processing of menus is also found here. | |
6 | * It's the first started task, but it does nothing until the Main_Screen | |
7 | * variable is set. | |
0 | 8 | */ |
9 | ||
10 | #include "config.h" | |
11 | ||
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
12 | spi_lobo_device_handle_t spi; ///< TFT screen SPI handler |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
13 | spi_lobo_device_handle_t tsspi = NULL; ///< Touchscreen SPI handler |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
14 | extern sButton Buttons[MAXBUTTONS]; ///< 40 buttons on a screen. |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
15 | time_t now; ///< Current time |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
16 | struct tm timeinfo; ///< Current time structure |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
17 | char s_timer[10]; ///< Timer sctring buffer |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
18 | char s_top_msg[64]; ///< Top message string buffer |
0 | 19 | |
20 | extern float stageTemp; | |
21 | extern uint16_t stageTime; | |
22 | extern uint16_t TimeWhirlPool; | |
23 | extern uint32_t TimeLeft; | |
24 | extern uint32_t TimeSpent; | |
25 | extern uint32_t SecsCount; | |
26 | extern uint32_t pumpTime; | |
27 | extern uint32_t TimeBrewing; | |
28 | extern uint16_t Steady; | |
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
29 | esp_timer_handle_t timerHandle; ///< Timer handler |
0 | 30 | extern bool _NewMinute; |
31 | extern bool _UseHLT; | |
32 | extern bool System_TimeOk; | |
33 | ||
34 | static const char *TAG = "task_tft"; | |
35 | ||
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
36 | #define SPI_BUS TFT_HSPI_HOST ///< SPI bus for the TFT, TFT_VSPI_HOST or TFT_HSPI_HOST |
0 | 37 | |
38 | extern int Main_Screen; | |
39 | extern int Old_Screen; | |
40 | extern int MLT_pin; | |
41 | extern int HLT_pin; | |
42 | extern int Pump_pin; | |
43 | extern DS18B20_State *ds18b20_state; | |
44 | extern DRIVER_State *driver_state; | |
45 | extern JSON_log *json_log; | |
46 | extern SemaphoreHandle_t xSemaphoreDS18B20; | |
47 | extern SemaphoreHandle_t xSemaphoreDriver; | |
48 | extern SemaphoreHandle_t xSemaphoreWiFi; | |
49 | extern WIFI_State *wifi_state; | |
50 | extern double Output; | |
51 | extern sButton Buttons[MAXBUTTONS]; | |
52 | ||
53 | extern int BoilPower, LastMashStep; | |
54 | extern char temp_buf[], logline[], strftime_buf[64]; | |
55 | extern bool loop, CoolBeep, Resume, pumpRest, updateRuntime; | |
56 | extern bool NewMinute, TempReached; | |
57 | extern uint8_t MashState; | |
58 | extern float temp_MLT, MinMash, MaxMash; | |
59 | extern uint32_t power_MLT, power_HLT, counts; | |
60 | ||
61 | ||
62 | #ifdef CONFIG_TEMP_SENSORS_SIMULATOR | |
63 | extern float Fake_MLT; | |
64 | extern float Fake_HLT; | |
65 | #endif | |
66 | ||
67 | ||
68 | ||
69 | /** | |
70 | * @brief Seconds timer callback. | |
71 | */ | |
72 | void TimerCallback(void *arg); | |
73 | ||
74 | ||
75 | /***************************************************************************/ | |
76 | ||
77 | ||
78 | ||
79 | int init_tft_display(void) | |
80 | { | |
81 | esp_err_t ret; | |
82 | esp_timer_create_args_t timerSecond = { | |
83 | .callback = &TimerCallback, | |
84 | .name = "SecondsTimer" | |
85 | }; | |
86 | ||
87 | ESP_LOGI(TAG, "Initialize TFT"); | |
88 | ||
89 | max_rdclock = 8000000; | |
90 | TFT_PinsInit(); | |
91 | ||
92 | spi_lobo_bus_config_t buscfg = { | |
93 | .miso_io_num=PIN_NUM_MISO, // set SPI MISO pin | |
94 | .mosi_io_num=PIN_NUM_MOSI, // set SPI MOSI pin | |
95 | .sclk_io_num=PIN_NUM_CLK, // set SPI CLK pin | |
96 | .quadwp_io_num=-1, | |
97 | .quadhd_io_num=-1, | |
98 | .max_transfer_sz = 6*1024, | |
99 | }; | |
100 | spi_lobo_device_interface_config_t devcfg={ | |
101 | .clock_speed_hz=8000000, // Initial clock out at 8 MHz | |
102 | .mode=0, // SPI mode 0 | |
103 | .spics_io_num=-1, // we will use external CS pin | |
104 | .spics_ext_io_num=PIN_NUM_CS, // external CS pin | |
105 | .flags=LB_SPI_DEVICE_HALFDUPLEX, // ALWAYS SET to HALF DUPLEX MODE!! for display spi | |
106 | }; | |
107 | spi_lobo_device_interface_config_t tsdevcfg={ | |
108 | .clock_speed_hz=2500000, //Clock out at 2.5 MHz | |
109 | .mode=0, //SPI mode 0 | |
110 | .spics_io_num=PIN_NUM_TCS, //Touch CS pin | |
111 | .spics_ext_io_num=-1, //Not using the external CS | |
112 | }; | |
113 | ||
114 | ESP_LOGI(TAG, "TFT pins: miso=%d, mosi=%d, sck=%d, cs=%d", PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK, PIN_NUM_CS); | |
115 | ||
116 | ret = spi_lobo_bus_add_device(SPI_BUS, &buscfg, &devcfg, &spi); | |
117 | assert(ret == ESP_OK); | |
118 | disp_spi = spi; | |
119 | ||
120 | // ==== Test select/deselect ==== | |
121 | ret = spi_lobo_device_select(spi, 1); | |
122 | assert(ret == ESP_OK); | |
123 | ret = spi_lobo_device_deselect(spi); | |
124 | assert(ret == ESP_OK); | |
125 | ||
126 | ESP_LOGI(TAG, "SPI: attached display, spi bus: %d, speed: %u, bus uses native pins: %s", | |
127 | SPI_BUS, spi_lobo_get_speed(spi), spi_lobo_uses_native_pins(spi) ? "true" : "false"); | |
128 | ||
129 | ESP_LOGI(TAG, "TS pins : miso=%d, mosi=%d, sck=%d, cs=%d", PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK, PIN_NUM_TCS); | |
130 | ||
131 | ret=spi_lobo_bus_add_device(SPI_BUS, &buscfg, &tsdevcfg, &tsspi); | |
132 | assert(ret == ESP_OK); | |
133 | ts_spi = tsspi; | |
134 | ||
135 | // ==== Test select/deselect ==== | |
136 | ret = spi_lobo_device_select(tsspi, 1); | |
137 | assert(ret == ESP_OK); | |
138 | ret = spi_lobo_device_deselect(tsspi); | |
139 | assert(ret == ESP_OK); | |
140 | ||
141 | ESP_LOGI(TAG, "SPI: attached TS device, spi bus: %d, speed: %u", SPI_BUS, spi_lobo_get_speed(tsspi)); | |
142 | ||
143 | // ==== Initialize the Display ==== | |
144 | TFT_display_init(); | |
145 | ||
146 | // ---- Detect maximum read speed ---- | |
147 | max_rdclock = find_rd_speed(); | |
148 | ||
149 | // ==== Set SPI clock used for display operations ==== | |
150 | spi_lobo_set_speed(spi, DEFAULT_SPI_CLOCK); | |
151 | ESP_LOGI(TAG, "SPI: Max rd speed: %u, changed speed to %u", max_rdclock, spi_lobo_get_speed(spi)); | |
152 | ||
153 | font_rotate = 0; | |
154 | text_wrap = 0; | |
155 | font_transparent = 0; | |
156 | font_forceFixed = 0; | |
157 | gray_scale = 0; | |
158 | TFT_setGammaCurve(DEFAULT_GAMMA_CURVE); | |
159 | TFT_setRotation(LANDSCAPE); | |
160 | TFT_setFont(DEFAULT_FONT, NULL); | |
161 | TFT_resetclipwin(); | |
162 | ||
163 | /* | |
164 | * Create a one second periodic timer. | |
165 | */ | |
166 | ret = esp_timer_create(&timerSecond, &timerHandle); | |
167 | assert(ret == ESP_OK); | |
168 | ret = esp_timer_start_periodic(timerHandle, 1000000); | |
169 | assert(ret == ESP_OK); | |
170 | ||
171 | return ret; | |
172 | } | |
173 | ||
174 | ||
175 | ||
176 | void TimerCallback(void *arg) | |
177 | { | |
178 | TimeSpent++; | |
179 | SecsCount++; | |
180 | Steady++; | |
181 | TimeBrewing++; | |
182 | runtime.TimeBrewing++; | |
183 | if ((SecsCount % 60) == 0) | |
184 | _NewMinute = true; | |
185 | ||
186 | if (TimeLeft) { | |
187 | TimeLeft--; | |
188 | if (TimeLeft == 5) { | |
189 | SoundPlay(SOUND_TimeOut); | |
190 | } | |
191 | if ((TimeLeft % 60) == 0) { | |
192 | pumpTime++; | |
193 | } | |
194 | } | |
195 | } | |
196 | ||
197 | ||
198 | ||
199 | void TimerSet(uint32_t seconds) | |
200 | { | |
201 | Steady = TimeSpent = SecsCount = 0; | |
202 | TimeLeft = seconds; | |
203 | } | |
204 | ||
205 | ||
206 | ||
207 | void TimerShow(uint32_t Time, int X, int Y) | |
208 | { | |
209 | uint8_t Hours = (uint8_t)(Time / 3600); | |
210 | uint8_t Minutes = (uint8_t)((Time % 3600) / 60); | |
211 | uint8_t Seconds = (uint8_t)(Time % 60); | |
212 | char msg[32]; | |
213 | static uint32_t _oldTime = 0; | |
214 | ||
215 | if (Time != _oldTime) { | |
216 | _fg = TFT_GREEN; | |
217 | TFT_setFont(FONT_7SEG, NULL); | |
218 | set_7seg_font_atrib(12, 2, 1, TFT_DARKGREY); | |
219 | snprintf(s_timer, 9, "%02d:%02d:%02d", Hours, Minutes, Seconds); | |
220 | TFT_print(s_timer, X, Y); | |
221 | _oldTime = Time; | |
222 | snprintf(msg, 31, "{\"timer\":\"%s\"}", s_timer); | |
223 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
224 | } | |
225 | } | |
226 | ||
227 | ||
228 | ||
229 | void TopMessage(char *text) | |
230 | { | |
231 | char msg[64]; | |
232 | ||
233 | snprintf(s_top_msg, 63, "%s", text); | |
234 | _fg = TFT_YELLOW; | |
235 | font_transparent = 1; | |
236 | TFT_setFont(DEJAVU24_FONT, NULL); | |
237 | TFT_fillRect(0, 0, 319, 25, TFT_NAVY); | |
238 | TFT_print(s_top_msg, CENTER, 2); | |
239 | font_transparent = 0; | |
240 | snprintf(msg, 63, "{\"top_msg\":\"%s\"}", s_top_msg); | |
241 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
242 | } | |
243 | ||
244 | ||
245 | ||
246 | void MLT_info(int x, int y, bool update) | |
247 | { | |
248 | char ctemp[16], csp[16], cpower[16], msg[32]; | |
249 | static char ltemp[16], lsp[16], lpower[16]; | |
250 | bool con, cpwr, cpump = false; | |
251 | static bool lon, lpwr, lpump; | |
252 | ||
253 | _bg = (color_t){ 48, 48, 48 }; | |
254 | _fg = TFT_WHITE; | |
255 | color_t _led = { 31,255, 31}; | |
256 | color_t _pump = {127,175,255}; | |
257 | color_t _pwr = {255, 47, 47}; | |
258 | ||
259 | if (! update) { | |
260 | TFT_fillRect(x, y, 178, 90, _bg); | |
261 | TFT_drawRect(x, y, 178, 90, _fg); | |
262 | TFT_drawFastHLine(x, y + 21, 178, _fg); | |
263 | TFT_setFont(DEJAVU18_FONT, NULL); | |
264 | TFT_print("MLT", x + 67, y + 3); | |
265 | } | |
266 | ||
267 | if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { | |
268 | sprintf(ctemp, "%7.3f", driver_state->mlt_pv); | |
269 | if (driver_state->mlt_mode) { | |
270 | sprintf(csp, "%6.2f sp", driver_state->mlt_sp); | |
271 | } else { | |
272 | csp[0] = '\0'; | |
273 | } | |
274 | if ((driver_state->mlt_mode == MLT_MODE_BANG) || (driver_state->mlt_mode == MLT_MODE_PID) || (driver_state->mlt_mode == MLT_MODE_EXT)) { | |
275 | sprintf(cpower, "%3d%%", driver_state->mlt_power); | |
276 | } else { | |
277 | cpower[0] = '\0'; | |
278 | } | |
279 | xSemaphoreGive(xSemaphoreDriver); | |
280 | } | |
281 | ||
282 | con = (MLT_pin) ? true : false; | |
283 | if ((con != lon) || (! update)) { | |
284 | if (con) { | |
285 | TFT_fillCircle(x + 166, y + 11, 8, _led); | |
286 | } else { | |
287 | TFT_fillCircle(x + 166, y + 11, 8, _bg); | |
288 | } | |
289 | lon = con; | |
290 | snprintf(msg, 31, "{\"mlt_led\":\"%s\"}", con ? "1":"0"); | |
291 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
292 | } | |
293 | ||
294 | cpump = (Pump_pin) ? true : false; | |
295 | if ((cpump != lpump) || (! update)) { | |
296 | if (cpump) { | |
297 | TFT_fillCircle(x + 146, y + 11, 8, _pump); | |
298 | } else { | |
299 | TFT_fillCircle(x + 146, y + 11, 8, _bg); | |
300 | } | |
301 | lpump = cpump; | |
302 | snprintf(msg, 31, "{\"pump_led\":\"%s\"}", cpump ? "1":"0"); | |
303 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
304 | } | |
305 | ||
306 | if (equipment.SSR2 == SSR2_ON_IDLE) { | |
307 | cpwr = (HLT_pin) ? true : false; | |
308 | if ((cpwr != lpwr) || (! update)) { | |
309 | if (cpwr) { | |
310 | TFT_fillCircle(x + 126, y + 11, 8, _pwr); | |
311 | } else { | |
312 | TFT_fillCircle(x + 126, y + 11, 8, _bg); | |
313 | } | |
314 | lpwr = cpwr; | |
315 | snprintf(msg, 31, "{\"hlt_led\":\"%s\"}", cpwr ? "1":"0"); | |
316 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
317 | } | |
318 | } | |
319 | ||
320 | if (strcmp(ctemp, ltemp) || (! update)) { | |
321 | TFT_setFont(USER_FONT, "/spiffs/fonts/Grotesk24x48.fon"); | |
322 | TFT_print(ctemp, x + 5, y + 23); | |
323 | strncpy(ltemp, ctemp, 16); | |
324 | snprintf(msg, 31, "{\"mlt_pv\":\"%s\"}", ctemp); | |
325 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
326 | } | |
327 | ||
328 | TFT_setFont(DEJAVU18_FONT, NULL); | |
329 | if (strcmp(csp, lsp) || (! update)) { | |
330 | TFT_clearStringRect(x + 5, y + 70, "123.45 sp"); | |
331 | TFT_print(csp, x + 5, y + 70); | |
332 | strncpy(lsp, csp, 16); | |
333 | snprintf(msg, 31, "{\"mlt_sp\":\"%s\"}", csp); | |
334 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
335 | } | |
336 | if (strcmp(cpower, lpower) || (! update)) { | |
337 | TFT_clearStringRect(x + 120, y + 70, "100%"); | |
338 | TFT_print(cpower, x + 120, y + 70); | |
339 | strncpy(lpower, cpower, 16); | |
340 | snprintf(msg, 31, "{\"mlt_power\":\"%s\"}", cpower); | |
341 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
342 | } | |
343 | } | |
344 | ||
345 | ||
346 | ||
347 | void HLT_info(int x, int y, bool update, bool small) | |
348 | { | |
349 | char ctemp[16], csp[16], cpower[16], msg[32]; | |
350 | static char ltemp[16], lsp[16], lpower[16]; | |
351 | bool con = false; | |
352 | static bool lon; | |
353 | uint8_t H; | |
354 | ||
355 | _bg = (color_t){ 63, 63, 64 }; | |
356 | _fg = TFT_YELLOW; | |
357 | color_t _led = {255, 47, 47}; | |
358 | H = (small) ? 70 : 90; | |
359 | ||
360 | if (! update) { | |
361 | TFT_fillRect(x, y, 178, H, _bg); | |
362 | TFT_drawRect(x, y, 178, H, _fg); | |
363 | TFT_drawFastHLine(x, y + 21, 178, _fg); | |
364 | TFT_setFont(DEJAVU18_FONT, NULL); | |
365 | TFT_print("HLT", x + 67, y + 3); | |
366 | } | |
367 | ||
368 | if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { | |
369 | sprintf(ctemp, "%7.3f", driver_state->hlt_pv); | |
370 | if (driver_state->hlt_mode == HLT_MODE_BANG) { | |
371 | sprintf(cpower, "%3d%%", driver_state->hlt_power); | |
372 | } else { | |
373 | cpower[0] = '\0'; | |
374 | } | |
375 | if (driver_state->hlt_mode == HLT_MODE_BANG || driver_state->hlt_mode == HLT_MODE_OFF) { | |
376 | sprintf(csp, "%6.2f sp", driver_state->hlt_sp); | |
377 | } else { | |
378 | csp[0] = '\0'; | |
379 | } | |
380 | xSemaphoreGive(xSemaphoreDriver); | |
381 | } | |
382 | ||
383 | con = (HLT_pin) ? true : false; | |
384 | if ((con != lon) || (! update)) { | |
385 | if (con) { | |
386 | TFT_fillCircle(x + 166, y + 11, 8, _led); | |
387 | } else { | |
388 | TFT_fillCircle(x + 166, y + 11, 8, _bg); | |
389 | } | |
390 | lon = con; | |
391 | snprintf(msg, 31, "{\"hlt_led\":\"%s\"}", con ? "1":"0"); | |
392 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
393 | } | |
394 | ||
395 | if (strcmp(ltemp, ctemp) || (! update)) { | |
396 | if (small) { | |
397 | TFT_setFont(USER_FONT, "/spiffs/fonts/DejaVuSans24.fon"); | |
398 | TFT_print(ctemp, x + 40, y + 25); | |
399 | } else { | |
400 | TFT_setFont(USER_FONT, "/spiffs/fonts/Grotesk24x48.fon"); | |
401 | TFT_print(ctemp, x + 5, y + 23); | |
402 | } | |
403 | strncpy(ltemp, ctemp, 16); | |
404 | snprintf(msg, 31, "{\"hlt_pv\":\"%s\"}", ctemp); | |
405 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
406 | } | |
407 | ||
408 | H = (small) ? 50 : 70; | |
409 | TFT_setFont(DEJAVU18_FONT, NULL); | |
410 | if (strcmp(csp, lsp) || (! update)) { | |
411 | TFT_clearStringRect(x + 5, y + H, "123.45 sp"); | |
412 | TFT_print(csp, x + 5, y + H); | |
413 | strncpy(lsp, csp, 16); | |
414 | snprintf(msg, 31, "{\"hlt_sp\":\"%s\"}", csp); | |
415 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
416 | } | |
417 | if (strcmp(cpower, lpower) || (! update)) { | |
418 | TFT_clearStringRect(x + 120, y + H, "100%"); | |
419 | TFT_print(cpower, x + 120, y + H); | |
420 | strncpy(lpower, cpower, 16); | |
421 | snprintf(msg, 31, "{\"hlt_power\":\"%s\"}", cpower); | |
422 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
423 | } | |
424 | } | |
425 | ||
426 | ||
427 | ||
428 | void update_json(void) | |
429 | { | |
430 | int Hour = (TimeBrewing / 3600); | |
431 | int Minute = ((TimeBrewing % 3600) / 60); | |
432 | ||
433 | if (counts == 0) | |
434 | counts = 1; // Prevent division by zero. | |
435 | ||
436 | if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { | |
437 | snprintf(json_log->time, 8, "%02d:%02d", Hour, Minute); | |
438 | json_log->mlt_sp = driver_state->mlt_sp; | |
439 | json_log->mlt_pv = driver_state->mlt_pv; | |
440 | json_log->mlt_power = power_MLT / counts; | |
441 | json_log->mlt_tempreached = TempReached ? 1:0; | |
442 | json_log->pump_run = driver_state->pump_run; | |
443 | json_log->hlt_sp = driver_state->hlt_sp; | |
444 | json_log->hlt_pv = driver_state->hlt_pv; | |
445 | json_log->hlt_power = power_HLT / counts; | |
446 | json_log->event[0] = '\0'; | |
447 | xSemaphoreGive(xSemaphoreDriver); | |
448 | } | |
449 | } | |
450 | ||
451 | ||
452 | ||
453 | void TFTstartWS(int client) | |
454 | { | |
455 | char msg[1024]; | |
456 | char mlt_sp[16], mlt_power[16], hlt_sp[16], hlt_power[16]; | |
457 | ||
458 | if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { | |
459 | if (driver_state->mlt_sp) { | |
460 | snprintf(mlt_sp, 15, "%6.2f sp", driver_state->mlt_sp); | |
461 | snprintf(mlt_power, 15, "%3d%%", driver_state->mlt_power); | |
462 | } else { | |
463 | mlt_sp[0] = '\0'; | |
464 | mlt_power[0] = '\0'; | |
465 | } | |
466 | if (driver_state->hlt_sp) { | |
467 | snprintf(hlt_sp, 15, "%6.2f sp", driver_state->hlt_sp); | |
468 | snprintf(hlt_power, 15, "%3d%%", driver_state->hlt_power); | |
469 | } else { | |
470 | hlt_sp[0] = '\0'; | |
471 | hlt_power[0] = '\0'; | |
472 | } | |
473 | snprintf(msg, 1023, "{\"main\":\"%d\",\"mlt_led\":\"%d\",\"mlt_pv\":\"%7.3f\",\"mlt_sp\":\"%s\",\"mlt_power\":\"%s\"" \ | |
474 | ",\"pump_led\":\"%d\",\"hlt_led\":\"%d\",\"hlt_pv\":\"%7.3f\",\"hlt_sp\":\"%s\",\"hlt_power\":\"%s\"" \ | |
475 | ",\"timer\":\"%s\",\"top_msg\":\"%s\"}", | |
476 | Main_Screen, (MLT_pin) ? 1:0, driver_state->mlt_pv, mlt_sp, mlt_power, | |
477 | (Pump_pin) ? 1:0, (HLT_pin) ? 1:0, driver_state->hlt_pv, hlt_sp, hlt_power, | |
478 | s_timer, s_top_msg); | |
479 | ||
480 | xSemaphoreGive(xSemaphoreDriver); | |
481 | ws_server_send_text_client(client, msg, strlen(msg)); | |
482 | } | |
483 | ||
484 | } | |
485 | ||
486 | ||
487 | ||
488 | void task_tft(void *pvParameter) | |
489 | { | |
490 | char msg[32]; | |
491 | ||
492 | ESP_LOGI(TAG, "Initialize TFT/Touch task"); | |
493 | ||
494 | /* | |
495 | * Task loop. Read touchscreen events. | |
496 | */ | |
497 | while (1) { | |
498 | /* | |
499 | * Build new screen. | |
500 | */ | |
501 | startover: | |
502 | ||
503 | updateRuntime = false; | |
504 | if (_NewMinute) { | |
505 | _NewMinute = false; | |
506 | NewMinute = true; | |
507 | } | |
508 | ||
509 | /* | |
510 | * Timekeeping. In the WiFi task sntp is started if there | |
511 | * is a valid internet connection. | |
512 | */ | |
513 | time(&now); | |
514 | localtime_r(&now, &timeinfo); | |
515 | // Is time set? If not, tm_year will be (1970 - 1900). | |
516 | if ((timeinfo.tm_year > (2016 - 1900)) && (! System_TimeOk)) { | |
517 | System_TimeOk = true; | |
518 | strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); | |
519 | ESP_LOGI(TAG, "System time is set: %s", strftime_buf); | |
520 | } | |
521 | ||
522 | if (Old_Screen != Main_Screen) { | |
523 | ||
524 | if ((Main_Screen == MAIN_MODE_FREE) && ((config.ts_xleft == 0) || (config.ts_ybottom == 0))) { | |
525 | Main_Screen = MAIN_MODE_CALIBRATION; | |
526 | } | |
527 | ||
528 | /* | |
529 | * With each screenchange, remove the timer too. | |
530 | */ | |
531 | snprintf(msg, 31, "{\"main\":\"%d\",\"timer\":\"\"}", Main_Screen); | |
532 | ws_server_send_text_clients("/ws", msg, strlen(msg)); | |
533 | ||
534 | ESP_LOGI(TAG, "Change screen %d to %d", Old_Screen, Main_Screen); | |
535 | _bg = TFT_BLACK; | |
536 | TFT_fillScreen(_bg); | |
537 | TFT_resetclipwin(); | |
538 | Buttons_Clear(); | |
539 | Old_Screen = Main_Screen; | |
540 | ||
541 | switch (Main_Screen) { | |
542 | case MAIN_MODE_FREE: | |
543 | TopMessage("Hoofdmenu"); | |
544 | MLT_info(71, 26, false); | |
545 | if ((equipment.SSR2 == SSR2_HLT_SHARE) || (equipment.SSR2 == SSR2_HLT_IND)) { | |
546 | HLT_info(71,150, false, false); | |
547 | } | |
548 | Buttons_Add( 5, 26, 60, 40, "Hand", 0); | |
549 | Buttons_Add(255, 26, 60, 40, "Auto", 1); | |
550 | Buttons_Add( 5, 200, 60, 40, "Info", 2); | |
551 | Buttons_Add(255, 200, 60, 40, "Tools", 3); | |
552 | Buttons_Show(); | |
553 | break; | |
554 | ||
555 | case MAIN_MODE_CALIBRATION: | |
556 | Calibration_Init(); | |
557 | break; | |
558 | ||
559 | case MAIN_INFO: | |
560 | sprintf(temp_buf, "BrewBoard %s", VERSION); | |
561 | TopMessage(temp_buf); | |
562 | _fg = TFT_YELLOW; | |
563 | TFT_setFont(UBUNTU16_FONT, NULL); | |
564 | TFT_print("Written by Michiel Broek (C) 2018\r\n\n", 0, 50); | |
565 | // ------------------------------------- | |
566 | _fg = TFT_ORANGE; | |
567 | TFT_print("Parts are written by Chris Morgan,\r\n", 0, LASTY); | |
568 | TFT_print("Brett Beauregard, Chris Garry, LoBo,\r\n", 0, LASTY); | |
569 | TFT_print("and David Antliff.\r\n", 0, LASTY); | |
570 | ShowInteger(1,140, "Free memory", " bytes", esp_get_free_heap_size()); | |
571 | ShowText(1,158, "IDF version", (char *)esp_get_idf_version()); | |
572 | Buttons_Add(130, 200, 60, 40, "Ok", 0); | |
573 | Buttons[0].dark = true; | |
574 | Buttons_Show(); | |
575 | break; | |
576 | ||
577 | case MAIN_TOOLS: | |
578 | TopMessage("Tools menu"); | |
579 | Buttons_Add( 20, 40,120, 40, "Setup", 0); | |
580 | Buttons_Add( 20,120,120, 40, "Bestanden", 1); | |
581 | Buttons_Add(180, 40,120, 40, "Recepten", 2); | |
582 | Buttons_Add(180,120,120, 40, "Updates", 3); | |
583 | Buttons_Add(130, 200, 60, 40, "Ok", 4); | |
584 | Buttons[4].dark = true; | |
585 | Buttons_Show(); | |
586 | break; | |
587 | ||
588 | case MAIN_TOOLS_SETUP: | |
589 | case MAIN_TOOLS_SETUP_CONFIG: | |
590 | case MAIN_TOOLS_SETUP_CO_EDIT: | |
591 | case MAIN_TOOLS_SETUP_EQUIPMENT: | |
592 | case MAIN_TOOLS_SETUP_EQ_EDIT: | |
593 | case MAIN_TOOLS_SETUP_CALIBRATION: | |
594 | Setup_Init(); | |
595 | break; | |
596 | ||
597 | case MAIN_TOOLS_SETUP_WIFI: | |
598 | case MAIN_TOOLS_SETUP_WIFI_CUR: | |
599 | case MAIN_TOOLS_SETUP_WIFI_CON: | |
600 | case MAIN_TOOLS_SETUP_WIFI_NEW: | |
601 | if (WiFi_Init()) | |
602 | goto startover; | |
603 | break; | |
604 | ||
605 | case MAIN_TOOLS_RECIPE: | |
606 | case MAIN_TOOLS_RECIPE_EDIT: | |
607 | Recipes_Init(); | |
608 | break; | |
609 | ||
610 | case MAIN_TOOLS_FILES: | |
2
7a03d81c0e0d
Added database backup and restore.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
611 | case MAIN_TOOLS_FILES_DIR: |
7a03d81c0e0d
Added database backup and restore.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
612 | case MAIN_TOOLS_FILES_RESTORE: |
7a03d81c0e0d
Added database backup and restore.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
613 | case MAIN_TOOLS_FILES_BACKUP: |
0 | 614 | Files_Init(); |
615 | break; | |
616 | ||
617 | case MAIN_TOOLS_UPDATES: | |
618 | Updates_Init(); | |
619 | break; | |
620 | ||
621 | case MAIN_AUTO_INIT: | |
622 | case MAIN_AUTO_DELAYSTART: | |
623 | case MAIN_AUTO_HEATUP: | |
624 | case MAIN_AUTO_MASH_IN: | |
625 | case MAIN_AUTO_MASH_1: | |
626 | case MAIN_AUTO_MASH_2: | |
627 | case MAIN_AUTO_MASH_3: | |
628 | case MAIN_AUTO_MASH_4: | |
629 | case MAIN_AUTO_MASH_5: | |
630 | case MAIN_AUTO_MASH_6: | |
631 | case MAIN_AUTO_MASH_OUT: | |
632 | case MAIN_AUTO_TOBOIL: | |
633 | case MAIN_AUTO_BOILING: | |
634 | case MAIN_AUTO_COOLING_H: | |
635 | case MAIN_AUTO_COOLING_M: | |
636 | case MAIN_AUTO_COOLING_C: | |
637 | case MAIN_AUTO_WHIRLPOOL9: | |
638 | case MAIN_AUTO_WHIRLPOOL7: | |
639 | case MAIN_AUTO_WHIRLPOOL6: | |
640 | case MAIN_AUTO_WHIRLPOOL2: | |
641 | case MAIN_AUTO_DONE: | |
642 | case MAIN_AUTO_ABORT: | |
643 | if (Automation_Init()) | |
644 | goto startover; | |
645 | break; | |
646 | ||
647 | case MAIN_MANUAL_INIT: | |
648 | case MAIN_MANUAL_MAIN: | |
649 | if (Manual_Init()) | |
650 | goto startover; | |
651 | break; | |
652 | ||
653 | default: | |
654 | break; | |
655 | } | |
656 | } | |
657 | ||
658 | /* | |
659 | * Update screen | |
660 | */ | |
661 | switch (Main_Screen) { | |
662 | case MAIN_MODE_FREE: | |
663 | MLT_info(71, 26, true); | |
664 | if ((equipment.SSR2 == SSR2_HLT_SHARE) || (equipment.SSR2 == SSR2_HLT_IND)) { | |
665 | HLT_info(71, 150, true, false); | |
666 | } | |
667 | switch (Buttons_Scan()) { | |
668 | case 0: Main_Screen = MAIN_MANUAL_INIT; break; | |
669 | case 1: Main_Screen = MAIN_AUTO_INIT; break; | |
670 | case 2: Main_Screen = MAIN_INFO; break; | |
671 | case 3: Main_Screen = MAIN_TOOLS; break; | |
672 | default: break; | |
673 | } | |
674 | break; | |
675 | ||
676 | case MAIN_MODE_CALIBRATION: | |
677 | Calibration_Loop(); | |
678 | Main_Screen = MAIN_MODE_FREE; | |
679 | break; | |
680 | ||
681 | case MAIN_TOOLS: | |
682 | switch (Buttons_Scan()) { | |
683 | case 0: Main_Screen = MAIN_TOOLS_SETUP; break; | |
684 | case 1: Main_Screen = MAIN_TOOLS_FILES; break; | |
685 | case 2: Main_Screen = MAIN_TOOLS_RECIPE; break; | |
686 | case 3: Main_Screen = MAIN_TOOLS_UPDATES; break; | |
687 | case 4: Main_Screen = MAIN_MODE_FREE; break; | |
688 | default: break; | |
689 | } | |
690 | break; | |
691 | ||
692 | case MAIN_TOOLS_SETUP: | |
693 | case MAIN_TOOLS_SETUP_CONFIG: | |
694 | case MAIN_TOOLS_SETUP_CO_EDIT: | |
695 | case MAIN_TOOLS_SETUP_EQUIPMENT: | |
696 | case MAIN_TOOLS_SETUP_EQ_EDIT: | |
697 | case MAIN_TOOLS_SETUP_CALIBRATION: | |
698 | Setup_Loop(); | |
699 | break; | |
700 | ||
701 | case MAIN_TOOLS_SETUP_WIFI: | |
702 | case MAIN_TOOLS_SETUP_WIFI_CUR: | |
703 | case MAIN_TOOLS_SETUP_WIFI_CON: | |
704 | case MAIN_TOOLS_SETUP_WIFI_NEW: | |
705 | if (WiFi_Loop()) | |
706 | goto startover; | |
707 | break; | |
708 | ||
709 | case MAIN_TOOLS_RECIPE: | |
710 | case MAIN_TOOLS_RECIPE_EDIT: | |
711 | Recipes_Loop(); | |
712 | break; | |
713 | ||
714 | case MAIN_TOOLS_FILES: | |
2
7a03d81c0e0d
Added database backup and restore.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
715 | case MAIN_TOOLS_FILES_DIR: |
7a03d81c0e0d
Added database backup and restore.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
716 | case MAIN_TOOLS_FILES_RESTORE: |
7a03d81c0e0d
Added database backup and restore.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
717 | case MAIN_TOOLS_FILES_BACKUP: |
0 | 718 | Files_Loop(); |
719 | break; | |
720 | ||
721 | case MAIN_TOOLS_UPDATES: | |
722 | Updates_Loop(); | |
723 | break; | |
724 | ||
725 | case MAIN_INFO: | |
726 | if (Buttons_Scan() == 0) { | |
727 | Main_Screen = MAIN_MODE_FREE; | |
728 | } | |
729 | break; | |
730 | ||
731 | case MAIN_AUTO_INIT: | |
732 | case MAIN_AUTO_DELAYSTART: | |
733 | case MAIN_AUTO_HEATUP: | |
734 | case MAIN_AUTO_MASH_IN: | |
735 | case MAIN_AUTO_MASH_1: | |
736 | case MAIN_AUTO_MASH_2: | |
737 | case MAIN_AUTO_MASH_3: | |
738 | case MAIN_AUTO_MASH_4: | |
739 | case MAIN_AUTO_MASH_5: | |
740 | case MAIN_AUTO_MASH_6: | |
741 | case MAIN_AUTO_MASH_OUT: | |
742 | case MAIN_AUTO_TOBOIL: | |
743 | case MAIN_AUTO_BOILING: | |
744 | case MAIN_AUTO_COOLING_H: | |
745 | case MAIN_AUTO_COOLING_M: | |
746 | case MAIN_AUTO_COOLING_C: | |
747 | case MAIN_AUTO_WHIRLPOOL9: | |
748 | case MAIN_AUTO_WHIRLPOOL7: | |
749 | case MAIN_AUTO_WHIRLPOOL6: | |
750 | case MAIN_AUTO_WHIRLPOOL2: | |
751 | case MAIN_AUTO_DONE: | |
752 | case MAIN_AUTO_ABORT: | |
753 | if (Automation_Loop()) | |
754 | goto startover; | |
755 | break; | |
756 | ||
757 | case MAIN_MANUAL_INIT: | |
758 | case MAIN_MANUAL_MAIN: | |
759 | if (Manual_Loop()) | |
760 | goto startover; | |
761 | break; | |
762 | ||
763 | default: | |
764 | break; | |
765 | } | |
766 | ||
767 | if (updateRuntime) { | |
768 | write_runtime(); | |
769 | } | |
770 | ||
771 | /* | |
772 | * Count power average during brewing. | |
773 | */ | |
774 | if ((Main_Screen >= MAIN_AUTO_MASH_IN) && (Main_Screen < MAIN_AUTO_DONE)) { | |
775 | if (xSemaphoreTake(xSemaphoreDriver, 10) == pdTRUE) { | |
776 | power_MLT += driver_state->mlt_power; | |
777 | power_HLT += driver_state->hlt_power; | |
778 | counts++; | |
779 | xSemaphoreGive(xSemaphoreDriver); | |
780 | } | |
781 | } | |
782 | ||
783 | if (NewMinute) { | |
784 | /* | |
785 | * Brew logging. | |
786 | */ | |
787 | if ((Main_Screen >= MAIN_AUTO_MASH_IN) && (Main_Screen < MAIN_AUTO_DONE)) { | |
788 | update_json(); | |
789 | log_json(); | |
790 | power_MLT = power_HLT = counts = 0; | |
791 | } | |
792 | } | |
793 | ||
794 | NewMinute = false; | |
795 | vTaskDelay(50 / portTICK_PERIOD_MS); | |
796 | } | |
797 | } | |
798 | ||
799 |