// // Created by MightyPork on 2023/04/09. // #include #include "app_gui.h" #include "app_heater.h" #include "ufb/fb_text.h" #include "snprintf.h" static struct calib_tuning_state { uint8_t digits[6 * 3]; // uint32_t Kp, Ki, Kd; // these are the float x 1000 int cursor; // the digit under cursor (range 0-17) bool digit_editing; // true if we are editing a digit } s_tuning; static void draw_digit_row(int row) { fbpos_t x = (FBW - (6 * 7 - 1)) / 2; fbpos_t y = 30 + row * 10; char buf2[2] = {}; int numofs = row * 6; const char * labels[3] = {"P","I","D"}; fb_text(FBW - 4, y + 2, labels[row], FONT_3X5, 1); bool significant = false; for (int i = 0; i < 6; i++) { if (i >= 2) significant = 1; int val = s_tuning.digits[numofs + i]; if (val != 0) { significant = true; } buf2[0] = '0' + val; if (s_tuning.cursor == numofs + i) { if (s_tuning.digit_editing) { fb_rect(x-1, y-1, 5+2, 7+2, 1); fb_text(x, y, buf2, 0, 0); } else { fb_hline(x, y + 8, 5, 1); if (significant) fb_text(x, y, buf2, 0, 1); } } else { if (significant) fb_text(x, y, buf2, 0, 1); } x += 6; if ( i == 2) { fb_text(x, y, ".", 0, 1); x += 6; } } } void screen_pid_tuning(GuiEvent event) { float Kp; float Ki; float Kd; uint32_t Kp_i; uint32_t Ki_i; uint32_t Kd_i; if (event == GUI_EVENT_SCREEN_INIT) { memset(&s_tuning, 0, sizeof(s_tuning)); app_heater_get_tuning(&Kp, &Ki, &Kd); Kp_i = (uint32_t)(Kp * 1000.f); Ki_i = (uint32_t)(Ki * 1000.f); Kd_i = (uint32_t)(Kd * 1000.f); char buf[19]; SNPRINTF(buf, 19, "%06lu%06lu%06lu", Kp_i, Ki_i, Kd_i); for(int i = 0; i < 18; i++) { s_tuning.digits[i] = buf[i] - '0'; } } switch (event) { case GUI_EVENT_PAINT: { fb_text(FBW / 2, 16, "Ladění PID", TEXT_CENTER, 1); draw_digit_row(0); draw_digit_row(1); draw_digit_row(2); if (s_tuning.cursor == 18) { fb_rect(0, 68, FBW, 9, 1); } fb_text(FBW / 2, 69, "Zrušit", TEXT_CENTER, s_tuning.cursor != 18); if (s_tuning.cursor == 19) { fb_rect(0, 68 + 9, FBW, 9, 1); } fb_text(FBW / 2, 69 + 9, "Uložit", TEXT_CENTER, s_tuning.cursor != 19); fb_text(2, FBH - 8 * (1 + (s_tuning.cursor < 18)), s_tuning.digit_editing ? "←→Hodnota" : "←→Kurzor", 0, 1); if (s_tuning.cursor < 18) { fb_text(2, FBH - 8 * 1, s_tuning.digit_editing ? "> Potvrdit" : "> Změnit", 0, 1); } return; } case GUI_EVENT_KNOB_PLUS: { input_sound_effect(); request_paint(); if (s_tuning.digit_editing) { if (s_tuning.digits[s_tuning.cursor] == 9) { s_tuning.digits[s_tuning.cursor] = 0; } else { s_tuning.digits[s_tuning.cursor]++; } } else { // 18 - cancel // 19 - save s_tuning.cursor++; if (s_tuning.cursor > 17) { s_tuning.digit_editing = false; } if (s_tuning.cursor > 19) { s_tuning.cursor = 0; } } break; } case GUI_EVENT_KNOB_MINUS: { input_sound_effect(); request_paint(); if (s_tuning.digit_editing) { if (s_tuning.digits[s_tuning.cursor] == 0) { s_tuning.digits[s_tuning.cursor] = 9; } else { s_tuning.digits[s_tuning.cursor]--; } } else { // 18 - cancel // 19 - save if (s_tuning.cursor == 0) { s_tuning.cursor = 19; s_tuning.digit_editing = false; } else { s_tuning.cursor--; } } break; } case GUI_EVENT_KNOB_RELEASE: { if (s_tuning.cursor < 18) { s_tuning.digit_editing = !s_tuning.digit_editing; } else if (s_tuning.cursor == 18) { // cancel switch_screen(screen_home, true); } else if (s_tuning.cursor == 19) { // save Kp_i = Ki_i = Kd_i = 0; for(int i = 0; i < 6; i++) { Kp_i *= 10; Kp_i += s_tuning.digits[i]; } for(int i = 6; i < 12; i++) { Ki_i *= 10; Ki_i += s_tuning.digits[i]; } for(int i = 12; i < 18; i++) { Kd_i *= 10; Kd_i += s_tuning.digits[i]; } Kp = ((float) Kp_i) / 1000.f; Ki = ((float) Ki_i) / 1000.f; Kd = ((float) Kd_i) / 1000.f; app_heater_set_tuning(Kp, Ki, Kd); app_heater_save_tuning(); switch_screen(screen_home, true); } break; } } }