28 static TaskHandle_t xTaskWifi = NULL; |
32 static TaskHandle_t xTaskWifi = NULL; |
29 static TaskHandle_t xTaskMQTT = NULL; |
33 static TaskHandle_t xTaskMQTT = NULL; |
30 const esp_app_desc_t *app_desc = NULL; ///< Application description |
34 const esp_app_desc_t *app_desc = NULL; ///< Application description |
31 u8g2_t u8g2; ///< A structure which will contain all the data for one display |
35 u8g2_t u8g2; ///< A structure which will contain all the data for one display |
32 rotary_encoder_info_t rinfo = { 0 }; ///< Rotary encoder record |
36 rotary_encoder_info_t rinfo = { 0 }; ///< Rotary encoder record |
|
37 rotary_encoder_event_t event = { 0 }; |
|
38 QueueHandle_t event_queue; |
33 static int PushDuration = 0; ///< Duration of the pushed button |
39 static int PushDuration = 0; ///< Duration of the pushed button |
34 |
40 |
35 extern unit_t units[3]; ///< Pressure test units |
41 extern unit_t units[3]; ///< Pressure test units |
36 extern SemaphoreHandle_t xSemaphoreUnits; ///< Units lock semaphore |
42 extern SemaphoreHandle_t xSemaphoreUnits; ///< Units lock semaphore |
37 extern DS18B20_State *ds18b20_state; ///< DS18B20 state |
43 extern DS18B20_State *ds18b20_state; ///< DS18B20 state |
38 extern SemaphoreHandle_t xSemaphoreDS18B20; ///< DS18B20 lock semaphore |
44 extern SemaphoreHandle_t xSemaphoreDS18B20; ///< DS18B20 lock semaphore |
39 extern ADC_State *adc_state; ///< ADC state |
45 extern ADC_State *adc_state; ///< ADC state |
40 extern SemaphoreHandle_t xSemaphoreADC; ///< ADC lock semaphore |
46 extern SemaphoreHandle_t xSemaphoreADC; ///< ADC lock semaphore |
|
47 extern WIFI_State *wifi_state; ///< WiFi state |
41 extern int count_pub; ///< Published MQTT messages in transit |
48 extern int count_pub; ///< Published MQTT messages in transit |
42 static xQueueHandle gpio_evt_queue = NULL; ///< Rotary pushbutton queue |
49 static xQueueHandle gpio_evt_queue = NULL; ///< Rotary pushbutton queue |
43 static int usertimer = 0; ///< User inactive timeout |
50 static int usertimer = 0; ///< User inactive timeout |
|
51 |
|
52 |
|
53 |
|
54 /** |
|
55 * @brief Get a keyboard character from the rotary encoder. |
|
56 * @param curkey The referenced value if the key being edited. NOTE, start at 0 for a new char?? |
|
57 * @param type The edittype, all values, integer or float. |
|
58 * @param x The x position on the screen. |
|
59 * @param y The y position on the screen. |
|
60 * @return 1 if short keypress, meaning enter key. 2 if long press, enter key and editing is ready. |
|
61 */ |
|
62 int getkey(int *curkey, int type, int x, int y) |
|
63 { |
|
64 int key = *curkey; |
|
65 int rc = 0; |
|
66 |
|
67 u8g2_DrawHLine(&u8g2, x, y+3, 12); |
|
68 u8g2_SendBuffer(&u8g2); |
|
69 |
|
70 for (;;) { |
|
71 if (xQueueReceive(event_queue, &event, 100 / portTICK_PERIOD_MS) == pdTRUE) { |
|
72 usertimer = INACTIVITY; |
|
73 if (event.state.position != 0) { |
|
74 |
|
75 u8g2_SetDrawColor(&u8g2, 0); |
|
76 u8g2_DrawGlyph(&u8g2, x, y, key); |
|
77 u8g2_SetDrawColor(&u8g2, 1); |
|
78 u8g2_SendBuffer(&u8g2); |
|
79 |
|
80 if (event.state.position > 0) { |
|
81 if (key == 126) |
|
82 key = 171; |
|
83 else if (key < 126) |
|
84 key++; |
|
85 } else if (event.state.position < 0) { |
|
86 if (key == 171) |
|
87 key = 126; |
|
88 else if (key > 32) |
|
89 key--; |
|
90 } |
|
91 |
|
92 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); |
|
93 u8g2_DrawGlyph(&u8g2, x, y, key); |
|
94 u8g2_SendBuffer(&u8g2); |
|
95 } |
|
96 } else { |
|
97 if (PushDuration) { |
|
98 if (PushDuration > 500) |
|
99 rc = 2; |
|
100 else |
|
101 rc = 1; |
|
102 PushDuration = 0; |
|
103 break; |
|
104 } |
|
105 } |
|
106 } |
|
107 u8g2_SetDrawColor(&u8g2, 0); |
|
108 u8g2_DrawHLine(&u8g2, x, y+3, 12); |
|
109 u8g2_SetDrawColor(&u8g2, 1); |
|
110 u8g2_SendBuffer(&u8g2); |
|
111 |
|
112 *curkey = key; |
|
113 return rc; |
|
114 } |
|
115 |
|
116 |
|
117 |
|
118 /** |
|
119 * @brief Editor using the rotary switch. |
|
120 * @param label The label of the edit field. |
|
121 * @param txt The string to edit. |
|
122 * @param errmsg The error message if needed. |
|
123 * @param len The maximum length for the string. |
|
124 * @param type The edit type. |
|
125 */ |
|
126 void rotary_editer(char *label, char *txt, char *errmsg, int len, int type) |
|
127 { |
|
128 char buf[65]; |
|
129 int key, x, y, rc; |
|
130 |
|
131 u8g2_ClearBuffer(&u8g2); |
|
132 u8g2_DrawHLine(&u8g2, 0, 14, 128); |
|
133 u8g2_DrawHLine(&u8g2, 0, 49, 128); |
|
134 u8g2_SetFont(&u8g2, u8g2_font_t0_15_tf); |
|
135 sprintf(buf, "Edit %s", label); |
|
136 u8g2_DrawStr(&u8g2,0,12,buf); |
|
137 |
|
138 if (strlen(errmsg)) { |
|
139 u8g2_SetFont(&u8g2, u8g2_font_t0_12b_tf); |
|
140 u8g2_DrawStr(&u8g2, 0, 61, errmsg); |
|
141 } |
|
142 u8g2_SetFont(&u8g2, u8g2_font_t0_12_tf); |
|
143 y = 36; |
|
144 u8g2_DrawStr(&u8g2, 0, y, txt); |
|
145 u8g2_SendBuffer(&u8g2); |
|
146 |
|
147 for (;;) { |
|
148 x = u8g2_GetUTF8Width(&u8g2, txt); |
|
149 key = 'a'; |
|
150 rc = getkey(&key, type, x, y); |
|
151 if (rc == 1) { |
|
152 if (key >= 32 && key <= 126 && strlen(txt) < len) { |
|
153 txt[strlen(txt) + 1] = '\0'; |
|
154 txt[strlen(txt)] = key; |
|
155 } else if (key == 171 && strlen(txt)) { |
|
156 // delete key |
|
157 txt[strlen(txt) - 1] = '\0'; |
|
158 } |
|
159 printf("strlen %d x %d key %d\n", strlen(txt), x, key); |
|
160 } else if (rc == 2) { |
|
161 break; |
|
162 } |
|
163 } |
|
164 } |
44 |
165 |
45 |
166 |
46 |
167 |
47 /** |
168 /** |
48 * @brief Write a menu line on the display. |
169 * @brief Write a menu line on the display. |
198 screen_top("Unit %d setup", no + 1); |
319 screen_top("Unit %d setup", no + 1); |
199 menu_line(sub == 0, 2, 25, "Mode %s", units[no].mode ? "ON":"OFF"); |
320 menu_line(sub == 0, 2, 25, "Mode %s", units[no].mode ? "ON":"OFF"); |
200 menu_line(sub == 1, 2, 37, "Zero mV %d", units[no].pressure_zero); |
321 menu_line(sub == 1, 2, 37, "Zero mV %d", units[no].pressure_zero); |
201 menu_line(sub == 2, 2, 49, "DS18B20 %s", units[no].temperature_rom_code); |
322 menu_line(sub == 2, 2, 49, "DS18B20 %s", units[no].temperature_rom_code); |
202 menu_line(sub == 3, 2, 61, "Return"); |
323 menu_line(sub == 3, 2, 61, "Return"); |
|
324 u8g2_SendBuffer(&u8g2); |
|
325 u8g2_SetPowerSave(&u8g2, 0); |
|
326 } |
|
327 |
|
328 |
|
329 |
|
330 void screen_wifi() |
|
331 { |
|
332 char buf[65]; |
|
333 |
|
334 screen_top("WiFi Status"); |
|
335 snprintf(buf, 65, "SSID %s", wifi_state->STA_ssid); |
|
336 u8g2_DrawStr(&u8g2, 1, 28, buf); |
|
337 snprintf(buf, 65, "Online %s", wifi_state->STA_online ? "Yes":"No"); |
|
338 u8g2_DrawStr(&u8g2, 1, 43, buf); |
|
339 snprintf(buf, 65, "RSSI %d", wifi_state->STA_rssi); |
|
340 u8g2_DrawStr(&u8g2, 1, 59, buf); |
|
341 u8g2_SendBuffer(&u8g2); |
|
342 u8g2_SetPowerSave(&u8g2, 0); |
|
343 } |
|
344 |
|
345 |
|
346 |
|
347 void screen_wifi_setup(int sub) |
|
348 { |
|
349 screen_top("WiFi Setup"); |
|
350 menu_line(sub == 0, 2, 25, "Connect"); |
|
351 menu_line(sub == 1, 2, 37, "New"); |
|
352 menu_line(sub == 2, 2, 49, "Delete"); |
|
353 menu_line(sub == 3, 2, 61, "Return"); |
|
354 u8g2_SendBuffer(&u8g2); |
|
355 u8g2_SetPowerSave(&u8g2, 0); |
|
356 } |
|
357 |
|
358 |
|
359 |
|
360 void screen_network() |
|
361 { |
|
362 screen_top("Network Status"); |
|
363 menu_line(0, 1, 25, "IP %s", wifi_state->STA_ip); |
|
364 menu_line(0, 1, 37, "Mask %s", wifi_state->STA_nm); |
|
365 menu_line(0, 1, 49, "GW %s", wifi_state->STA_gw); |
|
366 menu_line(0, 1, 61, "Name %s", config.hostname); |
|
367 u8g2_SendBuffer(&u8g2); |
|
368 u8g2_SetPowerSave(&u8g2, 0); |
|
369 } |
|
370 |
|
371 |
|
372 |
|
373 void screen_mqtt() |
|
374 { |
|
375 screen_top("MQTT Status"); |
|
376 menu_line(0, 1, 25, "serv %s", config.mqtt_server); |
|
377 menu_line(0, 1, 37, "port %d", config.mqtt_port); |
|
378 menu_line(0, 1, 49, "user %s", config.mqtt_user); |
|
379 u8g2_SendBuffer(&u8g2); |
|
380 u8g2_SetPowerSave(&u8g2, 0); |
|
381 } |
|
382 |
|
383 |
|
384 |
|
385 void screen_update() |
|
386 { |
|
387 screen_top("Update firmware"); |
|
388 menu_line(0, 1, 43, "Push to update"); |
203 u8g2_SendBuffer(&u8g2); |
389 u8g2_SendBuffer(&u8g2); |
204 u8g2_SetPowerSave(&u8g2, 0); |
390 u8g2_SetPowerSave(&u8g2, 0); |
205 } |
391 } |
206 |
392 |
207 |
393 |
478 |
665 |
479 gpio_isr_handler_add(ROT_ENC_SW_GPIO, gpio_isr_handler, (void*) ROT_ENC_SW_GPIO); |
666 gpio_isr_handler_add(ROT_ENC_SW_GPIO, gpio_isr_handler, (void*) ROT_ENC_SW_GPIO); |
480 |
667 |
481 // Create a queue for events from the rotary encoder driver. |
668 // Create a queue for events from the rotary encoder driver. |
482 // Tasks can read from this queue to receive up to date position information. |
669 // Tasks can read from this queue to receive up to date position information. |
483 QueueHandle_t event_queue = rotary_encoder_create_queue(); |
670 event_queue = rotary_encoder_create_queue(); |
484 ESP_ERROR_CHECK(rotary_encoder_set_queue(&rinfo, event_queue)); |
671 ESP_ERROR_CHECK(rotary_encoder_set_queue(&rinfo, event_queue)); |
485 |
672 |
486 /* |
673 /* |
487 * Main application loop. |
674 * Main application loop. |
488 */ |
675 */ |
489 while (1) { |
676 while (1) { |
490 |
677 |
491 ESP_LOGI(TAG, "Entered app loop"); |
678 ESP_LOGI(TAG, "Entered app loop"); |
492 rotary_encoder_event_t event = { 0 }; |
679 //event = { 0 }; |
493 int sub = 0; |
680 int sub = 0; |
494 u8g2_SetPowerSave(&u8g2, 1); |
681 u8g2_SetPowerSave(&u8g2, 1); |
495 |
682 |
496 /* Measure process or user input via rotary switch */ |
683 /* Measure process or user input via rotary switch */ |
497 while (1) { |
684 while (1) { |
634 case ML2_UNIT3: |
826 case ML2_UNIT3: |
635 ESP_LOGI(TAG, "Loop user: Unit %d", Main_Loop2 - ML2_UNIT1); |
827 ESP_LOGI(TAG, "Loop user: Unit %d", Main_Loop2 - ML2_UNIT1); |
636 screen_unit(Main_Loop2 - ML2_UNIT1); |
828 screen_unit(Main_Loop2 - ML2_UNIT1); |
637 break; |
829 break; |
638 |
830 |
639 case ML2_SET_WIFI: |
831 case ML2_WIFI: |
640 ESP_LOGI(TAG, "Loop user: Setup WiFi"); |
832 ESP_LOGI(TAG, "Loop user: WiFi"); |
641 break; |
833 screen_wifi(); |
642 |
834 break; |
643 case ML2_SET_NETWORK: |
835 |
644 ESP_LOGI(TAG, "Loop user: Setup Network"); |
836 case ML2_NETWORK: |
645 break; |
837 ESP_LOGI(TAG, "Loop user: Network"); |
646 |
838 screen_network(); |
647 case ML2_SET_MQTT: |
839 break; |
648 ESP_LOGI(TAG, "Loop user: Setup MQTT"); |
840 |
|
841 case ML2_MQTT: |
|
842 ESP_LOGI(TAG, "Loop user: MQTT"); |
|
843 screen_mqtt(); |
|
844 break; |
|
845 |
|
846 case ML2_SETUP_MQTT: |
|
847 ESP_LOGI(TAG, "Loop user: MQTT setup"); |
|
848 sprintf(txt, "EDtXt"); |
|
849 rotary_editer("MQTT demo", txt, "", 16, EDIT_TYPE_TEXT); |
|
850 New_Loop2 = ML2_MQTT; |
649 break; |
851 break; |
650 |
852 |
651 case ML2_UPDATE: |
853 case ML2_UPDATE: |
652 ESP_LOGI(TAG, "Loop user: Update"); |
854 ESP_LOGI(TAG, "Loop user: Update"); |
|
855 screen_update(); |
653 break; |
856 break; |
654 |
857 |
655 case ML2_SETUP_UNIT1: |
858 case ML2_SETUP_UNIT1: |
656 case ML2_SETUP_UNIT2: |
859 case ML2_SETUP_UNIT2: |
657 case ML2_SETUP_UNIT3: |
860 case ML2_SETUP_UNIT3: |
703 usertimer = INACTIVITY; |
906 usertimer = INACTIVITY; |
704 switch (Main_Loop2) { |
907 switch (Main_Loop2) { |
705 case ML2_USER: rotate_to_menu(event.state.position, ML2_UNIT1, ML2_USER); break; |
908 case ML2_USER: rotate_to_menu(event.state.position, ML2_UNIT1, ML2_USER); break; |
706 case ML2_UNIT1: rotate_to_menu(event.state.position, ML2_UNIT2, ML2_USER); break; |
909 case ML2_UNIT1: rotate_to_menu(event.state.position, ML2_UNIT2, ML2_USER); break; |
707 case ML2_UNIT2: rotate_to_menu(event.state.position, ML2_UNIT3, ML2_UNIT1); break; |
910 case ML2_UNIT2: rotate_to_menu(event.state.position, ML2_UNIT3, ML2_UNIT1); break; |
708 case ML2_UNIT3: rotate_to_menu(event.state.position, ML2_SET_WIFI, ML2_UNIT2); break; |
911 case ML2_UNIT3: rotate_to_menu(event.state.position, ML2_WIFI, ML2_UNIT2); break; |
709 case ML2_SET_WIFI: rotate_to_menu(event.state.position, ML2_SET_NETWORK, ML2_UNIT3); break; |
912 case ML2_WIFI: rotate_to_menu(event.state.position, ML2_NETWORK, ML2_UNIT3); break; |
710 case ML2_SET_NETWORK: rotate_to_menu(event.state.position, ML2_SET_MQTT, ML2_SET_WIFI); break; |
913 case ML2_NETWORK: rotate_to_menu(event.state.position, ML2_MQTT, ML2_WIFI); break; |
711 case ML2_SET_MQTT: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_NETWORK); break; |
914 case ML2_MQTT: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_NETWORK); break; |
712 case ML2_UPDATE: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_MQTT); break; |
915 case ML2_UPDATE: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_MQTT); break; |
713 case ML2_SETUP_UNIT1: |
916 case ML2_SETUP_UNIT1: |
714 case ML2_SETUP_UNIT2: |
917 case ML2_SETUP_UNIT2: |
715 case ML2_SETUP_UNIT3: if (rotate_to_sub(event.state.position, 0, 3, &sub)) |
918 case ML2_SETUP_UNIT3: if (rotate_to_sub(event.state.position, 0, 3, &sub)) |
716 screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); |
919 screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); |
717 break; |
920 break; |