// // Created by MightyPork on 2023/04/09. // #include #include #include "app_gui.h" #include "app_heater.h" #include "screen_menu.h" #include "ufb/fb_text.h" #include "app_temp.h" #include "snprintf.h" #include "FreeRTOS.h" struct calib_state { int phase; float sample1; float sample2; int temp1; int temp2; } s_calib; enum Phase { PH_HELLO = 0, PH_SAMPLE1, PH_TEMP1, PH_SAMPLE2, PH_TEMP2, PH_DONE, }; static void next_phase() { PUTS("Phase++\r\n"); s_calib.phase++; } static const char* calib0_opts[] = { "Pokračovat", "Zrušit", NULL }; static void calib0_cb(int opt) { switch (opt) { case 0: // Continue next_phase(); request_paint(); app_heater_manual_override(100); break; case 1: switch_screen(screen_home, true); break; } } static const char* calib1_opts[] = { "Vzorek 1", "Zrušit", NULL }; static void calib1_cb(int opt) { switch (opt) { case 0: // Continue next_phase(); request_paint(); s_calib.sample1 = app_temp_read_oven_raw(); app_heater_manual_override(0); break; case 1: app_heater_manual_override(-1); switch_screen(screen_home, true); break; } } static const char* calib3_opts[] = { "Vzorek 2", "Zrušit", NULL }; static void calib3_cb(int opt) { switch (opt) { case 0: // Continue next_phase(); request_paint(); s_calib.sample2 = app_temp_read_oven_raw(); app_heater_manual_override(0); break; case 1: app_heater_manual_override(-1); switch_screen(screen_home, true); break; } } void screen_calibration(GuiEvent event) { if (event == GUI_EVENT_SCREEN_INIT) { memset(&s_calib, 0, sizeof(s_calib)); // continue to the rest - so the menu can be inited } int *pT; switch (s_calib.phase) { case PH_HELLO: if (event == GUI_EVENT_PAINT) { fb_text(FBW/2, 16, "Vychlaď", TEXT_CENTER, 1); fb_text(FBW/2, 26, "troubu", TEXT_CENTER, 1); } screen_menu_offset(event, calib0_opts, calib0_cb, 30); break; case PH_SAMPLE1: // Heater is active, waiting for mark case PH_SAMPLE2: if (event == GUI_EVENT_PAINT) { fb_text(FBW/2, 16, "Zapiš", TEXT_CENTER, 1); fb_text(FBW/2, 26, "teplotu", TEXT_CENTER, 1); } if (s_calib.phase == PH_SAMPLE1) { screen_menu_offset(event, calib1_opts, calib1_cb, 30); } else { screen_menu_offset(event, calib3_opts, calib3_cb, 30); } break; case PH_TEMP1: case PH_TEMP2: if (s_calib.phase == PH_TEMP1) { pT = &s_calib.temp1; } else { pT = &s_calib.temp2; } if (push_time() > pdMS_TO_TICKS(500)) { input_sound_effect(); app_heater_manual_override_clear(); switch_screen(screen_home, true); return; } switch (event) { case GUI_EVENT_PAINT: { fb_text(FBW/2, 14, s_calib.phase == PH_TEMP1 ? "Teplota 1" : "Teplota 2", TEXT_CENTER, 1); SPRINTF(stmp, "%d°C", *pT); fb_text(FBW/2, 30, stmp, TEXT_CENTER | FONT_DOUBLE, 1); fb_text(2, FBH - 8 * 3, "←→Nastav", 0, 1); fb_text(2, FBH - 8 * 2, "> Potvrdit", 0, 1); fb_text(2, FBH - 8 * 1, "» Zrušit", 0, 1); return; } case GUI_EVENT_KNOB_PLUS: { if (*pT < 500) { *pT += 1; input_sound_effect(); request_paint(); } break; } case GUI_EVENT_KNOB_MINUS: { if (*pT > 0) { input_sound_effect(); *pT -= 1; request_paint(); } break; } case GUI_EVENT_KNOB_RELEASE: { next_phase(); request_paint(); if (s_calib.phase == PH_DONE) { app_heater_manual_override(-1); // TODO do the math PRINTF("Sample 1 %f, T1 %d\r\n", s_calib.sample1, s_calib.temp1); PRINTF("Sample 2 %f, T2 %d\r\n", s_calib.sample2, s_calib.temp2); float corrected1 = c_to_val((float) s_calib.temp1); float corrected2 = c_to_val((float) s_calib.temp2); float a = (corrected1 - corrected2) / (s_calib.sample1 - s_calib.sample2); float b = corrected1 - a * s_calib.sample1; app_temp_set_calib(a, b); } else { app_heater_manual_override(100); } break; } } break; case PH_DONE: if (event == GUI_EVENT_PAINT) { fb_text(FBW/2, 14, "Hotovo", TEXT_CENTER, 1); fb_text(FBW/2, 36, "→Hlavní menu", TEXT_CENTER, 1); } if (event == GUI_EVENT_KNOB_RELEASE) { switch_screen(screen_home, 1); } break; } }