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 /** |
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 |