split stepper conf
This commit is contained in:
parent
ffaa78798e
commit
8a099f5c21
@ -31,7 +31,9 @@ typedef struct{
|
||||
int32_t steps_counter;
|
||||
uint8_t stop_at_limit; // boolean to stop at stop_steps
|
||||
int32_t stop_steps; // position to stop at
|
||||
} pse_stepper_status;
|
||||
|
||||
typedef struct{
|
||||
GPIO_TypeDef* EN_GPIO_Port; // Pin definitions
|
||||
uint16_t EN_GPIO_Pin;
|
||||
GPIO_TypeDef* DIR_GPIO_Port;
|
||||
@ -59,12 +61,13 @@ typedef struct{
|
||||
pse_syringe* syringe; // associated syringe
|
||||
pse_stepper_conf* stepper_conf; // hardware configuration for the associated stepper
|
||||
pse_home_display* home_display; // Widgets for updating the home screen
|
||||
pse_stepper_status* stepper_status; // stepper position/speed status
|
||||
int32_t start_pos; // movement start position for volume calculation
|
||||
uint32_t nL_per_step; // pL delivered per step
|
||||
} pse_unit;
|
||||
|
||||
|
||||
void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, pse_home_display* home_displays, uint8_t unit_num, uint16_t ws_ind);
|
||||
void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, pse_stepper_status* stepper_status, pse_home_display* home_displays, uint8_t unit_num, uint16_t ws_ind);
|
||||
void load_units_short(pse_unit* units, uint8_t unit_num, uint16_t ws_ind);
|
||||
void save_units(pse_unit* units, uint8_t unit_num, uint16_t ws_ind);
|
||||
|
||||
|
@ -16,12 +16,12 @@
|
||||
#define PSE_STEPPER_JOG_PRESC 64 // jog step frequency 50kHz
|
||||
#define PSE_STEPPER_JOG_PERIOD 25 // 64Mhz / 64 / 10 / 2
|
||||
|
||||
void pse_sp_start_axis(pse_stepper_conf* conf);
|
||||
void pse_sp_start_axis(pse_stepper_conf* conf, pse_stepper_status* status);
|
||||
void pse_sp_stop_axis(pse_stepper_conf* conf);
|
||||
void pse_sp_set_dir(pse_stepper_conf* conf, int dir);
|
||||
int pse_sp_get_dir(pse_stepper_conf* conf);
|
||||
void pse_stepper_planer_tick(pse_unit* unit);
|
||||
void pse_sp_jog_speed(pse_stepper_conf* conf, int status);
|
||||
void pse_sp_jog_speed(pse_stepper_conf* conf, pse_stepper_status* sta, int status);
|
||||
|
||||
void pse_sp_set_dir_all(pse_unit* units, int unit_num, int dir);
|
||||
void pse_sp_start_all(pse_unit* units, int unit_num);
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void generate_default_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, pse_home_display* home_displays, uint8_t unit_num){
|
||||
static void generate_default_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs,pse_stepper_status* stepper_status, pse_home_display* home_displays, uint8_t unit_num){
|
||||
for(int i = 0; i < unit_num; i++){
|
||||
units[i] = (pse_unit){
|
||||
.enabled = i%2,
|
||||
@ -25,8 +25,9 @@ static void generate_default_units(pse_unit* units, pse_syringe* syringes, pse_s
|
||||
.volume = 0,
|
||||
.set_volume = 0,
|
||||
.syringe = &syringes[i],
|
||||
.stepper_conf = &stepper_confs[i],
|
||||
.home_display = &home_displays[i],
|
||||
.stepper_conf = &stepper_confs[i],
|
||||
.stepper_status = &stepper_status[i],
|
||||
.home_display = &home_displays[i],
|
||||
};
|
||||
syringes[i] = (pse_syringe){
|
||||
.name = "Test",
|
||||
@ -39,7 +40,7 @@ static void generate_default_units(pse_unit* units, pse_syringe* syringes, pse_s
|
||||
// Load units from file
|
||||
// Units configuration are saved as binary, in the order [pse_unit, pse_syringe, pse_stepper_conf] with each unit back to back
|
||||
// In case of any error fallback to a default configuration
|
||||
void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, pse_home_display* home_displays, uint8_t unit_num, uint16_t ws_ind){
|
||||
void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, pse_stepper_status* stepper_status, pse_home_display* home_displays, uint8_t unit_num, uint16_t ws_ind){
|
||||
// Open save file
|
||||
FIL saveFile;
|
||||
|
||||
@ -54,7 +55,7 @@ void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* steppe
|
||||
if(f_open(&saveFile, filename, FA_READ) != FR_OK){
|
||||
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Error", "Could not load configuration from SD card", NULL, true);
|
||||
lv_obj_center(mbox1);
|
||||
generate_default_units(units, syringes, stepper_confs, home_displays, unit_num);
|
||||
generate_default_units(units, syringes, stepper_confs, stepper_status, home_displays, unit_num);
|
||||
free(filename);
|
||||
return;
|
||||
}
|
||||
@ -68,12 +69,13 @@ void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* steppe
|
||||
units[i].syringe = &syringes[i];
|
||||
units[i].stepper_conf = &stepper_confs[i];
|
||||
units[i].home_display = &home_displays[i];
|
||||
units[i].stepper_status = &stepper_status[i];
|
||||
|
||||
res += f_read(&saveFile, units[i].syringe, sizeof(pse_syringe), &bytesRead);
|
||||
res += f_read(&saveFile, units[i].stepper_conf, sizeof(pse_stepper_conf), &bytesRead);
|
||||
res += f_read(&saveFile, units[i].stepper_status, sizeof(pse_stepper_status), &bytesRead);
|
||||
|
||||
if(res != FR_OK){
|
||||
generate_default_units(units, syringes, stepper_confs, home_displays, unit_num);
|
||||
generate_default_units(units, syringes, stepper_confs, stepper_status, home_displays, unit_num);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -82,7 +84,7 @@ void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* steppe
|
||||
}
|
||||
|
||||
void load_units_short(pse_unit* units, uint8_t unit_num, uint16_t ws_ind){
|
||||
load_units(units, units->syringe, units->stepper_conf, units->home_display, unit_num, ws_ind);
|
||||
load_units(units, units->syringe, units->stepper_conf, units->stepper_status , units->home_display, unit_num, ws_ind);
|
||||
}
|
||||
|
||||
void save_units(pse_unit* units, uint8_t unit_num, uint16_t ws_ind){
|
||||
@ -112,7 +114,7 @@ void save_units(pse_unit* units, uint8_t unit_num, uint16_t ws_ind){
|
||||
UINT bytesRead;
|
||||
res = f_write(&saveFile, &units[i], sizeof(units[i]), &bytesRead);
|
||||
res += f_write(&saveFile, units[i].syringe, sizeof(pse_syringe), &bytesRead);
|
||||
res += f_write(&saveFile, units[i].stepper_conf, sizeof(pse_stepper_conf), &bytesRead);
|
||||
res += f_write(&saveFile, units[i].stepper_status, sizeof(pse_stepper_status), &bytesRead);
|
||||
|
||||
if(res != FR_OK){
|
||||
return;
|
||||
@ -124,7 +126,7 @@ void save_units(pse_unit* units, uint8_t unit_num, uint16_t ws_ind){
|
||||
}
|
||||
|
||||
void pse_unit_compute_volume_delivered(pse_unit* unit){
|
||||
unit->volume = (int64_t)1 * (unit->stepper_conf->steps_counter - unit->start_pos) * unit->nL_per_step / 1000;
|
||||
unit->volume = (int64_t)1 * (unit->stepper_status->steps_counter - unit->start_pos) * unit->nL_per_step / 1000;
|
||||
}
|
||||
|
||||
void pse_unit_compute_volume_per_step(pse_unit* unit){
|
||||
|
@ -38,10 +38,12 @@ static void back_button_handler(lv_event_t * e){
|
||||
|
||||
// set limit if volume defined
|
||||
if(c_pse_unit->set_volume != 0){
|
||||
c_pse_unit->stepper_conf->stop_at_limit = 1;
|
||||
c_pse_unit->stepper_conf->stop_steps = (uint64_t)1000 * c_pse_unit->set_volume / c_pse_unit->nL_per_step; }
|
||||
if(c_pse_unit->nL_per_step == 0) return; // TODO: alert popup / better resolution
|
||||
if(c_pse_unit->flow == 0) return;
|
||||
c_pse_unit->stepper_status->stop_at_limit = 1;
|
||||
c_pse_unit->stepper_status->stop_steps = (uint64_t)1000 * c_pse_unit->set_volume / c_pse_unit->nL_per_step; }
|
||||
else
|
||||
c_pse_unit->stepper_conf->stop_at_limit = 0;
|
||||
c_pse_unit->stepper_status->stop_at_limit = 0;
|
||||
|
||||
// go back to the main menu
|
||||
Home_Screen_Gen(c_pse_units, c_pse_units_num, true);
|
||||
@ -167,12 +169,12 @@ static void jog_forward_button_handler(lv_event_t* e){
|
||||
pse_unit* unit = lv_event_get_user_data(e);
|
||||
|
||||
if(code == LV_EVENT_PRESSED) {
|
||||
pse_sp_jog_speed(unit->stepper_conf, 1);
|
||||
pse_sp_jog_speed(unit->stepper_conf, unit->stepper_status, 1);
|
||||
pse_sp_set_dir(unit->stepper_conf, 1);
|
||||
pse_sp_start_axis(unit->stepper_conf);
|
||||
pse_sp_start_axis(unit->stepper_conf, unit->stepper_status);
|
||||
}
|
||||
else if(code == LV_EVENT_RELEASED){
|
||||
pse_sp_jog_speed(unit->stepper_conf, 0);
|
||||
pse_sp_jog_speed(unit->stepper_conf, unit->stepper_status, 0);
|
||||
pse_sp_stop_axis(unit->stepper_conf);
|
||||
}
|
||||
}
|
||||
@ -182,12 +184,12 @@ static void jog_backward_button_handler(lv_event_t* e){
|
||||
pse_unit* unit = lv_event_get_user_data(e);
|
||||
|
||||
if(code == LV_EVENT_PRESSED) {
|
||||
pse_sp_jog_speed(unit->stepper_conf, 1);
|
||||
pse_sp_jog_speed(unit->stepper_conf, unit->stepper_status, 1);
|
||||
pse_sp_set_dir(unit->stepper_conf, 0);
|
||||
pse_sp_start_axis(unit->stepper_conf);
|
||||
pse_sp_start_axis(unit->stepper_conf, unit->stepper_status);
|
||||
}
|
||||
else if(code == LV_EVENT_RELEASED){
|
||||
pse_sp_jog_speed(unit->stepper_conf, 0);
|
||||
pse_sp_jog_speed(unit->stepper_conf, unit->stepper_status, 0);
|
||||
pse_sp_stop_axis(unit->stepper_conf);
|
||||
}
|
||||
}
|
||||
@ -197,7 +199,7 @@ static void set_home_button_handler(lv_event_t* e){
|
||||
pse_unit* unit = lv_event_get_user_data(e);
|
||||
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
unit->stepper_conf->steps_counter = 0;
|
||||
unit->stepper_status->steps_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,12 +95,13 @@ static void unit_home_handler(lv_event_t * e){
|
||||
if(code == LV_EVENT_CLICKED) {
|
||||
pse_unit* unit = lv_event_get_user_data(e);
|
||||
pse_stepper_conf* c = unit->stepper_conf;
|
||||
if(c->steps_counter == 0) return;
|
||||
c->stop_at_limit = 1;
|
||||
c->stop_steps = 0;
|
||||
pse_sp_jog_speed(c, 1);
|
||||
pse_sp_set_dir(c, c->steps_counter < 0);
|
||||
pse_sp_start_axis(c);
|
||||
pse_stepper_status* s = unit->stepper_status;
|
||||
if(s->steps_counter == 0) return;
|
||||
s->stop_at_limit = 1;
|
||||
s->stop_steps = 0;
|
||||
pse_sp_jog_speed(c, s, 1);
|
||||
pse_sp_set_dir(c, s->steps_counter < 0);
|
||||
pse_sp_start_axis(c, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,18 @@
|
||||
|
||||
void pse_stepper_planer_tick(pse_unit* unit){
|
||||
pse_stepper_conf* c = unit->stepper_conf;
|
||||
pse_stepper_status* s = unit->stepper_status;
|
||||
|
||||
HAL_GPIO_TogglePin(c->STEP_GPIO_Port, c->STEP_GPIO_Pin);
|
||||
c->steps_counter += (pse_sp_get_dir(c)?1:-1) * HAL_GPIO_ReadPin(c->STEP_GPIO_Port, c->STEP_GPIO_Pin);
|
||||
if(c->stop_at_limit && c->steps_counter == c->stop_steps){
|
||||
pse_sp_jog_speed(c, 0);
|
||||
s->steps_counter += (pse_sp_get_dir(c)?1:-1) * HAL_GPIO_ReadPin(c->STEP_GPIO_Port, c->STEP_GPIO_Pin);
|
||||
if(s->stop_at_limit && s->steps_counter == s->stop_steps){
|
||||
pse_sp_jog_speed(c, s, 0);
|
||||
pse_sp_stop_axis(c);
|
||||
}
|
||||
}
|
||||
|
||||
void pse_sp_start_axis(pse_stepper_conf* conf){
|
||||
if(conf->stop_at_limit && conf->steps_counter == conf->stop_steps) return;
|
||||
void pse_sp_start_axis(pse_stepper_conf* conf, pse_stepper_status* status){
|
||||
if(status->stop_at_limit && status->steps_counter == status->stop_steps) return;
|
||||
|
||||
HAL_GPIO_WritePin(conf->EN_GPIO_Port, conf->EN_GPIO_Pin, GPIO_PIN_RESET);
|
||||
HAL_TIM_Base_Start_IT(conf->tim);
|
||||
@ -61,6 +62,8 @@ static uint16_t int_sqrt(uint32_t s){
|
||||
|
||||
void pse_stepper_planer_compute_sps(pse_unit* unit){
|
||||
pse_stepper_conf* c = unit->stepper_conf;
|
||||
pse_stepper_status* s = unit->stepper_status;
|
||||
|
||||
// magic constants are used to approximate pi and other multiplicatives constant as a rationnal
|
||||
uint64_t numerator = (uint64_t)14323 * unit->syringe->diameter * unit->syringe->diameter * PSE_STEPPER_TIMER_CLOCK * PSE_STEPPER_SCREW_PITCH;
|
||||
uint64_t denominator = (uint64_t)607887 * unit->flow * PSE_STEPPER_STEPS_PER_ROTATION;
|
||||
@ -77,17 +80,17 @@ void pse_stepper_planer_compute_sps(pse_unit* unit){
|
||||
}
|
||||
|
||||
if(res < 65536){
|
||||
c->tim_presc = 0;
|
||||
c->tim_period = res - 1;
|
||||
__HAL_TIM_SET_AUTORELOAD(c->tim, c->tim_period);
|
||||
__HAL_TIM_SET_PRESCALER(c->tim, c->tim_presc);
|
||||
s->tim_presc = 0;
|
||||
s->tim_period = res - 1;
|
||||
__HAL_TIM_SET_AUTORELOAD(c->tim, s->tim_period);
|
||||
__HAL_TIM_SET_PRESCALER(c->tim, s->tim_presc);
|
||||
}
|
||||
else{
|
||||
uint16_t sqrt = int_sqrt(res);
|
||||
c->tim_presc = sqrt - 1;
|
||||
c->tim_period = sqrt;
|
||||
__HAL_TIM_SET_AUTORELOAD(c->tim, c->tim_period);
|
||||
__HAL_TIM_SET_PRESCALER(c->tim, c->tim_presc);
|
||||
s->tim_presc = sqrt - 1;
|
||||
s->tim_period = sqrt;
|
||||
__HAL_TIM_SET_AUTORELOAD(c->tim, s->tim_period);
|
||||
__HAL_TIM_SET_PRESCALER(c->tim, s->tim_presc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +103,7 @@ void pse_sp_set_dir_all(pse_unit* units, int units_num, int dir){
|
||||
void pse_sp_start_all(pse_unit* units, int units_num){
|
||||
for(int i = 0; i < units_num; i++){
|
||||
if(units[i].enabled){
|
||||
pse_sp_start_axis(units[i].stepper_conf);
|
||||
pse_sp_start_axis(units[i].stepper_conf, units[i].stepper_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,13 +114,13 @@ void pse_sp_stop_all(pse_unit* units, int units_num){
|
||||
}
|
||||
}
|
||||
|
||||
void pse_sp_jog_speed(pse_stepper_conf* conf, int status){
|
||||
void pse_sp_jog_speed(pse_stepper_conf* conf, pse_stepper_status* sta, int status){
|
||||
if(status){
|
||||
__HAL_TIM_SET_AUTORELOAD(conf->tim, PSE_STEPPER_JOG_PERIOD);
|
||||
__HAL_TIM_SET_PRESCALER(conf->tim, PSE_STEPPER_JOG_PRESC);
|
||||
}
|
||||
else{
|
||||
__HAL_TIM_SET_AUTORELOAD(conf->tim, conf->tim_period);
|
||||
__HAL_TIM_SET_PRESCALER(conf->tim, conf->tim_presc);
|
||||
__HAL_TIM_SET_AUTORELOAD(conf->tim, sta->tim_period);
|
||||
__HAL_TIM_SET_PRESCALER(conf->tim, sta->tim_presc);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user