Issue #4: Implement Constant temperature function in GUI. This is useful to verify the oven parameters
This commit is contained in:
		@@ -39,12 +39,14 @@ void oven_pid_ack_errors(void);
 | 
			
		||||
 | 
			
		||||
void oven_pid_init(struct pid_controller *controller_to_copy);
 | 
			
		||||
 | 
			
		||||
void oven_pid_handle(float target_temp);
 | 
			
		||||
void oven_pid_handle(void);
 | 
			
		||||
 | 
			
		||||
void oven_pid_stop(void);
 | 
			
		||||
 | 
			
		||||
void oven_pid_abort(void);
 | 
			
		||||
 | 
			
		||||
void oven_pid_set_target_temperature(float temp);
 | 
			
		||||
 | 
			
		||||
void oven_driver_apply_power_level(void);
 | 
			
		||||
 | 
			
		||||
enum oven_pid_status oven_pid_get_status(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,9 @@
 | 
			
		||||
#define SAFETY_ADC_TEMP_NOM_MV 760.0f
 | 
			
		||||
#define SAFETY_ADC_TEMP_MV_SLOPE 2.5f
 | 
			
		||||
 | 
			
		||||
#define SAFETY_ADC_NUM_OF_CHANNELS 2
 | 
			
		||||
#define SAFETY_ADC_CHANNELS TEMP_CHANNEL_NUM, INT_REF_CHANNEL_NUM
 | 
			
		||||
#define SAFETY_ADC_NUM_OF_CHANNELS 8
 | 
			
		||||
#define SAFETY_ADC_CHANNELS TEMP_CHANNEL_NUM, TEMP_CHANNEL_NUM, TEMP_CHANNEL_NUM, TEMP_CHANNEL_NUM, \
 | 
			
		||||
				INT_REF_CHANNEL_NUM, INT_REF_CHANNEL_NUM, INT_REF_CHANNEL_NUM, INT_REF_CHANNEL_NUM
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __SAFETY_ADC_HWCFG_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ struct pid_controller {
 | 
			
		||||
	float k_p;
 | 
			
		||||
	float k_int_t;
 | 
			
		||||
	float k_deriv_t;
 | 
			
		||||
	float k_inv_deriv_t;
 | 
			
		||||
	float output_sat_max;
 | 
			
		||||
	float output_sat_min;
 | 
			
		||||
	float integral_max;
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,7 @@ static void setup_nvic_priorities(void)
 | 
			
		||||
	NVIC_SetPriority(DMA2_Stream0_IRQn, 1);
 | 
			
		||||
	/* Shelmatta UART TX */
 | 
			
		||||
	NVIC_SetPriority(DMA2_Stream7_IRQn, 3);
 | 
			
		||||
	NVIC_SetPriority(DMA2_Stream4_IRQn, 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FATFS fs;
 | 
			
		||||
@@ -208,8 +209,10 @@ int main(void)
 | 
			
		||||
		handle_shell_uart_input(shell_handle);
 | 
			
		||||
 | 
			
		||||
		safety_controller_handle();
 | 
			
		||||
		/* Todo: Remove this */
 | 
			
		||||
		oven_driver_set_power(0);
 | 
			
		||||
		if (oven_pid_get_status() == OVEN_PID_RUNNING) {
 | 
			
		||||
			oven_pid_handle();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		oven_driver_apply_power_level();
 | 
			
		||||
 | 
			
		||||
		safety_controller_report_timing(ERR_TIMING_MAIN_LOOP);
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,8 @@ static struct pid_controller IN_SECTION(.ccm.bss) oven_pid;
 | 
			
		||||
static bool oven_pid_running;
 | 
			
		||||
static bool oven_pid_aborted;
 | 
			
		||||
static uint8_t IN_SECTION(.ccm.bss) oven_driver_power_level;
 | 
			
		||||
static float IN_SECTION(.ccm.bss) target_temp;
 | 
			
		||||
static uint64_t IN_SECTION(.ccm.bss) timestamp_last_run;
 | 
			
		||||
 | 
			
		||||
void oven_driver_init(void)
 | 
			
		||||
{
 | 
			
		||||
@@ -56,6 +58,7 @@ void oven_driver_init(void)
 | 
			
		||||
	oven_pid_running = false;
 | 
			
		||||
 | 
			
		||||
	oven_driver_set_power(0U);
 | 
			
		||||
	oven_driver_apply_power_level();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oven_driver_set_power(uint8_t power)
 | 
			
		||||
@@ -88,13 +91,18 @@ void oven_pid_init(struct pid_controller *controller_to_copy)
 | 
			
		||||
	oven_pid_running = true;
 | 
			
		||||
	oven_pid_aborted = false;
 | 
			
		||||
	safety_controller_report_timing(ERR_TIMING_PID);
 | 
			
		||||
	timestamp_last_run = systick_get_global_tick();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oven_pid_handle(float target_temp)
 | 
			
		||||
void oven_pid_set_target_temperature(float temp)
 | 
			
		||||
{
 | 
			
		||||
	target_temp = temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oven_pid_handle(void)
 | 
			
		||||
{
 | 
			
		||||
	float pid_out;
 | 
			
		||||
	float current_temp;
 | 
			
		||||
	static uint64_t timestamp_last_run;
 | 
			
		||||
 | 
			
		||||
	if (oven_pid_running && !oven_pid_aborted) {
 | 
			
		||||
		if (systick_ticks_have_passed(timestamp_last_run, (uint64_t)(oven_pid.sample_period * 1000))) {
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,7 @@ static volatile struct error_flag IN_SECTION(.ccm.data) flags[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static volatile struct timing_mon IN_SECTION(.ccm.data) timings[] = {
 | 
			
		||||
	TIM_MON_ENTRY(ERR_TIMING_PID, 2, 1000, ERR_FLAG_TIMING_PID),
 | 
			
		||||
	TIM_MON_ENTRY(ERR_TIMING_PID, 2, 5000, ERR_FLAG_TIMING_PID),
 | 
			
		||||
	TIM_MON_ENTRY(ERR_TIMING_MEAS_ADC, 0, 50, ERR_FLAG_TIMING_MEAS_ADC),
 | 
			
		||||
	TIM_MON_ENTRY(ERR_TIMING_SAFETY_ADC, 10, SAFETY_CONTROLLER_ADC_DELAY_MS + 1000, ERR_FLAG_SAFETY_ADC),
 | 
			
		||||
	TIM_MON_ENTRY(ERR_TIMING_MAIN_LOOP, 0, 1000, ERR_FLAG_TIMING_MAIN_LOOP),
 | 
			
		||||
@@ -538,6 +538,7 @@ static void safety_controller_handle_safety_adc()
 | 
			
		||||
{
 | 
			
		||||
	static uint64_t last_result_timestamp = 0;
 | 
			
		||||
	const uint16_t *channels;
 | 
			
		||||
	uint32_t sum;
 | 
			
		||||
	int poll_result;
 | 
			
		||||
	float analog_value;
 | 
			
		||||
 | 
			
		||||
@@ -546,9 +547,19 @@ static void safety_controller_handle_safety_adc()
 | 
			
		||||
	if (poll_result == 1) {
 | 
			
		||||
		/* Data available */
 | 
			
		||||
		channels = safety_adc_get_values();
 | 
			
		||||
		analog_value = safety_adc_convert_channel(SAFETY_ADC_MEAS_TEMP, channels[0]);
 | 
			
		||||
 | 
			
		||||
		/* Compute average of temp readings */
 | 
			
		||||
		sum = channels[0] + channels[1] + channels[2] + channels[3];
 | 
			
		||||
		sum /= 4;
 | 
			
		||||
 | 
			
		||||
		analog_value = safety_adc_convert_channel(SAFETY_ADC_MEAS_TEMP, (uint16_t)sum);
 | 
			
		||||
		safety_controller_report_analog_value(ERR_AMON_UC_TEMP, analog_value);
 | 
			
		||||
		analog_value = safety_adc_convert_channel(SAFETY_ADC_MEAS_VREF, channels[1]);
 | 
			
		||||
 | 
			
		||||
		/* Average VREF readings */
 | 
			
		||||
		sum = channels[4] + channels[5] + channels[6] + channels[7];
 | 
			
		||||
		sum /= 4;
 | 
			
		||||
 | 
			
		||||
		analog_value = safety_adc_convert_channel(SAFETY_ADC_MEAS_VREF, (uint16_t)sum);
 | 
			
		||||
		safety_controller_report_analog_value(ERR_AMON_VREF, analog_value);
 | 
			
		||||
		last_result_timestamp = systick_get_global_tick();
 | 
			
		||||
		safety_controller_report_timing(ERR_TIMING_SAFETY_ADC);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
#include <reflow-controller/systick.h>
 | 
			
		||||
#include <reflow-controller/adc-meas.h>
 | 
			
		||||
#include <reflow-controller/safety/safety-controller.h>
 | 
			
		||||
#include <reflow-controller/settings/settings.h>
 | 
			
		||||
#include <reflow-controller/temp-converter.h>
 | 
			
		||||
#include <helper-macros/helper-macros.h>
 | 
			
		||||
#include <stm-periph/unique-id.h>
 | 
			
		||||
@@ -33,6 +34,7 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <reflow-controller/oven-driver.h>
 | 
			
		||||
 | 
			
		||||
static char IN_SECTION(.ccm.bss) display_buffer[4][21] = {0};
 | 
			
		||||
static struct lcd_menu IN_SECTION(.ccm.bss) reflow_menu;
 | 
			
		||||
@@ -297,21 +299,113 @@ static void gui_menu_err_flags(struct lcd_menu *menu, enum menu_entry_func_entry
 | 
			
		||||
	timestamp = systick_get_global_tick();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gui_menu_constant_temperature_driver(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)
 | 
			
		||||
{
 | 
			
		||||
	static void IN_SECTION(.ccm.bss) *my_parent;
 | 
			
		||||
	static int16_t IN_SECTION(.ccm.bss) temperature;
 | 
			
		||||
	static bool IN_SECTION(.ccm.bss) fine;
 | 
			
		||||
	enum button_state button;
 | 
			
		||||
	int16_t rot;
 | 
			
		||||
	int16_t temp_old;
 | 
			
		||||
 | 
			
		||||
	if (entry_type == MENU_ENTRY_FIRST_ENTER) {
 | 
			
		||||
		my_parent = parent;
 | 
			
		||||
		temperature = 30;
 | 
			
		||||
		menu_display_clear(menu);
 | 
			
		||||
		menu_lcd_outputf(menu, 0, "Temp Controller");
 | 
			
		||||
		temp_old = 0;
 | 
			
		||||
	} else {
 | 
			
		||||
		temp_old = temperature;
 | 
			
		||||
	}
 | 
			
		||||
	if (menu_get_button_ready_state(menu)) {
 | 
			
		||||
		button = menu_get_button_state(menu);
 | 
			
		||||
		rot = menu_get_rotary_delta(menu);
 | 
			
		||||
		if (rot >= 4 || rot <= -4) {
 | 
			
		||||
			menu_ack_rotary_delta(menu);
 | 
			
		||||
			if (rot > 0)
 | 
			
		||||
				temperature += (fine ? 1 : 10);
 | 
			
		||||
			else
 | 
			
		||||
				temperature -= (fine ? 1 : 10);
 | 
			
		||||
			if (temperature > 300)
 | 
			
		||||
				temperature = 300;
 | 
			
		||||
			else if (temperature < 0)
 | 
			
		||||
				temperature = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch (button) {
 | 
			
		||||
		case BUTTON_SHORT_RELEASED:
 | 
			
		||||
			fine = !fine;
 | 
			
		||||
			break;
 | 
			
		||||
		case BUTTON_LONG:
 | 
			
		||||
			oven_pid_stop();
 | 
			
		||||
			menu_entry_dropback(menu, my_parent);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (oven_pid_get_status() != OVEN_PID_RUNNING) {
 | 
			
		||||
		menu_lcd_output(menu, 1, "PID stopped!");
 | 
			
		||||
		menu_lcd_output(menu, 2, "Check Flags!");
 | 
			
		||||
	} else {
 | 
			
		||||
		if (temperature != temp_old) {
 | 
			
		||||
			oven_pid_set_target_temperature((float)temperature);
 | 
			
		||||
			menu_lcd_outputf(menu, 1, "Temp: %d " LCD_DEGREE_SYMBOL_STRING "C", (int)temperature);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gui_menu_constant_temperature_driver_setup(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)
 | 
			
		||||
{
 | 
			
		||||
	static void IN_SECTION(.ccm.bss) *my_parent;
 | 
			
		||||
	struct oven_pid_settings pid_settings;
 | 
			
		||||
	enum button_state button;
 | 
			
		||||
	struct pid_controller pid_controller;
 | 
			
		||||
 | 
			
		||||
	if (entry_type == MENU_ENTRY_FIRST_ENTER) {
 | 
			
		||||
		my_parent = parent;
 | 
			
		||||
 | 
			
		||||
		/* Try loading PID parameters */
 | 
			
		||||
		if (settings_load_pid_oven_parameters(&pid_settings)) {
 | 
			
		||||
			menu_display_clear(menu);
 | 
			
		||||
			menu_lcd_output(menu, 0, "Could not load");
 | 
			
		||||
			menu_lcd_output(menu, 1, "PID parameters");
 | 
			
		||||
		} else {
 | 
			
		||||
			pid_init(&pid_controller, pid_settings.kd, pid_settings.ki, pid_settings.kp, 0, 100,
 | 
			
		||||
				 pid_settings.max_integral, pid_settings.t_sample);
 | 
			
		||||
			oven_pid_init(&pid_controller);
 | 
			
		||||
			menu_entry_enter(menu, gui_menu_constant_temperature_driver, true);
 | 
			
		||||
		}
 | 
			
		||||
	} else if (entry_type == MENU_ENTRY_DROPBACK) {
 | 
			
		||||
		menu_entry_dropback(menu, my_parent);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (menu_get_button_ready_state(menu)) {
 | 
			
		||||
		button = menu_get_button_state(menu);
 | 
			
		||||
		if (button == BUTTON_SHORT_RELEASED || button == BUTTON_LONG) {
 | 
			
		||||
			menu_entry_dropback(menu, my_parent);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gui_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)
 | 
			
		||||
{
 | 
			
		||||
	(void)parent;
 | 
			
		||||
	static struct menu_list list;
 | 
			
		||||
	bool menu_changed = false;
 | 
			
		||||
	static const char * const root_entry_names[] = {
 | 
			
		||||
		"About",
 | 
			
		||||
		"Constant Temp",
 | 
			
		||||
		"Monitoring",
 | 
			
		||||
		"Error Flags",
 | 
			
		||||
		"About",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
	static const menu_func_t root_entry_funcs[] = {
 | 
			
		||||
		gui_menu_about,
 | 
			
		||||
		gui_menu_constant_temperature_driver_setup,
 | 
			
		||||
		gui_menu_monitor,
 | 
			
		||||
		gui_menu_err_flags,
 | 
			
		||||
		gui_menu_about,
 | 
			
		||||
	};
 | 
			
		||||
	enum button_state push_button;
 | 
			
		||||
	int16_t rot_delta;
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,8 @@ void menu_entry_dropback(struct lcd_menu *menu, menu_func_t parent_func)
 | 
			
		||||
	else
 | 
			
		||||
		menu->active_entry = menu->root_entry;
 | 
			
		||||
 | 
			
		||||
	menu_ack_rotary_delta(menu);
 | 
			
		||||
 | 
			
		||||
	menu->active_entry_type = MENU_ENTRY_DROPBACK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user