Save configuration to SD card + take microstepping into account

This commit is contained in:
leo 2023-08-24 14:48:20 +02:00
parent 73c78dd8dd
commit 2fc79d35f9
Signed by: leo
GPG Key ID: 0DD993BFB2B307DB
7 changed files with 104 additions and 42 deletions

View File

@ -43,5 +43,6 @@ typedef struct{
} pse_unit; } pse_unit;
void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, uint8_t unit_num); void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, uint8_t unit_num);
void save_units(pse_unit* units, uint8_t unit_num);
#endif #endif

View File

@ -10,6 +10,6 @@
#include "PSE_unit.h" #include "PSE_unit.h"
void PSE_unit_edit_screen_Gen(lv_obj_t* parent, pse_unit* unit); void PSE_unit_edit_screen_Gen(lv_obj_t* parent, pse_unit* units, pse_unit* unit, uint8_t units_num);
#endif /* INC_PSE_EDIT_SCREEN_H_ */ #endif /* INC_PSE_EDIT_SCREEN_H_ */

View File

@ -12,7 +12,7 @@
#define PSE_STEPPER_INTERRUPT_RATE 20000 // 64Mhz (Presc 64, count 50) : 20kHz #define PSE_STEPPER_INTERRUPT_RATE 20000 // 64Mhz (Presc 64, count 50) : 20kHz
#define PSE_STEPPER_SCREW_PITCH 1000 // M6 : 1000µm / rotation #define PSE_STEPPER_SCREW_PITCH 1000 // M6 : 1000µm / rotation
#define PSE_STEPPER_STEPS_PER_ROTATION 200 // NEMA17 without microstepping 200 steps/rotation #define PSE_STEPPER_STEPS_PER_ROTATION 6400 // NEMA17 200 steps/rotation with 32x microstepping
void pse_sp_start_axis(pse_stepper_conf* conf); void pse_sp_start_axis(pse_stepper_conf* conf);
void pse_sp_stop_axis(pse_stepper_conf* conf); void pse_sp_stop_axis(pse_stepper_conf* conf);

View File

@ -7,21 +7,81 @@
#include "PSE_unit.h" #include "PSE_unit.h"
// TODO: load from SD-card #include "fatfs.h"
void load_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, uint8_t unit_num){ #include "lvgl.h"
for(int i = 0; i < unit_num; i++){
units[i] = (pse_unit){ static void generate_default_units(pse_unit* units, pse_syringe* syringes, pse_stepper_conf* stepper_confs, uint8_t unit_num){
.enabled = i%2, for(int i = 0; i < unit_num; i++){
.port = i, units[i] = (pse_unit){
.flow = 1500*i, .enabled = i%2,
.volume = 0, .port = i,
.set_volume = 0, .flow = 1500*i,
.syringe = &syringes[i], .volume = 0,
.stepper_conf = &stepper_confs[i], .set_volume = 0,
}; .syringe = &syringes[i],
syringes[i] = (pse_syringe){ .stepper_conf = &stepper_confs[i],
.name = "Test", };
.diameter = 26700, syringes[i] = (pse_syringe){
}; .name = "Test",
} .diameter = 26700,
};
}
}
// 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, uint8_t unit_num){
// Open save file
FIL saveFile;
if(f_open(&saveFile, "PSE_save.txt", FA_READ) != FR_OK){
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Error", "Could not load configuration to SD card", NULL, true);
lv_obj_center(mbox1);
generate_default_units(units, syringes, stepper_confs, unit_num);
return;
}
// read configuration sequentially
for(int i = 0; i < unit_num; i++){
FRESULT res;
UINT bytesRead;
res = f_read(&saveFile, &units[i], sizeof(units[i]), &bytesRead);
units[i].syringe = &syringes[i];
units[i].stepper_conf = &stepper_confs[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);
if(res != FR_OK){
generate_default_units(units, syringes, stepper_confs, unit_num);
return;
}
}
f_close(&saveFile);
}
void save_units(pse_unit* units, uint8_t unit_num){
// Open save file
FIL saveFile;
if(f_open(&saveFile, "PSE_save.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK){
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Error", "Could not save configuration to SD card", NULL, true);
lv_obj_center(mbox1);
return;
}
for(int i = 0; i < unit_num; i++){
FRESULT res;
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);
if(res != FR_OK){
return;
}
}
f_close(&saveFile);
} }

View File

