main/co2meter.c

changeset 19
4fb9ed228a23
parent 18
d969e0fe05dc
child 20
7c1dacafed03
equal deleted inserted replaced
18:d969e0fe05dc 19:4fb9ed228a23
91 u8g2_DrawStr(&u8g2, (128 - w) / 2,12, buf); 91 u8g2_DrawStr(&u8g2, (128 - w) / 2,12, buf);
92 } 92 }
93 93
94 94
95 95
96 /**
97 * @brief The splash screen shown during cold boot or user wakeup.
98 */
96 void screen_splash() 99 void screen_splash()
97 { 100 {
98 screen_top("CO2 meter %s", app_desc->version); 101 screen_top("CO2 meter %s", app_desc->version);
99 102
100 u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf); 103 u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf);
105 u8g2_SetPowerSave(&u8g2, 0); // wake up display 108 u8g2_SetPowerSave(&u8g2, 0); // wake up display
106 } 109 }
107 110
108 111
109 112
113 /**
114 * @brief The main overview screen.
115 */
110 void screen_main() 116 void screen_main()
111 { 117 {
112 char buf[65]; 118 char buf[65];
113 int i; 119 int i;
114 120
133 u8g2_SetPowerSave(&u8g2, 0); // wake up display 139 u8g2_SetPowerSave(&u8g2, 0); // wake up display
134 } 140 }
135 141
136 142
137 143
144 /**
145 * @brief The unit display screen.
146 * @param no The unit index number.
147 */
138 void screen_unit(int no) 148 void screen_unit(int no)
139 { 149 {
140 char buf[65]; 150 char buf[65];
141 151
142 if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) { 152 if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) {
158 u8g2_SetPowerSave(&u8g2, 0); // wake up display 168 u8g2_SetPowerSave(&u8g2, 0); // wake up display
159 } 169 }
160 170
161 171
162 172
173 /**
174 * @brief The unit zero setup screen.
175 * @param no The unit index number.
176 * @param sub The submenu index number.
177 */
163 void screen_unit_zero(int no, int sub) 178 void screen_unit_zero(int no, int sub)
164 { 179 {
165 screen_top("Unit %d zero mV", no + 1); 180 screen_top("Unit %d zero mV", no + 1);
166 menu_line( 0, 2, 25, "Current %d", units[no].pressure_zero); 181 menu_line( 0, 2, 25, "Current %d", units[no].pressure_zero);
167 menu_line(sub == 0, 2, 37, "New value %d", units[no].pressure_voltage / (adc_state->Batt_voltage / 1000)); 182 menu_line(sub == 0, 2, 37, "New value %d", units[no].pressure_voltage / (adc_state->Batt_voltage / 1000));
168 menu_line(sub == 1, 2, 49, "Return"); 183 menu_line(sub == 1, 2, 49, "Return");
169 184 printf("current %d p_voltage %d batt %d\n", units[no].pressure_zero, units[no].pressure_voltage, adc_state->Batt_voltage);
170 u8g2_SendBuffer(&u8g2); 185 u8g2_SendBuffer(&u8g2);
171 u8g2_SetPowerSave(&u8g2, 0); 186 u8g2_SetPowerSave(&u8g2, 0);
172 } 187 }
173 188
174 189
175 190
191 /**
192 * @brief The unit setup screen.
193 * @param no The unit index number.
194 * @param sub The submenu index number.
195 */
176 void screen_unit_setup(int no, int sub) 196 void screen_unit_setup(int no, int sub)
177 { 197 {
178 screen_top("Unit %d setup", no + 1); 198 screen_top("Unit %d setup", no + 1);
179 menu_line(sub == 0, 2, 25, "Mode %s", units[no].mode ? "ON":"OFF"); 199 menu_line(sub == 0, 2, 25, "Mode %s", units[no].mode ? "ON":"OFF");
180 menu_line(sub == 1, 2, 37, "Zero mV %d", units[no].pressure_zero); 200 menu_line(sub == 1, 2, 37, "Zero mV %d", units[no].pressure_zero);
181 menu_line(sub == 2, 2, 49, "DS18B20 %s", units[no].temperature_rom_code); 201 menu_line(sub == 2, 2, 49, "DS18B20 %s", units[no].temperature_rom_code);
182 menu_line(sub == 3, 2, 61, "Return"); 202 menu_line(sub == 3, 2, 61, "Return");
183
184 u8g2_SendBuffer(&u8g2); 203 u8g2_SendBuffer(&u8g2);
185 u8g2_SetPowerSave(&u8g2, 0); 204 u8g2_SetPowerSave(&u8g2, 0);
186 } 205 }
187 206
188 207
189 208
209 /**
210 * @brief Fatal messages on the screen.
211 * @param e1 The first line.
212 * @param e2 The second line.
213 */
190 void screen_fatal(char *e1, char *e2) 214 void screen_fatal(char *e1, char *e2)
191 { 215 {
192 u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); 216 u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr);
193 u8g2_DrawStr(&u8g2,2,12,e1); 217 u8g2_DrawStr(&u8g2,2,12,e1);
194 u8g2_DrawStr(&u8g2,2,24,e2); 218 u8g2_DrawStr(&u8g2,2,24,e2);
196 u8g2_SetPowerSave(&u8g2, 0); 220 u8g2_SetPowerSave(&u8g2, 0);
197 } 221 }
198 222
199 223
200 224
201 /* 225 /**
202 * Interrupt service routine for the rotary pushbutton. 226 * @brief Interrupt service routine for the rotary pushbutton.
203 */ 227 */
204 static void IRAM_ATTR gpio_isr_handler(void* arg) 228 static void IRAM_ATTR gpio_isr_handler(void* arg)
205 { 229 {
206 uint32_t gpio_num = (uint32_t) arg; 230 uint32_t gpio_num = (uint32_t) arg;
207 xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); 231 xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
208 } 232 }
209 233
210 234
211 235
212 /* 236 /**
213 * GPIO queue task. See if there is a rotary pushbutton event in the queue. 237 * @brief GPIO queue task. See if there is a rotary pushbutton event on the queue.
214 */ 238 */
215 static void gpio_task(void* arg) 239 static void gpio_task(void* arg)
216 { 240 {
217 uint32_t io_num; 241 uint32_t io_num;
218 static int64_t pushed = 0; 242 static int64_t pushed = 0;
235 } 259 }
236 } 260 }
237 261
238 262
239 263
240 /* 264 /**
241 * Select new menu number on a postitive or negative rotary position. 265 * @brief Select new menu number on a postitive or negative rotary position.
242 * Then reset the rotary position. 266 * @param pos The new position, positive, negative or zero.
267 * @param next_menu The selected menu if rotated clockwise.
268 * @param prev_menu The selected menu if rotated counter-clockwise.
243 */ 269 */
244 static void rotate_to_menu(rotary_encoder_position_t pos, int next_menu, int prev_menu) 270 static void rotate_to_menu(rotary_encoder_position_t pos, int next_menu, int prev_menu)
245 { 271 {
246 if (pos > 0) 272 if (pos > 0)
247 New_Loop2 = next_menu; 273 New_Loop2 = next_menu;
250 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); 276 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
251 } 277 }
252 278
253 279
254 280
255 int rotate_to_sub(rotary_encoder_position_t pos, int min, int max, int cursub) 281 /**
256 { 282 * @brief Rotate subscreens numbers.
257 int sub = cursub; 283 * @param pos The new position, positive, negative or zero.
284 * @param min The lowest number. If already at the lowest, select the highest.
285 * @param max The highest number. If already at the highest, select the lowest.
286 * @param cursub The subscreen number by reference. This is updated with the new number.
287 * @return Returns true if a new number is selected, false if nothing changed.
288 */
289 bool rotate_to_sub(rotary_encoder_position_t pos, int min, int max, int *cursub)
290 {
291 int sub = *cursub;
292 bool rc = false;
258 293
259 if (pos > 0) { 294 if (pos > 0) {
260 if (sub < max) 295 if (sub < max)
261 sub++; 296 sub++;
262 else 297 else
263 sub = min; 298 sub = min;
264 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); 299 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
300 rc = true;
265 } else if (pos < 0) { 301 } else if (pos < 0) {
266 if (sub > min) 302 if (sub > min)
267 sub--; 303 sub--;
268 else 304 else
269 sub = max; 305 sub = max;
270 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); 306 ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
271 } 307 rc = true;
272 return sub; 308 }
273 } 309
310 *cursub = sub;
311 return rc;
312 }
313
274 314
275 315
276 void app_main() 316 void app_main()
277 { 317 {
278 struct timeval now; 318 struct timeval now;
638 break; 678 break;
639 } 679 }
640 } 680 }
641 681
642 /* 682 /*
643 * Main user processing. Handle the rotary encoder and pushbutton. 683 * Handle rotationg the rotary encoder.
644 */ 684 */
645 if (Main_Loop2 < ML2_INACTIVE) { 685 if (Main_Loop2 < ML2_INACTIVE) {
646 // If not configured, start configure 686 // If not configured, start configure
647 // If configured select first unit 687 // If configured select first unit
648 // Handle screen (first is show measured values) 688 // Handle screen (first is show measured values)
670 case ML2_SET_NETWORK: rotate_to_menu(event.state.position, ML2_SET_MQTT, ML2_SET_WIFI); break; 710 case ML2_SET_NETWORK: rotate_to_menu(event.state.position, ML2_SET_MQTT, ML2_SET_WIFI); break;
671 case ML2_SET_MQTT: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_NETWORK); break; 711 case ML2_SET_MQTT: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_NETWORK); break;
672 case ML2_UPDATE: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_MQTT); break; 712 case ML2_UPDATE: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_MQTT); break;
673 case ML2_SETUP_UNIT1: 713 case ML2_SETUP_UNIT1:
674 case ML2_SETUP_UNIT2: 714 case ML2_SETUP_UNIT2:
675 case ML2_SETUP_UNIT3: sub = rotate_to_sub(event.state.position, 0, 3, sub); 715 case ML2_SETUP_UNIT3: if (rotate_to_sub(event.state.position, 0, 3, &sub))
676 screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); 716 screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub);
677 break; 717 break;
678 case ML2_ZERO_UNIT1: 718 case ML2_ZERO_UNIT1:
679 case ML2_ZERO_UNIT2: 719 case ML2_ZERO_UNIT2:
680 case ML2_ZERO_UNIT3: sub = rotate_to_sub(event.state.position, 0, 1, sub); 720 case ML2_ZERO_UNIT3: if (rotate_to_sub(event.state.position, 0, 1, &sub))
681 screen_unit_zero(Main_Loop2 - ML2_ZERO_UNIT1, sub); 721 screen_unit_zero(Main_Loop2 - ML2_ZERO_UNIT1, sub);
682 break; 722 break;
683 default: 723 default:
684 ESP_LOGI(TAG, "Event: position %d, direction %s", event.state.position, 724 ESP_LOGI(TAG, "Event: position %d, direction %s", event.state.position,
685 event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW":"CCW"):"NOT_SET"); 725 event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW":"CCW"):"NOT_SET");
686 } 726 }

mercurial