main/task_user.c

changeset 24
64078aa15512
parent 23
58a328e91881
child 25
cc7c423f03fb
equal deleted inserted replaced
23:58a328e91881 24:64078aa15512
17 int SubMenu = 0; ///< Submenu number 17 int SubMenu = 0; ///< Submenu number
18 u8g2_t u8g2; ///< A structure which will contain all the data for one display 18 u8g2_t u8g2; ///< A structure which will contain all the data for one display
19 rotary_encoder_info_t rinfo = { 0 }; ///< Rotary encoder record 19 rotary_encoder_info_t rinfo = { 0 }; ///< Rotary encoder record
20 rotary_encoder_event_t event = { 0 }; 20 rotary_encoder_event_t event = { 0 };
21 QueueHandle_t event_queue; 21 QueueHandle_t event_queue;
22 static xQueueHandle gpio_evt_queue = NULL; ///< Rotary pushbutton queue
22 static int PushDuration = 0; ///< Duration of the pushed button 23 static int PushDuration = 0; ///< Duration of the pushed button
23 24
24 extern const esp_app_desc_t *app_desc; 25 extern const esp_app_desc_t *app_desc;
25 extern unit_t units[3]; ///< Pressure test units 26 extern unit_t units[3]; ///< Pressure test units
26 extern SemaphoreHandle_t xSemaphoreUnits; ///< Units lock semaphore 27 extern SemaphoreHandle_t xSemaphoreUnits; ///< Units lock semaphore
27 extern DS18B20_State *ds18b20_state; ///< DS18B20 state 28 extern DS18B20_State *ds18b20_state; ///< DS18B20 state
28 extern SemaphoreHandle_t xSemaphoreDS18B20; ///< DS18B20 lock semaphore 29 extern SemaphoreHandle_t xSemaphoreDS18B20; ///< DS18B20 lock semaphore
29 extern ADC_State *adc_state; ///< ADC state 30 extern ADC_State *adc_state; ///< ADC state
30 extern SemaphoreHandle_t xSemaphoreADC; ///< ADC lock semaphore 31 extern SemaphoreHandle_t xSemaphoreADC; ///< ADC lock semaphore
31 extern WIFI_State *wifi_state; ///< WiFi state 32 extern WIFI_State *wifi_state; ///< WiFi state
33 extern SemaphoreHandle_t xSemaphoreWiFi; ///< WiFi lock semaphore
32 extern int count_pub; ///< Published MQTT messages in transit 34 extern int count_pub; ///< Published MQTT messages in transit
33 static xQueueHandle gpio_evt_queue = NULL; ///< Rotary pushbutton queue
34 extern int Main_Loop1; ///< Main measure loop 35 extern int Main_Loop1; ///< Main measure loop
35
36 36
37 37
38 const int TASK_USER_COLD = BIT0; ///< System cold start 38 const int TASK_USER_COLD = BIT0; ///< System cold start
39 const int TASK_USER_WAKEUP = BIT1; ///< System wakeup from deepsleep 39 const int TASK_USER_WAKEUP = BIT1; ///< System wakeup from deepsleep
40 const int TASK_USER_BUSY = BIT2; ///< User interface is busy doing something. 40 const int TASK_USER_BUSY = BIT2; ///< User interface is busy doing something.
95 95
96 96
97 97
98 /** 98 /**
99 * @brief Get a keyboard character from the rotary encoder. 99 * @brief Get a keyboard character from the rotary encoder.
100 * @param curkey The referenced value if the key being edited. NOTE, start at 0 for a new char?? 100 * @param curkey The referenced value if the key being edited.
101 * @param type The edittype, all values, integer or float. 101 * @param type The edittype, all values, integer or float.
102 * @param x The x position on the screen. 102 * @param x The x position on the screen.
103 * @param y The y position on the screen. 103 * @param y The y position on the screen.
104 * @return 1 if short keypress, meaning enter key. 2 if long press, enter key and editing is ready. 104 * @return 1 if short keypress, meaning enter key. 2 if long press, enter key and editing is ready.
105 */ 105 */
106 int getkey(int *curkey, int type, int x, int y) 106 int getkey(int *curkey, int type, int x, int y)
107 { 107 {
108 int key = *curkey; 108 int key = *curkey;
109 int rc = 0; 109 int rc = 0;
110 int8_t ascent = u8g2_GetAscent(&u8g2); 110 int8_t ascent = u8g2_GetAscent(&u8g2);
111 int8_t descent = u8g2_GetDescent(&u8g2);
111 int8_t charheight = u8g2_GetMaxCharHeight(&u8g2); 112 int8_t charheight = u8g2_GetMaxCharHeight(&u8g2);
112 int8_t charwidth = u8g2_GetMaxCharWidth(&u8g2); 113 int8_t charwidth = u8g2_GetMaxCharWidth(&u8g2);
113 114
115 u8g2_DrawGlyph(&u8g2, x, y, key);
114 u8g2_DrawHLine(&u8g2, x, y+3, 12); 116 u8g2_DrawHLine(&u8g2, x, y+3, 12);
115 u8g2_SendBuffer(&u8g2); 117 u8g2_UpdateDisplay(&u8g2);
116 118
117 ESP_LOGI(TAG, "getkey(%c, %d, %d, %d) a %d h %d w %d", key, type, x, y, ascent, charheight, charwidth); 119 ESP_LOGI(TAG, "getkey(%c, %d, %d, %d) a %d d %d h %d w %d", key, type, x, y, ascent, descent, charheight, charwidth);
118 120
119 for (;;) { 121 for (;;) {
120 if (xQueueReceive(event_queue, &event, 100 / portTICK_PERIOD_MS) == pdTRUE) { 122 if (xQueueReceive(event_queue, &event, 100 / portTICK_PERIOD_MS) == pdTRUE) {
121 UserTimer = INACTIVITY; 123 UserTimer = INACTIVITY;
122 if (event.state.position != 0) { 124 if (event.state.position != 0) {
123 125
124 // u8g2_SetDrawColor(&u8g2, 0); 126 u8g2_SetDrawColor(&u8g2, 0);
125 // u8g2_DrawGlyph(&u8g2, x, y, key); 127 u8g2_DrawBox(&u8g2, x, y - 12, charwidth, charheight);
126 // u8g2_SetDrawColor(&u8g2, 1); 128 u8g2_SetDrawColor(&u8g2, 1);
127 129 u8g2_DrawHLine(&u8g2, x, y+3, charwidth);
128 u8g2_DrawBox(&u8g2, x, y - ascent, 16, 16); 130
129 // u8g2_UpdateDisplayArea(&u8g2, x, y, 16, 16); 131 if (event.state.position > 0) {
130 u8g2_SendBuffer(&u8g2); 132 /*
131 133 * If turned fast, the encoder registers multiple steps.
132 if (event.state.position > 0) { 134 * So follow these steps.
133 // if (key == 126) 135 */
134 // key = 171; 136 for (int i = 0; i < event.state.position; i++) {
135 // else 137 if (type == EDIT_TYPE_CAPS) {
136 if (key < 127) 138 if (key < 127)
137 key++; 139 key++;
138 } else if (event.state.position < 0) { 140 if (key > 96 && key < 123)
139 // if (key == 171) 141 key = 123;
140 // key = 126; 142 } else if (type == EDIT_TYPE_INT) {
141 // else 143 if (key < 127)
142 if (key > 32) 144 key++;
143 key--; 145 if (key < 45)
146 key = 45;
147 if (key == 46 || key == 47)
148 key = 48;
149 if (key > 57)
150 key = 127;
151 } else if (type == EDIT_TYPE_FLOAT) {
152
153 } else { // EDIT_TYPE_TEXT
154 if (key < 127)
155 key++;
156 }
157 }
158 } else if (event.state.position < 0) {
159 for (int i = 0; i > event.state.position; i--) {
160 if (type == EDIT_TYPE_CAPS) {
161 if (key > 32)
162 key--;
163 if (key > 96 && key < 123)
164 key = 96;
165 } else if (type == EDIT_TYPE_INT) {
166 if (key > 45)
167 key--;
168 if (key > 57)
169 key = 57;
170 if (key == 46 || key == 47)
171 key = 45;
172 } else if (type == EDIT_TYPE_FLOAT) {
173
174 } else { // EDIT_TYPE_TEXT
175 if (key > 32)
176 key--;
177 }
178 }
144 } 179 }
145 180
146 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); 181 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
147 u8g2_DrawGlyph(&u8g2, x, y, key); 182 u8g2_DrawGlyph(&u8g2, x, y, key);
148 u8g2_SendBuffer(&u8g2); 183 u8g2_SendBuffer(&u8g2);
184 u8g2_UpdateDisplay(&u8g2);
149 } 185 }
150 } else { 186 } else {
151 if (PushDuration) { 187 if (PushDuration) {
188 UserTimer = INACTIVITY;
152 if (PushDuration > 500) 189 if (PushDuration > 500)
153 rc = 2; 190 rc = 2;
154 else 191 else
155 rc = 1; 192 rc = 1;
156 PushDuration = 0; 193 PushDuration = 0;
157 break; 194 break;
158 } 195 }
159 } 196 }
160 } 197 }
161 u8g2_SetDrawColor(&u8g2, 0); 198 u8g2_SetDrawColor(&u8g2, 0);
162 u8g2_DrawHLine(&u8g2, x, y+3, 12); 199 if (key == 127)
200 u8g2_DrawBox(&u8g2, x, y - 12, charwidth, charheight); // Erase DEL character
201 u8g2_DrawHLine(&u8g2, x, y+3, charwidth);
163 u8g2_SetDrawColor(&u8g2, 1); 202 u8g2_SetDrawColor(&u8g2, 1);
164 u8g2_SendBuffer(&u8g2); 203 u8g2_UpdateDisplay(&u8g2);
165 204
166 *curkey = key; 205 *curkey = key;
167 return rc; 206 return rc;
168 } 207 }
169 208
192 if (strlen(errmsg)) { 231 if (strlen(errmsg)) {
193 u8g2_SetFont(&u8g2, u8g2_font_t0_12b_tf); 232 u8g2_SetFont(&u8g2, u8g2_font_t0_12b_tf);
194 u8g2_DrawStr(&u8g2, 0, 61, errmsg); 233 u8g2_DrawStr(&u8g2, 0, 61, errmsg);
195 } 234 }
196 u8g2_SetFont(&u8g2, u8g2_font_unifont_t_symbols); 235 u8g2_SetFont(&u8g2, u8g2_font_unifont_t_symbols);
197 // u8g2_SetFont(&u8g2, u8g2_font_t0_12_tf);
198 y = 36; 236 y = 36;
199 u8g2_DrawStr(&u8g2, 0, y, txt); 237 u8g2_DrawStr(&u8g2, 0, y, txt);
200 u8g2_SendBuffer(&u8g2); 238 u8g2_SendBuffer(&u8g2);
201 ESP_LOGI(TAG, "rotary_editer(%s, %s, %s, %d, %d)", label, txt, errmsg, len, type); 239 ESP_LOGI(TAG, "rotary_editer(%s, %s, %s, %d, %d)", label, txt, errmsg, len, type);
202 240
241 /*
242 * Choose initial edit key
243 */
244 if (type == EDIT_TYPE_CAPS)
245 key = 'A';
246 else if (type == EDIT_TYPE_INT || type == EDIT_TYPE_FLOAT)
247 key = '0';
248 else
249 key = 'a';
250
203 for (;;) { 251 for (;;) {
204 x = u8g2_GetUTF8Width(&u8g2, txt); 252 x = u8g2_GetUTF8Width(&u8g2, txt);
205 key = 'a';
206 rc = getkey(&key, type, x, y); 253 rc = getkey(&key, type, x, y);
207 if (rc == 1) { 254 if (rc == 1) {
208 if (key >= 32 && key <= 126 && strlen(txt) < len) { 255 if (key >= 32 && key <= 126 && strlen(txt) < len) {
209 txt[strlen(txt) + 1] = '\0'; 256 txt[strlen(txt) + 1] = '\0';
210 txt[strlen(txt)] = key; 257 txt[strlen(txt)] = key;
211 } else if (key == 171 && strlen(txt)) { 258 } else if (key == 127 && strlen(txt)) {
212 // delete key 259 // delete key
213 txt[strlen(txt) - 1] = '\0'; 260 txt[strlen(txt) - 1] = '\0';
261 if (strlen(txt))
262 key = txt[strlen(txt) - 1];
214 } 263 }
215 printf("strlen %d x %d key %d\n", strlen(txt), x, key); 264 ESP_LOGI(TAG, " strlen %d x %d key %d `%s`", strlen(txt), x, key, txt);
216 } else if (rc == 2) { 265 } else if (rc == 2) {
217 break; 266 break;
218 } 267 }
219 } 268 }
269 ESP_LOGI(TAG, "rotary_editer() `%s`", txt);
220 } 270 }
221 271
222 272
223 273
224 /** 274 /**
326 */ 376 */
327 void screen_unit(int no) 377 void screen_unit(int no)
328 { 378 {
329 char buf[65]; 379 char buf[65];
330 380
331 if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) { 381 if (xSemaphoreTake(xSemaphoreUnits, 35) == pdTRUE) {
332 382
333 screen_top("Unit %d %s", no + 1, units[no].mode ? "On":"Off"); 383 screen_top("Unit %d %s", no + 1, units[no].mode ? "On":"Off");
334 384
335 u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf); 385 u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf);
336 sprintf(buf, "%.1f °C", units[no].temperature / 1000.0); 386 sprintf(buf, "%.1f °C", units[no].temperature / 1000.0);
338 u8g2_DrawUTF8(&u8g2, (128 - w) / 2,40, buf); 388 u8g2_DrawUTF8(&u8g2, (128 - w) / 2,40, buf);
339 389
340 sprintf(buf, "%.2f bar", units[no].pressure / 1000.0); 390 sprintf(buf, "%.2f bar", units[no].pressure / 1000.0);
341 w = u8g2_GetUTF8Width(&u8g2, buf); 391 w = u8g2_GetUTF8Width(&u8g2, buf);
342 u8g2_DrawUTF8(&u8g2, (128 - w) / 2,63, buf); 392 u8g2_DrawUTF8(&u8g2, (128 - w) / 2,63, buf);
393
394 xSemaphoreGive(xSemaphoreUnits);
343 u8g2_SendBuffer(&u8g2); 395 u8g2_SendBuffer(&u8g2);
344
345 xSemaphoreGive(xSemaphoreUnits);
346 } else { 396 } else {
347 ESP_LOGE(TAG, "screen_unit(%d) lock error", no); 397 ESP_LOGE(TAG, "screen_unit(%d) lock error", no);
348 } 398 }
349 } 399 }
350 400
385 435
386 void screen_wifi() 436 void screen_wifi()
387 { 437 {
388 char buf[65]; 438 char buf[65];
389 439
390 screen_top("WiFi Status"); 440 if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
391 snprintf(buf, 65, "SSID %s", wifi_state->STA_ssid); 441 screen_top("WiFi Status");
392 u8g2_DrawStr(&u8g2, 1, 28, buf); 442 snprintf(buf, 65, "SSID %s", wifi_state->STA_ssid);
393 snprintf(buf, 65, "RSSI %d", wifi_state->STA_rssi); 443 u8g2_DrawStr(&u8g2, 1, 28, buf);
394 u8g2_DrawStr(&u8g2, 1, 43, buf); 444 snprintf(buf, 65, "RSSI %d", wifi_state->STA_rssi);
395 snprintf(buf, 65, "Online %s", wifi_state->STA_online ? "Yes":"No"); 445 u8g2_DrawStr(&u8g2, 1, 43, buf);
396 u8g2_DrawStr(&u8g2, 1, 59, buf); 446 snprintf(buf, 65, "Online %s", wifi_state->STA_online ? "Yes":"No");
397 u8g2_SendBuffer(&u8g2); 447 u8g2_DrawStr(&u8g2, 1, 59, buf);
448 xSemaphoreGive(xSemaphoreWiFi);
449 u8g2_SendBuffer(&u8g2);
450 } else {
451 ESP_LOGE(TAG, "screen_wifi() lock error");
452 }
398 } 453 }
399 454
400 455
401 456
402 void screen_wifi_setup(int sub) 457 void screen_wifi_setup(int sub)
427 { 482 {
428 screen_top("MQTT Status"); 483 screen_top("MQTT Status");
429 menu_line(0, 1, 25, "serv %s", config.mqtt_server); 484 menu_line(0, 1, 25, "serv %s", config.mqtt_server);
430 menu_line(0, 1, 37, "port %d", config.mqtt_port); 485 menu_line(0, 1, 37, "port %d", config.mqtt_port);
431 menu_line(0, 1, 49, "user %s", config.mqtt_user); 486 menu_line(0, 1, 49, "user %s", config.mqtt_user);
487 u8g2_SendBuffer(&u8g2);
488 }
489
490
491
492 void screen_mqtt_setup(int sub)
493 {
494 screen_top("MQTT Setup");
495 menu_line(sub == 0, 2, 25, "serv %s", config.mqtt_server);
496 menu_line(sub == 1, 2, 37, "port %d", config.mqtt_port);
497 menu_line(sub == 2, 2, 49, "user %s", config.mqtt_user);
498 menu_line(sub == 3, 2, 61, "Return");
432 u8g2_SendBuffer(&u8g2); 499 u8g2_SendBuffer(&u8g2);
433 } 500 }
434 501
435 502
436 503
534 601
535 602
536 603
537 void menu_change(void) 604 void menu_change(void)
538 { 605 {
539 char txt[65];
540
541 if (New_Loop2 != Main_Loop2) { 606 if (New_Loop2 != Main_Loop2) {
542 607
543 Main_Loop2 = New_Loop2; 608 Main_Loop2 = New_Loop2;
544 609
545 switch (Main_Loop2) { 610 switch (Main_Loop2) {
575 screen_mqtt(); 640 screen_mqtt();
576 break; 641 break;
577 642
578 case ML2_SETUP_MQTT: 643 case ML2_SETUP_MQTT:
579 ESP_LOGI(TAG, "Loop user: MQTT setup"); 644 ESP_LOGI(TAG, "Loop user: MQTT setup");
580 sprintf(txt, "EDtXt"); 645 screen_mqtt_setup(SubMenu);
581 rotary_editer("MQTT demo", txt, "", 16, EDIT_TYPE_TEXT); 646 break;
582 New_Loop2 = ML2_MQTT;
583 break;
584 647
585 case ML2_UPDATE: 648 case ML2_UPDATE:
586 ESP_LOGI(TAG, "Loop user: Update"); 649 ESP_LOGI(TAG, "Loop user: Update");
587 screen_update(); 650 screen_update();
588 break; 651 break;
636 case ML2_ZERO_UNIT1: 699 case ML2_ZERO_UNIT1:
637 case ML2_ZERO_UNIT2: 700 case ML2_ZERO_UNIT2:
638 case ML2_ZERO_UNIT3: if (rotate_to_sub(event.state.position, 0, 1, &SubMenu)) 701 case ML2_ZERO_UNIT3: if (rotate_to_sub(event.state.position, 0, 1, &SubMenu))
639 screen_unit_zero(Main_Loop2 - ML2_ZERO_UNIT1, SubMenu); 702 screen_unit_zero(Main_Loop2 - ML2_ZERO_UNIT1, SubMenu);
640 break; 703 break;
704 case ML2_SETUP_MQTT: if (rotate_to_sub(event.state.position, 0, 3, &SubMenu))
705 screen_mqtt_setup(SubMenu);
706 break;
641 default: 707 default:
642 ESP_LOGI(TAG, "Event: position %d, direction %s", event.state.position, 708 ESP_LOGI(TAG, "Event: position %d, direction %s", event.state.position,
643 event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW":"CCW"):"NOT_SET"); 709 event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW":"CCW"):"NOT_SET");
644 } 710 }
645 } 711 }
662 728
663 729
664 730
665 void menu_loop(void) 731 void menu_loop(void)
666 { 732 {
667 int idx = 0; 733 int idx = 0;
734 char txt[32];
668 735
669 switch (Main_Loop2) { 736 switch (Main_Loop2) {
670 case ML2_UNIT1: 737 case ML2_UNIT1:
671 case ML2_UNIT2: 738 case ML2_UNIT2:
672 case ML2_UNIT3: 739 case ML2_UNIT3:
683 units[idx].mode = 0; 750 units[idx].mode = 0;
684 else 751 else
685 units[idx].mode = 1; 752 units[idx].mode = 1;
686 write_units(); 753 write_units();
687 xSemaphoreGive(xSemaphoreUnits); 754 xSemaphoreGive(xSemaphoreUnits);
755 } else {
756 ESP_LOGE(TAG, "menu_loop() ML2_SETUP_UNIT%d units lock", idx + 1);
688 } 757 }
689 screen_unit_setup(idx, SubMenu); 758 screen_unit_setup(idx, SubMenu);
690 if (Main_Loop1 == ML1_DONE) 759 if (Main_Loop1 == ML1_DONE)
691 Main_Loop1 = ML1_INIT; 760 Main_Loop1 = ML1_INIT;
692 } 761 }
725 794
726 case ML2_MQTT: 795 case ML2_MQTT:
727 New_Loop2 = ML2_SETUP_MQTT; 796 New_Loop2 = ML2_SETUP_MQTT;
728 break; 797 break;
729 798
799 case ML2_SETUP_MQTT:
800 if (SubMenu == 0) {
801 rotary_editer("MQTT server", config.mqtt_server, "", 16, EDIT_TYPE_TEXT);
802 screen_mqtt_setup(SubMenu);
803 }
804 if (SubMenu == 1) {
805 sprintf(txt, "%d", config.mqtt_port);
806 rotary_editer("MQTT server poort", txt, "", 6, EDIT_TYPE_INT);
807 config.mqtt_port = atoi(txt);
808 screen_mqtt_setup(SubMenu);
809 }
810 if (SubMenu == 2) {
811 rotary_editer("MQTT user", config.mqtt_user, "", 16, EDIT_TYPE_TEXT);
812 rotary_editer("MQTT password", config.mqtt_pwd, "", 16, EDIT_TYPE_TEXT);
813 screen_mqtt_setup(SubMenu);
814 }
815 if (SubMenu == 3) {
816 ESP_LOGI(TAG, "mqtt_server %s:%d", config.mqtt_server, config.mqtt_port);
817 ESP_LOGI(TAG, "mqtt_user/pass `%s/%s`", config.mqtt_user, config.mqtt_pwd);
818 write_config();
819 New_Loop2 = ML2_MQTT;
820 }
821 break;
822
730 default: 823 default:
731 break; 824 break;
732 } 825 }
733 } 826 }
734 827

mercurial