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; |
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; |
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 } |