From 93f0463b2125f2926bba4655545ccda084e4cd9a Mon Sep 17 00:00:00 2001 From: Simon Oliver Date: Tue, 19 Mar 2013 09:05:11 -0500 Subject: [PATCH] Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset). Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read. Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks. Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk. Conflicts: Marlin/language.h --- Marlin/ConfigurationStore.cpp | 105 ++++++++++-------- Marlin/Marlin_main.cpp | 35 +++--- Marlin/language.h | 23 +++- Marlin/planner.cpp | 10 +- Marlin/planner.h | 2 + Marlin/temperature.cpp | 28 +++++ Marlin/temperature.h | 9 +- Marlin/ultralcd.cpp | 85 ++++++++++++-- .../ultralcd_implementation_hitachi_HD44780.h | 20 ++++ 9 files changed, 243 insertions(+), 74 deletions(-) diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index 6d4777701..574c438ad 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -3,26 +3,26 @@ #include "temperature.h" #include "ultralcd.h" #include "ConfigurationStore.h" - -void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) -{ - do - { - eeprom_write_byte((unsigned char*)pos, *value); - pos++; - value++; + +void _EEPROM_writeData(int &pos, uint8_t* value, uint8_t size) +{ + do + { + eeprom_write_byte((unsigned char*)pos, *value); + pos++; + value++; }while(--size); -} +} #define EEPROM_WRITE_VAR(pos, value) _EEPROM_writeData(pos, (uint8_t*)&value, sizeof(value)) -void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) -{ - do - { - *value = eeprom_read_byte((unsigned char*)pos); - pos++; - value++; +void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) +{ + do + { + *value = eeprom_read_byte((unsigned char*)pos); + pos++; + value++; }while(--size); -} +} #define EEPROM_READ_VAR(pos, value) _EEPROM_readData(pos, (uint8_t*)&value, sizeof(value)) //====================================================================================== @@ -43,7 +43,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) void Config_StoreSettings() { char ver[4]= "000"; - int i=EEPROM_OFFSET; + int i=EEPROM_OFFSET; EEPROM_WRITE_VAR(i,ver); // invalidate data first EEPROM_WRITE_VAR(i,axis_steps_per_unit); EEPROM_WRITE_VAR(i,max_feedrate); @@ -58,8 +58,8 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,max_e_jerk); EEPROM_WRITE_VAR(i,add_homeing); #ifndef ULTIPANEL - int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED; - int absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP, absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP, absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; + int plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP, plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP, plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED; + int absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP, absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP, absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; #endif EEPROM_WRITE_VAR(i,plaPreheatHotendTemp); EEPROM_WRITE_VAR(i,plaPreheatHPBTemp); @@ -75,7 +75,7 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,3000); EEPROM_WRITE_VAR(i,0); EEPROM_WRITE_VAR(i,0); - #endif + #endif char ver2[4]=EEPROM_VERSION; i=EEPROM_OFFSET; EEPROM_WRITE_VAR(i,ver2); // validate data @@ -105,7 +105,7 @@ void Config_PrintSettings() SERIAL_ECHOPAIR(" Z", max_feedrate[2] ); SERIAL_ECHOPAIR(" E", max_feedrate[3]); SERIAL_ECHOLN(""); - + SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Maximum Acceleration (mm/s2):"); SERIAL_ECHO_START; @@ -120,9 +120,9 @@ void Config_PrintSettings() SERIAL_ECHOPAIR(" M204 S",acceleration ); SERIAL_ECHOPAIR(" T" ,retract_acceleration); SERIAL_ECHOLN(""); - + SERIAL_ECHO_START; - SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s), Z=maximum Z jerk (mm/s)"); + SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s), Z=maximum Z jerk (mm/s), E=maximum E jerk (mm/s)"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M205 S",minimumfeedrate ); SERIAL_ECHOPAIR(" T" ,mintravelfeedrate ); @@ -131,7 +131,7 @@ void Config_PrintSettings() SERIAL_ECHOPAIR(" Z" ,max_z_jerk); SERIAL_ECHOPAIR(" E" ,max_e_jerk); SERIAL_ECHOLN(""); - + SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Home offset (mm):"); SERIAL_ECHO_START; @@ -144,8 +144,8 @@ void Config_PrintSettings() SERIAL_ECHOLNPGM("PID settings:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M301 P",Kp); - SERIAL_ECHOPAIR(" I" ,Ki/PID_dT); - SERIAL_ECHOPAIR(" D" ,Kd*PID_dT); + SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki)); + SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd)); SERIAL_ECHOLN(""); #endif } @@ -161,11 +161,15 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,stored_ver); //read stored version // SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]"); if (strncmp(ver,stored_ver,3) == 0) - { + { // version number match EEPROM_READ_VAR(i,axis_steps_per_unit); EEPROM_READ_VAR(i,max_feedrate); EEPROM_READ_VAR(i,max_acceleration_units_per_sq_second); + + // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner) + reset_acceleration_rates(); + EEPROM_READ_VAR(i,acceleration); EEPROM_READ_VAR(i,retract_acceleration); EEPROM_READ_VAR(i,minimumfeedrate); @@ -176,36 +180,37 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,max_e_jerk); EEPROM_READ_VAR(i,add_homeing); #ifndef ULTIPANEL - int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed; - int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed; + int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed; + int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed; #endif EEPROM_READ_VAR(i,plaPreheatHotendTemp); EEPROM_READ_VAR(i,plaPreheatHPBTemp); EEPROM_READ_VAR(i,plaPreheatFanSpeed); EEPROM_READ_VAR(i,absPreheatHotendTemp); EEPROM_READ_VAR(i,absPreheatHPBTemp); - EEPROM_READ_VAR(i,absPreheatFanSpeed); + EEPROM_READ_VAR(i,absPreheatFanSpeed); #ifndef PIDTEMP float Kp,Ki,Kd; #endif + // do not need to scale PID values as the values in EEPROM are already scaled EEPROM_READ_VAR(i,Kp); EEPROM_READ_VAR(i,Ki); EEPROM_READ_VAR(i,Kd); + // Call updatePID (similar to when we have processed M301) + updatePID(); SERIAL_ECHO_START; - SERIAL_ECHOLNPGM("Stored settings retreived:"); + SERIAL_ECHOLNPGM("Stored settings retrieved"); + } + else + { + Config_ResetDefault(); } - else - { - Config_ResetDefault(); - SERIAL_ECHO_START; - SERIAL_ECHOLN("Using Default settings:"); - } Config_PrintSettings(); } -#endif - -void Config_ResetDefault() +#endif + +void Config_ResetDefault() { float tmp1[]=DEFAULT_AXIS_STEPS_PER_UNIT; float tmp2[]=DEFAULT_MAX_FEEDRATE; @@ -216,6 +221,10 @@ void Config_ResetDefault() max_feedrate[i]=tmp2[i]; max_acceleration_units_per_sq_second[i]=tmp3[i]; } + + // steps per sq second need to be updated to agree with the units per sq second + reset_acceleration_rates(); + acceleration=DEFAULT_ACCELERATION; retract_acceleration=DEFAULT_RETRACT_ACCELERATION; minimumfeedrate=DEFAULT_MINIMUMFEEDRATE; @@ -234,11 +243,19 @@ void Config_ResetDefault() absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; #endif #ifdef PIDTEMP - Kp = DEFAULT_Kp; - Ki = (DEFAULT_Ki*PID_dT); - Kd = (DEFAULT_Kd/PID_dT); + Kp = DEFAULT_Kp; + Ki = scalePID_i(DEFAULT_Ki); + Kd = scalePID_d(DEFAULT_Kd); + + // call updatePID (similar to when we have processed M301) + updatePID(); + #ifdef PID_ADD_EXTRUSION_RATE Kc = DEFAULT_Kc; #endif//PID_ADD_EXTRUSION_RATE #endif//PIDTEMP + +SERIAL_ECHO_START; +SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); + } diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 016a2036e..a76f321ed 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -363,13 +363,8 @@ void setup() fromsd[i] = false; } - Config_RetrieveSettings(); // loads data from EEPROM if available - - for(int8_t i=0; i < NUM_AXIS; i++) - { - axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i]; - } - + // loads data from EEPROM if available else uses defaults (and resets step acceleration rate) + Config_RetrieveSettings(); tp_init(); // Initialize temperature loop plan_init(); // Initialize planner; @@ -1323,9 +1318,10 @@ void process_commands() if(code_seen(axis_codes[i])) { max_acceleration_units_per_sq_second[i] = code_value(); - axis_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i]; } } + // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner) + reset_acceleration_rates(); break; #if 0 // Not used for Sprinter/grbl gen6 case 202: // M202 @@ -1468,22 +1464,25 @@ void process_commands() case 301: // M301 { if(code_seen('P')) Kp = code_value(); - if(code_seen('I')) Ki = code_value()*PID_dT; - if(code_seen('D')) Kd = code_value()/PID_dT; + if(code_seen('I')) Ki = scalePID_i(code_value()); + if(code_seen('D')) Kd = scalePID_d(code_value()); + #ifdef PID_ADD_EXTRUSION_RATE if(code_seen('C')) Kc = code_value(); #endif + updatePID(); SERIAL_PROTOCOL(MSG_OK); SERIAL_PROTOCOL(" p:"); SERIAL_PROTOCOL(Kp); SERIAL_PROTOCOL(" i:"); - SERIAL_PROTOCOL(Ki/PID_dT); + SERIAL_PROTOCOL(unscalePID_i(Ki)); SERIAL_PROTOCOL(" d:"); - SERIAL_PROTOCOL(Kd*PID_dT); + SERIAL_PROTOCOL(unscalePID_d(Kd)); #ifdef PID_ADD_EXTRUSION_RATE SERIAL_PROTOCOL(" c:"); - SERIAL_PROTOCOL(Kc*PID_dT); + //Kc does not have scaling applied above, or in resetting defaults + SERIAL_PROTOCOL(Kc); #endif SERIAL_PROTOCOLLN(""); } @@ -1493,16 +1492,18 @@ void process_commands() case 304: // M304 { if(code_seen('P')) bedKp = code_value(); - if(code_seen('I')) bedKi = code_value()*PID_dT; - if(code_seen('D')) bedKd = code_value()/PID_dT; + if(code_seen('I')) bedKi = scalePID_i(code_value()); + if(code_seen('D')) bedKd = scalePID_d(code_value()); + // Scale the Bed PID values by PID_dT + scaleBedPID(); updatePID(); SERIAL_PROTOCOL(MSG_OK); SERIAL_PROTOCOL(" p:"); SERIAL_PROTOCOL(bedKp); SERIAL_PROTOCOL(" i:"); - SERIAL_PROTOCOL(bedKi/PID_dT); + SERIAL_PROTOCOL(unscalePID_i(bedKi)); SERIAL_PROTOCOL(" d:"); - SERIAL_PROTOCOL(bedKd*PID_dT); + SERIAL_PROTOCOL(unscalePID_d(bedKd)); SERIAL_PROTOCOLLN(""); } break; diff --git a/Marlin/language.h b/Marlin/language.h index c3eb71d5e..f562ea282 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -75,7 +75,9 @@ #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" #define MSG_ACC "Accel" - #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX "Vmax " #define MSG_X "x" #define MSG_Y "y" @@ -233,6 +235,8 @@ #define MSG_PID_C "PID-C" #define MSG_ACC "Acc" #define MSG_VXY_JERK "Zryw Vxy" + #define MSG_VZ_JERK "Zryw Vz" + #define MSG_VE_JERK "Zryw Ve" #define MSG_VMAX "Vmax" #define MSG_X "x" #define MSG_Y "y" @@ -391,7 +395,9 @@ #define MSG_PID_D " PID-D: " #define MSG_PID_C " PID-C: " #define MSG_ACC " Acc:" -#define MSG_VXY_JERK " Vxy-jerk: " +#define MSG_VXY_JERK "Vxy-jerk" +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX " Vmax " #define MSG_X "x:" #define MSG_Y "y:" @@ -555,6 +561,8 @@ #define MSG_PID_C "PID-C" #define MSG_ACC "Acc" #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX "Vmax " #define MSG_X "x" #define MSG_Y "y" @@ -713,6 +721,8 @@ #define MSG_PID_C " PID-C: " #define MSG_ACC " Acc:" #define MSG_VXY_JERK " Vxy-jerk: " +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX " Vmax " #define MSG_X "x:" #define MSG_Y "y:" @@ -871,6 +881,8 @@ #define MSG_PID_C " PID-C: " #define MSG_ACC " Acc:" #define MSG_VXY_JERK " Vxy-jerk: " +#define MSG_VZ_JERK "Vz-jerk" +#define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX " Vmax " #define MSG_X "x:" #define MSG_Y "y:" @@ -1024,6 +1036,8 @@ #define MSG_PID_C "PID-C" #define MSG_ACC "Accel" #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX "Vmax" #define MSG_X "x" #define MSG_Y "y" @@ -1184,6 +1198,8 @@ #define MSG_PID_C " PID-C: " #define MSG_ACC " Acc:" #define MSG_VXY_JERK " Vxy-jerk: " + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX " Vmax " #define MSG_X "x:" #define MSG_Y "y:" @@ -1350,6 +1366,8 @@ #define MSG_PID_C "PID-C" #define MSG_ACC "Kiihtyv" #define MSG_VXY_JERK "Vxy-jerk" + #define MSG_VZ_JERK "Vz-jerk" + #define MSG_VE_JERK "Ve-jerk" #define MSG_VMAX "Vmax " #define MSG_X "x" #define MSG_Y "y" @@ -1465,4 +1483,3 @@ #endif #endif // ifndef LANGUAGE_H - diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 5101e1821..e45c9d7ff 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -478,7 +478,7 @@ void check_axes_activity() tail_fan_speed = 255; } else { fan_kick_end = 0; - } + } #endif//FAN_KICKSTART_TIME analogWrite(FAN_PIN,tail_fan_speed); #endif//!FAN_SOFT_PWM @@ -895,3 +895,11 @@ void allow_cold_extrudes(bool allow) #endif } +// Calculate the steps/s^2 acceleration rates, based on the mm/s^s +void reset_acceleration_rates() +{ + for(int8_t i=0; i < NUM_AXIS; i++) + { + axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i]; + } +} diff --git a/Marlin/planner.h b/Marlin/planner.h index fc0d83c2b..9a904e577 100644 --- a/Marlin/planner.h +++ b/Marlin/planner.h @@ -136,4 +136,6 @@ FORCE_INLINE bool blocks_queued() } void allow_cold_extrudes(bool allow); + +void reset_acceleration_rates(); #endif diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 58c7b60e6..85017750b 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -1128,3 +1128,31 @@ ISR(TIMER0_COMPB_vect) #endif } } + +#ifdef PIDTEMP +// Apply the scale factors to the PID values + + +float scalePID_i(float i) +{ + return i*PID_dT; +} + +float unscalePID_i(float i) +{ + return i/PID_dT; +} + +float scalePID_d(float d) +{ + return d/PID_dT; +} + +float unscalePID_d(float d) +{ + return d*PID_dT; +} + +#endif //PIDTEMP + + diff --git a/Marlin/temperature.h b/Marlin/temperature.h index feffcbd41..7cc62aa52 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -31,8 +31,8 @@ void tp_init(); //initialise the heating void manage_heater(); //it is critical that this is called periodically. -//low leven conversion routines -// do not use this routines and variables outsie of temperature.cpp +// low level conversion routines +// do not use these routines and variables outside of temperature.cpp extern int target_temperature[EXTRUDERS]; extern float current_temperature[EXTRUDERS]; extern int target_temperature_bed; @@ -40,6 +40,11 @@ extern float current_temperature_bed; #ifdef PIDTEMP extern float Kp,Ki,Kd,Kc; + float scalePID_i(float i); + float scalePID_d(float d); + float unscalePID_i(float i); + float unscalePID_d(float d); + #endif #ifdef PIDTEMPBED extern float bedKp,bedKi,bedKd; diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 8a017292b..fe0619fb8 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -31,6 +31,10 @@ char lcd_status_message[LCD_WIDTH+1] = WELCOME_MSG; #endif /** forward declerations **/ + +void copy_and_scalePID_i(); +void copy_and_scalePID_d(); + /* Different menus */ static void lcd_status_screen(); #ifdef ULTIPANEL @@ -63,6 +67,14 @@ static void menu_action_setting_edit_float5(const char* pstr, float* ptr, float static void menu_action_setting_edit_float51(const char* pstr, float* ptr, float minValue, float maxValue); static void menu_action_setting_edit_float52(const char* pstr, float* ptr, float minValue, float maxValue); static void menu_action_setting_edit_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue); +static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_float3(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_float32(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_float5(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_float51(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_float52(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); +static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue, menuFunc_t callbackFunc); #define ENCODER_STEPS_PER_MENU_ITEM 5 @@ -93,6 +105,7 @@ static void menu_action_setting_edit_long5(const char* pstr, unsigned long* ptr, } while(0) #define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0) #define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args ) +#define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args ) #define END_MENU() \ if (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; \ if ((uint8_t)(encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = (encoderPosition / ENCODER_STEPS_PER_MENU_ITEM) - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \ @@ -123,6 +136,10 @@ uint16_t prevEncoderPosition; const char* editLabel; void* editValue; int32_t minEditValue, maxEditValue; +menuFunc_t callbackFunc; + +// placeholders for Ki and Kd edits +float raw_Ki, raw_Kd; /* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependend */ static void lcd_status_screen() @@ -442,6 +459,10 @@ static void lcd_control_menu() static void lcd_control_temperature_menu() { + // set up temp variables - undo the default scaling + raw_Ki = unscalePID_i(Ki); + raw_Kd = unscalePID_d(Kd); + START_MENU(); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15); @@ -463,9 +484,9 @@ static void lcd_control_temperature_menu() #endif #ifdef PIDTEMP MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp, 1, 9990); -//TODO, I and D should have a PID_dT multiplier (Ki = PID_I * PID_dT, Kd = PID_D / PID_dT) - MENU_ITEM_EDIT(float52, MSG_PID_I, &Ki, 1, 9990); - MENU_ITEM_EDIT(float52, MSG_PID_D, &Kd, 1, 9990); + // i is typically a small value so allows values below 1 + MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d); # ifdef PID_ADD_EXTRUSION_RATE MENU_ITEM_EDIT(float3, MSG_PID_C, &Kc, 1, 9990); # endif//PID_ADD_EXTRUSION_RATE @@ -511,16 +532,18 @@ static void lcd_control_motion_menu() MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 500, 99000); MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &max_xy_jerk, 1, 990); + MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &max_z_jerk, 0.1, 990); + MENU_ITEM_EDIT(float3, MSG_VE_JERK, &max_e_jerk, 1, 990); MENU_ITEM_EDIT(float3, MSG_VMAX MSG_X, &max_feedrate[X_AXIS], 1, 999); MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Y, &max_feedrate[Y_AXIS], 1, 999); MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Z, &max_feedrate[Z_AXIS], 1, 999); MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &max_feedrate[E_AXIS], 1, 999); MENU_ITEM_EDIT(float3, MSG_VMIN, &minimumfeedrate, 0, 999); MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &mintravelfeedrate, 0, 999); - MENU_ITEM_EDIT(long5, MSG_AMAX MSG_X, &max_acceleration_units_per_sq_second[X_AXIS], 100, 99000); - MENU_ITEM_EDIT(long5, MSG_AMAX MSG_Y, &max_acceleration_units_per_sq_second[Y_AXIS], 100, 99000); - MENU_ITEM_EDIT(long5, MSG_AMAX MSG_Z, &max_acceleration_units_per_sq_second[Z_AXIS], 100, 99000); - MENU_ITEM_EDIT(long5, MSG_AMAX MSG_E, &max_acceleration_units_per_sq_second[E_AXIS], 100, 99000); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &max_acceleration_units_per_sq_second[X_AXIS], 100, 99000, reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &max_acceleration_units_per_sq_second[Y_AXIS], 100, 99000, reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &max_acceleration_units_per_sq_second[Z_AXIS], 100, 99000, reset_acceleration_rates); + MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &max_acceleration_units_per_sq_second[E_AXIS], 100, 99000, reset_acceleration_rates); MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &retract_acceleration, 100, 99000); MENU_ITEM_EDIT(float52, MSG_XSTEPS, &axis_steps_per_unit[X_AXIS], 5, 9999); MENU_ITEM_EDIT(float52, MSG_YSTEPS, &axis_steps_per_unit[Y_AXIS], 5, 9999); @@ -610,6 +633,23 @@ void lcd_sdcard_menu() encoderPosition = prevEncoderPosition; \ } \ } \ + void menu_edit_callback_ ## _name () \ + { \ + if ((int32_t)encoderPosition < minEditValue) \ + encoderPosition = minEditValue; \ + if ((int32_t)encoderPosition > maxEditValue) \ + encoderPosition = maxEditValue; \ + if (lcdDrawUpdate) \ + lcd_implementation_drawedit(editLabel, _strFunc(((_type)encoderPosition) / scale)); \ + if (LCD_CLICKED) \ + { \ + *((_type*)editValue) = ((_type)encoderPosition) / scale; \ + lcd_quick_feedback(); \ + currentMenu = prevMenu; \ + encoderPosition = prevEncoderPosition; \ + (*callbackFunc)();\ + } \ + } \ static void menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) \ { \ prevMenu = currentMenu; \ @@ -623,6 +663,21 @@ void lcd_sdcard_menu() minEditValue = minValue * scale; \ maxEditValue = maxValue * scale; \ encoderPosition = (*ptr) * scale; \ + }\ + static void menu_action_setting_edit_callback_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue, menuFunc_t callback) \ + { \ + prevMenu = currentMenu; \ + prevEncoderPosition = encoderPosition; \ + \ + lcdDrawUpdate = 2; \ + currentMenu = menu_edit_callback_ ## _name; \ + \ + editLabel = pstr; \ + editValue = ptr; \ + minEditValue = minValue * scale; \ + maxEditValue = maxValue * scale; \ + encoderPosition = (*ptr) * scale; \ + callbackFunc = callback;\ } menu_edit_type(int, int3, itostr3, 1) menu_edit_type(float, float3, ftostr3, 1) @@ -1070,4 +1125,20 @@ char *ftostr52(const float &x) return conv; } +// Callback for after editing PID i value +// grab the pid i value out of the temp variable; scale it; then update the PID driver +void copy_and_scalePID_i() +{ + Ki = scalePID_i(raw_Ki); + updatePID(); +} + +// Callback for after editing PID d value +// grab the pid d value out of the temp variable; scale it; then update the PID driver +void copy_and_scalePID_d() +{ + Kd = scalePID_d(raw_Kd); + updatePID(); +} + #endif //ULTRA_LCD diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h index 1d19b7718..88dea492b 100644 --- a/Marlin/ultralcd_implementation_hitachi_HD44780.h +++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h @@ -376,6 +376,26 @@ static void lcd_implementation_drawmenu_setting_edit_generic_P(uint8_t row, cons #define lcd_implementation_drawmenu_setting_edit_long5(row, pstr, pstr2, data, minValue, maxValue) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) #define lcd_implementation_drawmenu_setting_edit_bool_selected(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) #define lcd_implementation_drawmenu_setting_edit_bool(row, pstr, pstr2, data) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + +//Add version for callback functions +#define lcd_implementation_drawmenu_setting_edit_callback_int3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_int3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', itostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float3(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr3(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float32(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr32(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float52(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr52(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_float51(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr51(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5_selected(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, '>', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_long5(row, pstr, pstr2, data, minValue, maxValue, callback) lcd_implementation_drawmenu_setting_edit_generic(row, pstr, ' ', ftostr5(*(data))) +#define lcd_implementation_drawmenu_setting_edit_callback_bool_selected(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, '>', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) +#define lcd_implementation_drawmenu_setting_edit_callback_bool(row, pstr, pstr2, data, callback) lcd_implementation_drawmenu_setting_edit_generic_P(row, pstr, ' ', (*(data))?PSTR(MSG_ON):PSTR(MSG_OFF)) + + void lcd_implementation_drawedit(const char* pstr, char* value) { lcd.setCursor(1, 1);