main/co2meter.c

changeset 20
7c1dacafed03
parent 19
4fb9ed228a23
child 21
043ae27633f8
equal deleted inserted replaced
19:4fb9ed228a23 20:7c1dacafed03
11 #define PIN_SCL (CONFIG_I2C_MASTER_SCL) 11 #define PIN_SCL (CONFIG_I2C_MASTER_SCL)
12 #define ROT_ENC_A_GPIO (CONFIG_ROT_ENC_A_GPIO) 12 #define ROT_ENC_A_GPIO (CONFIG_ROT_ENC_A_GPIO)
13 #define ROT_ENC_B_GPIO (CONFIG_ROT_ENC_B_GPIO) 13 #define ROT_ENC_B_GPIO (CONFIG_ROT_ENC_B_GPIO)
14 #define ROT_ENC_SW_GPIO (CONFIG_ROT_ENC_SW_GPIO) 14 #define ROT_ENC_SW_GPIO (CONFIG_ROT_ENC_SW_GPIO)
15 #define INACTIVITY 480 ///< Time in 250 mSec units. 15 #define INACTIVITY 480 ///< Time in 250 mSec units.
16
17 #define EDIT_TYPE_TEXT 0 ///< Editor type is text
18 #define EDIT_TYPE_INT 1 ///< Editor type is integer
19 #define EDIT_TYPE_FLOAT 2 ///< Editor type is float
16 20
17 21
18 int Main_Loop1 = ML1_INIT; ///< Loop 1 init 22 int Main_Loop1 = ML1_INIT; ///< Loop 1 init
19 int Main_Loop2 = -1; ///< Loop 2 invalid 23 int Main_Loop2 = -1; ///< Loop 2 invalid
20 int New_Loop2 = ML2_DONE; ///< Loop 2 new state 24 int New_Loop2 = ML2_DONE; ///< Loop 2 new state
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
317 { 503 {
318 struct timeval now; 504 struct timeval now;
319 gettimeofday(&now, NULL); 505 gettimeofday(&now, NULL);
320 int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; 506 int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000;
321 esp_err_t ret; 507 esp_err_t ret;
508 char txt[65];
322 509
323 Main_Loop1 = ML1_INIT; 510 Main_Loop1 = ML1_INIT;
324 Main_Loop2 = -1; 511 Main_Loop2 = -1;
325 512
326 /* 513 /*
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) {
504 request_ds18b20(); 691 request_ds18b20();
505 request_adc(); 692 request_adc();
506 break; 693 break;
507 694
508 case ML1_CONNECT: 695 case ML1_CONNECT:
509 if (ready_WiFi()) 696 if (ready_WiFi()) {
510 Main_Loop1 = ML1_MQTT_CONNECT; 697 Main_Loop1 = ML1_MQTT_CONNECT;
698 if (Main_Loop2 == ML2_WIFI)
699 screen_wifi();
700 }
511 break; 701 break;
512 702
513 case ML1_MQTT_CONNECT: 703 case ML1_MQTT_CONNECT:
514 if (ready_ds18b20() && ready_adc()) { 704 if (ready_ds18b20() && ready_adc()) {
515 connect_mqtt(true); 705 connect_mqtt(true);
601 791
602 case ML1_WIFI_OFF: 792 case ML1_WIFI_OFF:
603 if (! ready_WiFi()) { 793 if (! ready_WiFi()) {
604 ESP_LOGI(TAG, "Loop timer: Done"); 794 ESP_LOGI(TAG, "Loop timer: Done");
605 Main_Loop1 = ML1_DONE; 795 Main_Loop1 = ML1_DONE;
796 if (Main_Loop2 == ML2_WIFI)
797 screen_wifi();
606 } 798 }
607 break; 799 break;
608 800
609 case ML1_DONE: 801 case ML1_DONE:
610 break; 802 break;
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;
802 sub = 1; 1005 sub = 1;
803 } 1006 }
804 printf("unit zero sub %d new %d idx %d\n", sub, New_Loop2, idx); 1007 printf("unit zero sub %d new %d idx %d\n", sub, New_Loop2, idx);
805 break; 1008 break;
806 1009
1010 case ML2_MQTT:
1011 New_Loop2 = ML2_SETUP_MQTT;
1012 break;
1013
807 default: 1014 default:
808 break; 1015 break;
809 } 1016 }
810 PushDuration = 0; 1017 PushDuration = 0;
811 } 1018 }

mercurial