Implement basic gui for profile selection. Still doesn't do anything

This commit is contained in:
Mario Hüttel 2021-04-04 17:43:31 +02:00
parent 666353e3b7
commit 5deac33949
4 changed files with 107 additions and 74 deletions

View File

@ -15,3 +15,4 @@ reflow-controller.includes
*.config *.config
*.files *.files
*.user.* *.user.*
*.user

View File

@ -942,7 +942,7 @@ static shellmatta_cmd_t cmd[21] = {
.cmd = "execute", .cmd = "execute",
.cmdAlias = NULL, .cmdAlias = NULL,
.helpText = "Execute Temp Profile", .helpText = "Execute Temp Profile",
.usageText = "", .usageText = "execute /path/to/script.tpr",
.cmdFct = shell_cmd_execute, .cmdFct = shell_cmd_execute,
.next = NULL, .next = NULL,
} }

View File

@ -27,15 +27,15 @@
#include <reflow-controller/digio.h> #include <reflow-controller/digio.h>
static struct tpe_current_state IN_SECTION(.ccm.data) state = { static struct tpe_current_state IN_SECTION(.ccm.data) state = {
.status = TPE_OFF, .status = TPE_OFF,
.start_timestamp = 0, .start_timestamp = 0,
}; };
static bool IN_SECTION(.ccm.bss) pid_should_run; static bool IN_SECTION(.ccm.bss) pid_should_run;
struct pid_controller IN_SECTION(.ccm.bss) pid; struct pid_controller IN_SECTION(.ccm.bss) pid;
static struct pl_command IN_SECTION(.ccm.bss) cmd_list[MAX_PROFILE_LENGTH]; static struct pl_command IN_SECTION(.ccm.bss) cmd_list[MAX_PROFILE_LENGTH];
static void abort(void) static void tpe_abort(void)
{ {
temp_profile_executer_stop(); temp_profile_executer_stop();
state.status = TPE_ABORT; state.status = TPE_ABORT;
@ -54,6 +54,8 @@ enum pl_ret_val temp_profile_executer_start(const char *filename)
oven_pid_stop(); oven_pid_stop();
pid_should_run = false; pid_should_run = false;
state.status = TPE_OFF;
state.profile_steps = 0;
res = temp_profile_parse_from_file(filename, cmd_list, MAX_PROFILE_LENGTH, &parsed_count); res = temp_profile_parse_from_file(filename, cmd_list, MAX_PROFILE_LENGTH, &parsed_count);
if (res == PL_RET_SUCCESS) { if (res == PL_RET_SUCCESS) {
@ -74,7 +76,7 @@ static bool cmd_wait_temp(struct pl_command *cmd, bool cmd_continue)
res = adc_pt1000_get_current_resistance(&resistance); res = adc_pt1000_get_current_resistance(&resistance);
if (res < 0) { if (res < 0) {
abort(); tpe_abort();
return false; return false;
} }
@ -137,7 +139,7 @@ static bool cmd_ramp(struct pl_command *cmd, bool cmd_continue)
} else { } else {
secs_passed = ((float)(systick_get_global_tick() - start_timestamp)) / 1000.0f; secs_passed = ((float)(systick_get_global_tick() - start_timestamp)) / 1000.0f;
if ((state.setpoint <= cmd->params[0] && start_temp < cmd->params[0]) || if ((state.setpoint <= cmd->params[0] && start_temp < cmd->params[0]) ||
(state.setpoint >= cmd->params[0] && start_temp > cmd->params[0])) { (state.setpoint >= cmd->params[0] && start_temp > cmd->params[0])) {
state.setpoint = start_temp + secs_passed * slope; state.setpoint = start_temp + secs_passed * slope;
} else { } else {
state.setpoint = cmd->params[0]; state.setpoint = cmd->params[0];
@ -158,74 +160,79 @@ int temp_profile_executer_handle(void)
uint32_t next_step; uint32_t next_step;
/* Return if no profile is currently executed */
if (state.status != TPE_RUNNING) if (state.status != TPE_RUNNING)
return -1; return -1;
/* Abort profile execution if oven PID is aborted. This is most likely due to some error flags */
if (oven_pid_get_status() == OVEN_PID_ABORTED && pid_should_run) { if (oven_pid_get_status() == OVEN_PID_ABORTED && pid_should_run) {
abort(); tpe_abort();
oven_pid_stop(); oven_pid_stop();
return -1; return -1;
} }
if (systick_ticks_have_passed(last_tick, 100)) { /* Execute Temp Profile every 100 ms. If not yet due, return */
current_cmd = &cmd_list[state.step]; if (!systick_ticks_have_passed(last_tick, 100))
next_step = state.step; return 0;
switch (current_cmd->cmd) { current_cmd = &cmd_list[state.step];
case PL_WAIT_FOR_TIME: next_step = state.step;
advance = cmd_wait_time(current_cmd, cmd_continue);
break;
case PL_WAIT_FOR_TEMP:
advance = cmd_wait_temp(current_cmd, cmd_continue);
break;
case PL_SET_TEMP:
advance = cmd_set_temp(current_cmd, cmd_continue);
break;
case PL_LOUDSPEAKER_SET:
loudspeaker_set((uint16_t)current_cmd->params[0]);
advance = true;
break;
case PL_OFF:
oven_pid_stop();
pid_should_run = false;
advance = true;
break;
case PL_PID_CONF:
pid_init(&pid, current_cmd->params[0], /* Kd */
current_cmd->params[1], /* Ki */
current_cmd->params[2], /* Kp */
0.0f, 0.0f,
current_cmd->params[3], /* Int max */
current_cmd->params[4], /* Kd tau */
current_cmd->params[5]); /* Period */
oven_pid_init(&pid);
advance = true;
pid_should_run = true;
break;
case PL_SET_RAMP:
advance = cmd_ramp(current_cmd, cmd_continue);
break;
default:
abort();
advance = true;
break;
}
if (advance) switch (current_cmd->cmd) {
next_step++; case PL_WAIT_FOR_TIME:
advance = cmd_wait_time(current_cmd, cmd_continue);
if (next_step != state.step) { break;
state.step = next_step; case PL_WAIT_FOR_TEMP:
if (next_step >= state.profile_steps) { advance = cmd_wait_temp(current_cmd, cmd_continue);
(void)temp_profile_executer_stop(); break;
} else { case PL_SET_TEMP:
cmd_continue = false; advance = cmd_set_temp(current_cmd, cmd_continue);
} break;
} else { case PL_LOUDSPEAKER_SET:
cmd_continue = true; loudspeaker_set((uint16_t)current_cmd->params[0]);
} advance = true;
last_tick = systick_get_global_tick(); break;
case PL_OFF:
oven_pid_stop();
pid_should_run = false;
advance = true;
break;
case PL_PID_CONF:
pid_init(&pid, current_cmd->params[0], /* Kd */
current_cmd->params[1], /* Ki */
current_cmd->params[2], /* Kp */
0.0f, 0.0f,
current_cmd->params[3], /* Int max */
current_cmd->params[4], /* Kd tau */
current_cmd->params[5]); /* Period */
oven_pid_init(&pid);
advance = true;
pid_should_run = true;
break;
case PL_SET_RAMP:
advance = cmd_ramp(current_cmd, cmd_continue);
break;
default:
tpe_abort();
advance = true;
break;
} }
if (advance)
next_step++;
if (next_step != state.step) {
state.step = next_step;
if (next_step >= state.profile_steps) {
(void)temp_profile_executer_stop();
} else {
cmd_continue = false;
}
} else {
cmd_continue = true;
}
last_tick = systick_get_global_tick();
return 0; return 0;
} }

View File

@ -37,6 +37,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <reflow-controller/oven-driver.h> #include <reflow-controller/oven-driver.h>
#include <fatfs/ff.h> #include <fatfs/ff.h>
#include <reflow-controller/temp-profile-executer.h>
static char IN_SECTION(.ccm.bss) display_buffer[4][21] = {0}; static char IN_SECTION(.ccm.bss) display_buffer[4][21] = {0};
static struct lcd_menu IN_SECTION(.ccm.bss) reflow_menu; static struct lcd_menu IN_SECTION(.ccm.bss) reflow_menu;
@ -417,9 +418,12 @@ static void gui_menu_temp_profile_select(struct lcd_menu *menu, enum menu_entry_
static void *my_parent; static void *my_parent;
static char profile_list[10][17]; static char profile_list[10][17];
static bool file_error = false; static bool file_error = false;
static enum pl_ret_val profile_ret_val = PL_RET_SUCCESS;
static uint8_t currently_selected = 0U; static uint8_t currently_selected = 0U;
static uint8_t current_scroll_offset = 0U;
static uint8_t loaded; static uint8_t loaded;
int16_t delta;
enum button_state button;
int res; int res;
if (entry_type == MENU_ENTRY_FIRST_ENTER) { if (entry_type == MENU_ENTRY_FIRST_ENTER) {
@ -431,7 +435,7 @@ static void gui_menu_temp_profile_select(struct lcd_menu *menu, enum menu_entry_
if (res < 0) { if (res < 0) {
file_error = true; file_error = true;
} }
current_scroll_offset = 0u;
currently_selected = 0u; currently_selected = 0u;
loaded = (uint32_t)res; loaded = (uint32_t)res;
menu_lcd_outputf(menu, 0, "Select:"); menu_lcd_outputf(menu, 0, "Select:");
@ -441,28 +445,49 @@ static void gui_menu_temp_profile_select(struct lcd_menu *menu, enum menu_entry_
} }
if (menu_get_button_ready_state(menu)) { if (menu_get_button_ready_state(menu)) {
if (menu_get_button_state(menu) == BUTTON_LONG) { delta = menu_get_rotary_delta(menu);
button = menu_get_button_state(menu);
if (button == BUTTON_LONG) {
menu_entry_dropback(menu, my_parent); menu_entry_dropback(menu, my_parent);
} }
if (file_error) { if (file_error) {
menu_lcd_outputf(menu, 0, "Disk Error"); menu_lcd_outputf(menu, 0, "Disk Error");
menu_lcd_outputf(menu, 1, "SD inserted?"); menu_lcd_outputf(menu, 1, "SD inserted?");
if (menu_get_button_state(menu) == BUTTON_SHORT_RELEASED) if (button == BUTTON_SHORT_RELEASED)
menu_entry_dropback(menu, my_parent); menu_entry_dropback(menu, my_parent);
return; return;
} } else if (loaded == 0) {
if (loaded == 0) {
menu_lcd_outputf(menu, 0, "No profiles"); menu_lcd_outputf(menu, 0, "No profiles");
menu_lcd_outputf(menu, 1, "found"); menu_lcd_outputf(menu, 1, "found");
if (menu_get_button_state(menu) == BUTTON_SHORT_RELEASED) if (button == BUTTON_SHORT_RELEASED)
menu_entry_dropback(menu, my_parent); menu_entry_dropback(menu, my_parent);
return; return;
} else if (profile_ret_val != PL_RET_SUCCESS) {
menu_lcd_outputf(menu, 0, "Profile Error");
if (button == BUTTON_SHORT_RELEASED)
menu_entry_dropback(menu, my_parent);
return;
} else if (currently_selected < loaded) {
/* Show currently selected profile */
menu_lcd_outputf(menu, 1, "%s", &profile_list[currently_selected][0]);
if (button == BUTTON_SHORT_RELEASED) {
/* Execute selected profile */
}
if (delta >= 4) {
menu_ack_rotary_delta(menu);
if (currently_selected < (loaded - 1))
currently_selected++;
} else if (delta <= -4) {
menu_ack_rotary_delta(menu);
if (currently_selected > 0)
currently_selected--;
}
} }
} }
} }
static void gui_menu_constant_temperature_driver_setup(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent) static void gui_menu_constant_temperature_driver_setup(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)