Make multiple PID parameters a config option
* Adds config parameter `PID_PARAMS_PER_EXTRUDER` - allows single PID parameters to be used where this would be preferable (e.g. dual identical extruders) * When disabled, will use `float Kp, Ki, Kd, Kc;` as before. Preprocessor macros used to switch between. * ultralcd.cpp defines extra menus for extra parameters only where required * M301 reports `e:xx` only if independent pid parameters enabled * EEPROM structure still leaves space for 3 extruders worth, when undef will save single parameter to all extruder positions, but only read the first * Switching off saves approx 330 B with no LCD enabled, 2634B with LCD (RRD) enabled: this is significant. * LCD modifications should be tested.
This commit is contained in:
parent
0877aa0fe0
commit
bf2c923db5
6 changed files with 96 additions and 70 deletions
|
@ -152,6 +152,8 @@
|
|||
//#define PID_DEBUG // Sends debug data to the serial port.
|
||||
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
||||
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
||||
//#define PID_PARAMS_PER_EXTRUDER // Uses separate PID parameters for each extruder (useful for mismatched extruders)
|
||||
// Set/get with gcode: M301 E[extruder number, 0-2]
|
||||
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
||||
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
|
||||
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
|
||||
|
|
|
@ -81,11 +81,11 @@ void Config_StoreSettings()
|
|||
{
|
||||
if (e < EXTRUDERS)
|
||||
{
|
||||
EEPROM_WRITE_VAR(i,Kp[e]);
|
||||
EEPROM_WRITE_VAR(i,Ki[e]);
|
||||
EEPROM_WRITE_VAR(i,Kd[e]);
|
||||
EEPROM_WRITE_VAR(i,PID_PARAM(Kp,e));
|
||||
EEPROM_WRITE_VAR(i,PID_PARAM(Ki,e));
|
||||
EEPROM_WRITE_VAR(i,PID_PARAM(Kd,e));
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
EEPROM_WRITE_VAR(i,Kc[e]);
|
||||
EEPROM_WRITE_VAR(i,PID_PARAM(Kc,e));
|
||||
#else//PID_ADD_EXTRUSION_RATE
|
||||
dummy = 1.0f; // 1.0 = default kc
|
||||
EEPROM_WRITE_VAR(dummmy);
|
||||
|
@ -232,9 +232,9 @@ SERIAL_ECHOLNPGM("Scaling factors:");
|
|||
SERIAL_ECHO_START;
|
||||
SERIAL_ECHOLNPGM("PID settings:");
|
||||
SERIAL_ECHO_START;
|
||||
SERIAL_ECHOPAIR(" M301 P", Kp[0]); // for compatibility with hosts, only echos values for E0
|
||||
SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki[0]));
|
||||
SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd[0]));
|
||||
SERIAL_ECHOPAIR(" M301 P", PID_PARAM(Kp,0)); // for compatibility with hosts, only echos values for E0
|
||||
SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0)));
|
||||
SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0)));
|
||||
SERIAL_ECHOLN("");
|
||||
#endif//PIDTEMP
|
||||
#ifdef FWRETRACT
|
||||
|
@ -341,11 +341,11 @@ void Config_RetrieveSettings()
|
|||
if (e < EXTRUDERS)
|
||||
{
|
||||
// do not need to scale PID values as the values in EEPROM are already scaled
|
||||
EEPROM_READ_VAR(i,Kp[e]);
|
||||
EEPROM_READ_VAR(i,Ki[e]);
|
||||
EEPROM_READ_VAR(i,Kd[e]);
|
||||
EEPROM_READ_VAR(i,PID_PARAM(Kp,e));
|
||||
EEPROM_READ_VAR(i,PID_PARAM(Ki,e));
|
||||
EEPROM_READ_VAR(i,PID_PARAM(Kd,e));
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
EEPROM_READ_VAR(i,Kc[e]);
|
||||
EEPROM_READ_VAR(i,PID_PARAM(Kc,e));
|
||||
#else//PID_ADD_EXTRUSION_RATE
|
||||
EEPROM_READ_VAR(i,dummy);
|
||||
#endif//PID_ADD_EXTRUSION_RATE
|
||||
|
@ -470,14 +470,18 @@ void Config_ResetDefault()
|
|||
lcd_contrast = DEFAULT_LCD_CONTRAST;
|
||||
#endif//DOGLCD
|
||||
#ifdef PIDTEMP
|
||||
#ifdef PID_PARAMS_PER_EXTRUDER
|
||||
for (int e = 0; e < EXTRUDERS; e++)
|
||||
#else // PID_PARAMS_PER_EXTRUDER
|
||||
int e = 0; // only need to write once
|
||||
#endif // PID_PARAMS_PER_EXTRUDER
|
||||
{
|
||||
Kp[e] = DEFAULT_Kp;
|
||||
Ki[e] = scalePID_i(DEFAULT_Ki);
|
||||
Kd[e] = scalePID_d(DEFAULT_Kd);
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
Kc[e] = DEFAULT_Kc;
|
||||
#endif//PID_ADD_EXTRUSION_RATE
|
||||
PID_PARAM(Kp,e) = DEFAULT_Kp;
|
||||
PID_PARAM(Ki,e) = scalePID_i(DEFAULT_Ki);
|
||||
PID_PARAM(Kd,e) = scalePID_d(DEFAULT_Kd);
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
PID_PARAM(Kc,e) = DEFAULT_Kc;
|
||||
#endif//PID_ADD_EXTRUSION_RATE
|
||||
}
|
||||
// call updatePID (similar to when we have processed M301)
|
||||
updatePID();
|
||||
|
|
|
@ -3209,27 +3209,29 @@ Sigma_Exit:
|
|||
if (e < EXTRUDERS) // catch bad input value
|
||||
{
|
||||
|
||||
if (code_seen('P')) Kp[e] = code_value();
|
||||
if (code_seen('I')) Ki[e] = scalePID_i(code_value());
|
||||
if (code_seen('D')) Kd[e] = scalePID_d(code_value());
|
||||
if (code_seen('P')) PID_PARAM(Kp,e) = code_value();
|
||||
if (code_seen('I')) PID_PARAM(Ki,e) = scalePID_i(code_value());
|
||||
if (code_seen('D')) PID_PARAM(Kd,e) = scalePID_d(code_value());
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
if (code_seen('C')) Kc[e] = code_value();
|
||||
if (code_seen('C')) PID_PARAM(Kc,e) = code_value();
|
||||
#endif
|
||||
|
||||
updatePID();
|
||||
SERIAL_PROTOCOL(MSG_OK);
|
||||
#ifdef PID_PARAMS_PER_EXTRUDER
|
||||
SERIAL_PROTOCOL(" e:"); // specify extruder in serial output
|
||||
SERIAL_PROTOCOL(e);
|
||||
#endif // PID_PARAMS_PER_EXTRUDER
|
||||
SERIAL_PROTOCOL(" p:");
|
||||
SERIAL_PROTOCOL(Kp[e]);
|
||||
SERIAL_PROTOCOL(PID_PARAM(Kp,e));
|
||||
SERIAL_PROTOCOL(" i:");
|
||||
SERIAL_PROTOCOL(unscalePID_i(Ki[e]));
|
||||
SERIAL_PROTOCOL(unscalePID_i(PID_PARAM(Ki,e)));
|
||||
SERIAL_PROTOCOL(" d:");
|
||||
SERIAL_PROTOCOL(unscalePID_d(Kd[e]));
|
||||
SERIAL_PROTOCOL(unscalePID_d(PID_PARAM(Kd,e)));
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
SERIAL_PROTOCOL(" c:");
|
||||
//Kc does not have scaling applied above, or in resetting defaults
|
||||
SERIAL_PROTOCOL(Kc[e]);
|
||||
SERIAL_PROTOCOL(PID_PARAM(Kc,e));
|
||||
#endif
|
||||
SERIAL_PROTOCOLLN("");
|
||||
|
||||
|
|
|
@ -126,12 +126,21 @@ static volatile bool temp_meas_ready = false;
|
|||
#endif
|
||||
|
||||
#ifdef PIDTEMP
|
||||
#ifdef PID_PARAMS_PER_EXTRUDER
|
||||
float Kp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp);
|
||||
float Ki[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT);
|
||||
float Kd[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT);
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc);
|
||||
#endif
|
||||
#endif // PID_ADD_EXTRUSION_RATE
|
||||
#else //PID_PARAMS_PER_EXTRUDER
|
||||
float Kp = DEFAULT_Kp;
|
||||
float Ki = DEFAULT_Ki * PID_dT;
|
||||
float Kd = DEFAULT_Kd / PID_dT;
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
float Kc = DEFAULT_Kc;
|
||||
#endif // PID_ADD_EXTRUSION_RATE
|
||||
#endif // PID_PARAMS_PER_EXTRUDER
|
||||
#endif //PIDTEMP
|
||||
|
||||
// Init min and max temp with extreme values to prevent false errors during startup
|
||||
|
@ -343,7 +352,7 @@ void updatePID()
|
|||
{
|
||||
#ifdef PIDTEMP
|
||||
for(int e = 0; e < EXTRUDERS; e++) {
|
||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e];
|
||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
|
||||
}
|
||||
#endif
|
||||
#ifdef PIDTEMPBED
|
||||
|
@ -464,14 +473,14 @@ void manage_heater()
|
|||
temp_iState[e] = 0.0;
|
||||
pid_reset[e] = false;
|
||||
}
|
||||
pTerm[e] = Kp[e] * pid_error[e];
|
||||
pTerm[e] = PID_PARAM(Kp,e) * pid_error[e];
|
||||
temp_iState[e] += pid_error[e];
|
||||
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
||||
iTerm[e] = Ki[e] * temp_iState[e];
|
||||
iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
|
||||
|
||||
//K1 defined in Configuration.h in the PID settings
|
||||
#define K2 (1.0-K1)
|
||||
dTerm[e] = (Kd[e] * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
|
||||
dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
|
||||
pid_output = pTerm[e] + iTerm[e] - dTerm[e];
|
||||
if (pid_output > PID_MAX) {
|
||||
if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
||||
|
@ -811,7 +820,7 @@ void tp_init()
|
|||
maxttemp[e] = maxttemp[0];
|
||||
#ifdef PIDTEMP
|
||||
temp_iState_min[e] = 0.0;
|
||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e];
|
||||
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
|
||||
#endif //PIDTEMP
|
||||
#ifdef PIDTEMPBED
|
||||
temp_iState_min_bed = 0.0;
|
||||
|
|
|
@ -58,7 +58,14 @@ extern float current_temperature_bed;
|
|||
#endif
|
||||
|
||||
#ifdef PIDTEMP
|
||||
extern float Kp[EXTRUDERS], Ki[EXTRUDERS], Kd[EXTRUDERS], Kc[EXTRUDERS];
|
||||
|
||||
#ifdef PID_PARAMS_PER_EXTRUDER
|
||||
extern float Kp[EXTRUDERS], Ki[EXTRUDERS], Kd[EXTRUDERS], Kc[EXTRUDERS]; // one param per extruder
|
||||
#define PID_PARAM(param,e) param[e] // use macro to point to array value
|
||||
#else
|
||||
extern float Kp, Ki, Kd, Kc; // one param per extruder - saves 20 or 36 bytes of ram (inc array pointer)
|
||||
#define PID_PARAM(param, e) param // use macro to point directly to value
|
||||
#endif // PID_PARAMS_PER_EXTRUDER
|
||||
float scalePID_i(float i);
|
||||
float scalePID_d(float d);
|
||||
float unscalePID_i(float i);
|
||||
|
|
|
@ -790,41 +790,43 @@ static void lcd_control_temperature_menu()
|
|||
#ifdef PIDTEMP
|
||||
// set up temp variables - undo the default scaling
|
||||
pid_current_extruder = 0;
|
||||
raw_Ki = unscalePID_i(Ki[0]);
|
||||
raw_Kd = unscalePID_d(Kd[0]);
|
||||
MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp[0], 1, 9990);
|
||||
raw_Ki = unscalePID_i(PID_PARAM(Ki,0));
|
||||
raw_Kd = unscalePID_d(PID_PARAM(Kd,0));
|
||||
MENU_ITEM_EDIT(float52, MSG_PID_P, &PID_PARAM(Kp,0), 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[0], 1, 9990);
|
||||
# endif//PID_ADD_EXTRUSION_RATE
|
||||
#if EXTRUDERS > 1
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
MENU_ITEM_EDIT(float3, MSG_PID_C, &PID_PARAM(Kc,0), 1, 9990);
|
||||
#endif//PID_ADD_EXTRUSION_RATE
|
||||
#ifdef PID_PARAMS_PER_EXTRUDER
|
||||
#if EXTRUDERS > 1
|
||||
// set up temp variables - undo the default scaling
|
||||
pid_current_extruder = 1;
|
||||
raw_Ki = unscalePID_i(Ki[1]);
|
||||
raw_Kd = unscalePID_d(Kd[1]);
|
||||
MENU_ITEM_EDIT(float52, MSG_PID_P1, &Kp[1], 1, 9990);
|
||||
pid_current_extruder = 0;
|
||||
raw_Ki = unscalePID_i(PID_PARAM(Ki,1));
|
||||
raw_Kd = unscalePID_d(PID_PARAM(Kd,1));
|
||||
MENU_ITEM_EDIT(float52, MSG_PID_P1, &PID_PARAM(Kp,1), 1, 9990);
|
||||
// i is typically a small value so allows values below 1
|
||||
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I1, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
|
||||
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D1, &raw_Kd, 1, 9990, copy_and_scalePID_d);
|
||||
# ifdef PID_ADD_EXTRUSION_RATE
|
||||
MENU_ITEM_EDIT(float3, MSG_PID_C1, &Kc[1], 1, 9990);
|
||||
# endif//PID_ADD_EXTRUSION_RATE
|
||||
#endif//EXTRUDERS > 1
|
||||
#if EXTRUDERS > 2
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
MENU_ITEM_EDIT(float3, MSG_PID_C1, &PID_PARAM(Kc,1), 1, 9990);
|
||||
#endif//PID_ADD_EXTRUSION_RATE
|
||||
#endif//EXTRUDERS > 1
|
||||
#if EXTRUDERS > 2
|
||||
// set up temp variables - undo the default scaling
|
||||
pid_current_extruder = 2;
|
||||
raw_Ki = unscalePID_i(Ki[2]);
|
||||
raw_Kd = unscalePID_d(Kd[2]);
|
||||
MENU_ITEM_EDIT(float52, MSG_PID_P2, &Kp[2], 1, 9990);
|
||||
pid_current_extruder = 0;
|
||||
raw_Ki = unscalePID_i(PID_PARAM(Ki,2));
|
||||
raw_Kd = unscalePID_d(PID_PARAM(Kd,2));
|
||||
MENU_ITEM_EDIT(float52, MSG_PID_P2, &PID_PARAM(Kp,2), 1, 9990);
|
||||
// i is typically a small value so allows values below 1
|
||||
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I2, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
|
||||
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D2, &raw_Kd, 1, 9990, copy_and_scalePID_d);
|
||||
# ifdef PID_ADD_EXTRUSION_RATE
|
||||
MENU_ITEM_EDIT(float3, MSG_PID_C2, &Kc[2], 1, 9990);
|
||||
# endif//PID_ADD_EXTRUSION_RATE
|
||||
#endif//EXTRUDERS > 2
|
||||
#ifdef PID_ADD_EXTRUSION_RATE
|
||||
MENU_ITEM_EDIT(float3, MSG_PID_C2, &PID_PARAM(Kc,2), 1, 9990);
|
||||
#endif//PID_ADD_EXTRUSION_RATE
|
||||
#endif//EXTRUDERS > 2
|
||||
#endif // PID_PARAMS_PER_EXTRUDER
|
||||
#endif//PIDTEMP
|
||||
MENU_ITEM(submenu, MSG_PREHEAT_PLA_SETTINGS, lcd_control_temperature_preheat_pla_settings_menu);
|
||||
MENU_ITEM(submenu, MSG_PREHEAT_ABS_SETTINGS, lcd_control_temperature_preheat_abs_settings_menu);
|
||||
|
@ -1731,7 +1733,7 @@ char *ftostr52(const float &x)
|
|||
void copy_and_scalePID_i()
|
||||
{
|
||||
#ifdef PIDTEMP
|
||||
Ki[pid_current_extruder] = scalePID_i(raw_Ki);
|
||||
PID_PARAM(Ki, pid_current_extruder) = scalePID_i(raw_Ki);
|
||||
updatePID();
|
||||
#endif
|
||||
}
|
||||
|
@ -1741,7 +1743,7 @@ void copy_and_scalePID_i()
|
|||
void copy_and_scalePID_d()
|
||||
{
|
||||
#ifdef PIDTEMP
|
||||
Kd[pid_current_extruder] = scalePID_d(raw_Kd);
|
||||
PID_PARAM(Kd, pid_current_extruder) = scalePID_d(raw_Kd);
|
||||
updatePID();
|
||||
#endif
|
||||
}
|
||||
|
|
Reference in a new issue