@ -19,13 +19,16 @@
static lv_obj_t* parent_screen; static lv_obj_t* parent_screen;
static lv_obj_t* this_screen; static lv_obj_t* this_screen;
static pse_unit* c_pse_units;
static pse_unit* c_pse_unit; static pse_unit* c_pse_unit;
static uint8_t c_pse_units_num;
static void back_button_handler(lv_event_t * e){ static void back_button_handler(lv_event_t * e){
lv_event_code_t code = lv_event_get_code(e); lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) { if(code == LV_EVENT_CLICKED) {
// Save save_units(c_pse_units, c_pse_units_num);
// update stepper pwm generation // update stepper pwm generation
pse_stepper_planer_compute_sps(c_pse_unit); pse_stepper_planer_compute_sps(c_pse_unit);
@ -191,13 +194,15 @@ static lv_obj_t* controls_widget(lv_obj_t* parent, pse_unit* unit){
return cont; return cont;
} }
void PSE_unit_edit_screen_Gen(lv_obj_t* parent, pse_unit* unit){ void PSE_unit_edit_screen_Gen(lv_obj_t* parent, pse_unit* units, pse_unit* c_unit, uint8_t units_num){
parent_screen = parent; parent_screen = parent;
// Create a new screen // Create a new screen
lv_obj_t* scr = lv_obj_create(NULL); lv_obj_t* scr = lv_obj_create(NULL);
this_screen = scr; this_screen = scr;
c_pse_unit = unit; c_pse_units = units;
c_pse_unit = c_unit;
c_pse_units_num = units_num;
// create the top menu on the top 20% // create the top menu on the top 20%
lv_obj_t* top_menu = lv_obj_create(scr); lv_obj_t* top_menu = lv_obj_create(scr);
@ -226,16 +231,16 @@ void PSE_unit_edit_screen_Gen(lv_obj_t* parent, pse_unit* unit){
lv_obj_set_grid_dsc_array(units_grid, widg_col_dsc, widg_row_dsc); lv_obj_set_grid_dsc_array(units_grid, widg_col_dsc, widg_row_dsc);
// Flow widget // Flow widget
lv_obj_t* flow = flow_widget(units_grid, unit); lv_obj_t* flow = flow_widget(units_grid, c_unit);
lv_obj_set_grid_cell(flow, LV_GRID_ALIGN_CENTER, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1); lv_obj_set_grid_cell(flow, LV_GRID_ALIGN_CENTER, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1);
// Set volume widget // Set volume widget
lv_obj_t* vol = volume_widget(units_grid, unit); lv_obj_t* vol = volume_widget(units_grid, c_unit);
lv_obj_set_grid_cell(vol, LV_GRID_ALIGN_CENTER, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); lv_obj_set_grid_cell(vol, LV_GRID_ALIGN_CENTER, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);
// Syringe widget // Syringe widget
lv_obj_t* syringe = syringe_widget(units_grid, unit); lv_obj_t* syringe = syringe_widget(units_grid, c_unit);
lv_obj_set_grid_cell(syringe, LV_GRID_ALIGN_CENTER, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1); lv_obj_set_grid_cell(syringe, LV_GRID_ALIGN_CENTER, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1);
// controls widget // controls widget
lv_obj_t* controls = controls_widget(units_grid, unit); lv_obj_t* controls = controls_widget(units_grid, c_unit);
lv_obj_set_grid_cell(controls, LV_GRID_ALIGN_CENTER, 3, 1, LV_GRID_ALIGN_CENTER, 0, 1); lv_obj_set_grid_cell(controls, LV_GRID_ALIGN_CENTER, 3, 1, LV_GRID_ALIGN_CENTER, 0, 1);
// fade in the new screen // fade in the new screen

View File

@ -66,7 +66,7 @@ static void unit_widget_clicked_handler(lv_event_t* e){
if(code == LV_EVENT_CLICKED) { if(code == LV_EVENT_CLICKED) {
pse_unit* unit = lv_event_get_user_data(e); pse_unit* unit = lv_event_get_user_data(e);
PSE_unit_edit_screen_Gen(screen, unit); PSE_unit_edit_screen_Gen(screen, units, unit, units_num);
} }
} }

View File

@ -231,7 +231,7 @@ int main(void)
disp_drv.flush_cb = &my_flush_cb; disp_drv.flush_cb = &my_flush_cb;
lv_disp_drv_register(&disp_drv); lv_disp_drv_register(&disp_drv);
lv_disp_t * disp = lv_disp_drv_register(&disp_drv); lv_disp_drv_register(&disp_drv);
// load the default theme // load the default theme
lv_theme_t * th = lv_theme_default_init(lv_disp_get_default(), lv_color_hex(0x2BAEE1), lv_color_hex(0x001361), true, LV_FONT_DEFAULT); lv_theme_t * th = lv_theme_default_init(lv_disp_get_default(), lv_color_hex(0x2BAEE1), lv_color_hex(0x001361), true, LV_FONT_DEFAULT);
@ -261,23 +261,19 @@ int main(void)
// initialize the Touchscreen Driver // initialize the Touchscreen Driver
ADS7843_Init(&Touch_Def); ADS7843_Init(&Touch_Def);
load_units(pse_units, pse_syringes, pse_stepper_confs, PSE_UNITS_NUM); // mount the SD card
pse_sp_set_timer(&htim4); char SD_disk_path[4];
Home_Screen_Gen(pse_units, PSE_UNITS_NUM);
// SD tests
char mynewdiskPath[4];
FATFS FatFs; FATFS FatFs;
uint8_t wtext[] = "Hello world"; f_mount(&FatFs, SD_disk_path, 0);
uint32_t wbytes;
FIL MyFile;
HAL_Delay(1000); // Load saved units
load_units(pse_units, pse_syringes, pse_stepper_confs, PSE_UNITS_NUM);
f_mount(&FatFs, mynewdiskPath, 0); // Set timer used for step interrupts
f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE); pse_sp_set_timer(&htim4);
f_write(&MyFile, wtext, sizeof(wtext), (void *)&wbytes);
f_close(&MyFile); // Load the home screen
Home_Screen_Gen(pse_units, PSE_UNITS_NUM);
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Infinite loop */ /* Infinite loop */