From 37c7e8300ff3161f88ac8ad3a15541c45706cdbf Mon Sep 17 00:00:00 2001 From: grob6000 Date: Sat, 10 Jan 2015 14:46:08 +1100 Subject: [PATCH] Independent PID parameters for each extruder * Variables Kp, Ki, Kd, Kc now arrays of size EXTRUDERS * M301 gains (optional, default=0) E parameter to define which extruder's settings to modify. Tested, works with Repetier Host's EEPROM config window, albeit only reads/updates settings for E0. * All Kp, Ki, Kd, Kc parameters saved in EEPROM (version now v14), up to 3 extruders supported (same as Marlin in general) --- Marlin/ConfigurationStore.cpp | 192 ++++++++++++++++++++++------------ Marlin/Marlin_main.cpp | 64 ++++++++---- Marlin/temperature.cpp | 27 ++--- Marlin/temperature.h | 2 +- 4 files changed, 184 insertions(+), 101 deletions(-) diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index 8e4a32805..58335ea0e 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -38,7 +38,7 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) // wrong data being written to the variables. // ALSO: always make sure the variables in the Store and retrieve sections are in the same order. -#define EEPROM_VERSION "V13" +#define EEPROM_VERSION "V14" #ifdef EEPROM_SETTINGS void Config_StoreSettings() @@ -63,11 +63,11 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,delta_radius); EEPROM_WRITE_VAR(i,delta_diagonal_rod); EEPROM_WRITE_VAR(i,delta_segments_per_second); - #endif + #endif//DELTA #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; - #endif + #endif//ULTIPANEL EEPROM_WRITE_VAR(i,plaPreheatHotendTemp); EEPROM_WRITE_VAR(i,plaPreheatHPBTemp); EEPROM_WRITE_VAR(i,plaPreheatFanSpeed); @@ -76,37 +76,58 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i,absPreheatFanSpeed); EEPROM_WRITE_VAR(i,zprobe_zoffset); #ifdef PIDTEMP - EEPROM_WRITE_VAR(i,Kp); - EEPROM_WRITE_VAR(i,Ki); - EEPROM_WRITE_VAR(i,Kd); - #else + float dummy = 0.0f; + for (int e = 0; e < 3; e++) + { + if (e < EXTRUDERS) + { + EEPROM_WRITE_VAR(i,Kp[e]); + EEPROM_WRITE_VAR(i,Ki[e]); + EEPROM_WRITE_VAR(i,Kd[e]); + #ifdef PID_ADD_EXTRUSION_RATE + EEPROM_WRITE_VAR(i,Kc[e]); + #else//PID_ADD_EXTRUSION_RATE + dummy = 1.0f; // 1.0 = default kc + EEPROM_WRITE_VAR(dummmy); + #endif//PID_ADD_EXTRUSION_RATE + } + else + { + dummy = 3000.0f; + EEPROM_WRITE_VAR(i, dummy); + dummy = 0.0f; + EEPROM_WRITE_VAR(i,dummy); + EEPROM_WRITE_VAR(i,dummy); + } + } + #else//PIDTEMP float dummy = 3000.0f; EEPROM_WRITE_VAR(i,dummy); dummy = 0.0f; EEPROM_WRITE_VAR(i,dummy); EEPROM_WRITE_VAR(i,dummy); - #endif + #endif//PIDTEMP #ifndef DOGLCD int lcd_contrast = 32; - #endif + #endif//DOGLCD EEPROM_WRITE_VAR(i,lcd_contrast); #ifdef SCARA EEPROM_WRITE_VAR(i,axis_scaling); // Add scaling for SCARA - #endif + #endif//SCARA #ifdef FWRETRACT EEPROM_WRITE_VAR(i,autoretract_enabled); EEPROM_WRITE_VAR(i,retract_length); #if EXTRUDERS > 1 EEPROM_WRITE_VAR(i,retract_length_swap); - #endif + #endif//EXTRUDERS > 1 EEPROM_WRITE_VAR(i,retract_feedrate); EEPROM_WRITE_VAR(i,retract_zlift); EEPROM_WRITE_VAR(i,retract_recover_length); #if EXTRUDERS > 1 EEPROM_WRITE_VAR(i,retract_recover_length_swap); - #endif + #endif//EXTRUDERS > 1 EEPROM_WRITE_VAR(i,retract_recover_feedrate); - #endif + #endif//FWRETRACT // Save filament sizes EEPROM_WRITE_VAR(i, volumetric_enabled); @@ -115,8 +136,8 @@ void Config_StoreSettings() EEPROM_WRITE_VAR(i, filament_size[1]); #if EXTRUDERS > 2 EEPROM_WRITE_VAR(i, filament_size[2]); - #endif - #endif + #endif//EXTRUDERS > 2 + #endif//EXTRUDERS > 1 char ver2[4]=EEPROM_VERSION; i=EEPROM_OFFSET; @@ -149,7 +170,7 @@ SERIAL_ECHOLNPGM("Scaling factors:"); SERIAL_ECHOLN(""); SERIAL_ECHO_START; -#endif +#endif//SCARA SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M203 X", max_feedrate[X_AXIS]); @@ -206,16 +227,23 @@ SERIAL_ECHOLNPGM("Scaling factors:"); SERIAL_ECHOPAIR(" R" ,delta_radius ); SERIAL_ECHOPAIR(" S" ,delta_segments_per_second ); SERIAL_ECHOLN(""); -#endif +#endif//DELTA #ifdef PIDTEMP SERIAL_ECHO_START; SERIAL_ECHOLNPGM("PID settings:"); - SERIAL_ECHO_START; - SERIAL_ECHOPAIR(" M301 P",Kp); - SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki)); - SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd)); - SERIAL_ECHOLN(""); -#endif + for (int e = 0; e < EXTRUDERS; e++) + { + SERIAL_ECHO_START; + SERIAL_ECHOPAIR(" M301 E", (long unsigned int)e); + SERIAL_ECHOPAIR(" P", Kp[e]); + SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki[e])); + SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd[e])); +#ifdef PID_ADD_EXTRUSION_RATE + SERIAL_ECHOPAIR(" C" ,Kc[e]); +#endif//PID_ADD_EXTRUSION_RATE + SERIAL_ECHOLN(""); + } +#endif//PIDTEMP #ifdef FWRETRACT SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Retract: S=Length (mm) F:Speed (mm/m) Z: ZLift (mm)"); @@ -244,7 +272,7 @@ SERIAL_ECHOLNPGM("Scaling factors:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" Swap rec. addl. length (mm): ", retract_recover_length_swap); SERIAL_ECHOLN(""); -#endif +#endif//EXTRUDERS > 1 SERIAL_ECHO_START; if (volumetric_enabled) { SERIAL_ECHOLNPGM("Filament settings:"); @@ -259,14 +287,14 @@ SERIAL_ECHOLNPGM("Scaling factors:"); SERIAL_ECHO_START; SERIAL_ECHOPAIR(" M200 T2 D", filament_size[2]); SERIAL_ECHOLN(""); -#endif -#endif +#endif//EXTRUDERS > 2 +#endif//EXTRUDERS > 1 } else { SERIAL_ECHOLNPGM("Filament settings: Disabled"); } -#endif +#endif//FWRETRACT } -#endif +#endif//DISABLE_M503 #ifdef EEPROM_SETTINGS @@ -301,11 +329,11 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,delta_radius); EEPROM_READ_VAR(i,delta_diagonal_rod); EEPROM_READ_VAR(i,delta_segments_per_second); - #endif + #endif//DELTA #ifndef ULTIPANEL int plaPreheatHotendTemp, plaPreheatHPBTemp, plaPreheatFanSpeed; int absPreheatHotendTemp, absPreheatHPBTemp, absPreheatFanSpeed; - #endif + #endif//ULTIPANEL EEPROM_READ_VAR(i,plaPreheatHotendTemp); EEPROM_READ_VAR(i,plaPreheatHPBTemp); EEPROM_READ_VAR(i,plaPreheatFanSpeed); @@ -313,35 +341,68 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i,absPreheatHPBTemp); EEPROM_READ_VAR(i,absPreheatFanSpeed); EEPROM_READ_VAR(i,zprobe_zoffset); - #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); + #ifdef PIDTEMP + float dummy = 0.0f; + for (int e = 0; e < 3; e++) // 3 = max extruders supported by marlin + { + 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]); +#ifdef PID_ADD_EXTRUSION_RATE + EEPROM_READ_VAR(i,Kc[e]); +#else//PID_ADD_EXTRUSION_RATE + EEPROM_READ_VAR(i,dummy); +#endif//PID_ADD_EXTRUSION_RATE + } + else + { + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + } + } + #else//PIDTEMP + // 4 x 3 = 12 slots for PID parameters + float dummy = 0.0f; + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + EEPROM_READ_VAR(i,dummy); + #endif//PIDTEMP #ifndef DOGLCD int lcd_contrast; - #endif + #endif//DOGLCD EEPROM_READ_VAR(i,lcd_contrast); #ifdef SCARA EEPROM_READ_VAR(i,axis_scaling); - #endif + #endif//SCARA #ifdef FWRETRACT EEPROM_READ_VAR(i,autoretract_enabled); EEPROM_READ_VAR(i,retract_length); #if EXTRUDERS > 1 EEPROM_READ_VAR(i,retract_length_swap); - #endif + #endif//EXTRUDERS > 1 EEPROM_READ_VAR(i,retract_feedrate); EEPROM_READ_VAR(i,retract_zlift); EEPROM_READ_VAR(i,retract_recover_length); #if EXTRUDERS > 1 EEPROM_READ_VAR(i,retract_recover_length_swap); - #endif + #endif//EXTRUDERS > 1 EEPROM_READ_VAR(i,retract_recover_feedrate); - #endif + #endif//FWRETRACT EEPROM_READ_VAR(i, volumetric_enabled); EEPROM_READ_VAR(i, filament_size[0]); @@ -349,8 +410,8 @@ void Config_RetrieveSettings() EEPROM_READ_VAR(i, filament_size[1]); #if EXTRUDERS > 2 EEPROM_READ_VAR(i, filament_size[2]); -#endif -#endif +#endif//EXTRUDERS > 2 +#endif//EXTRUDERS > 1 calculate_volumetric_multipliers(); // Call updatePID (similar to when we have processed M301) updatePID(); @@ -363,9 +424,9 @@ void Config_RetrieveSettings() } #ifdef EEPROM_CHITCHAT Config_PrintSettings(); - #endif + #endif//EEPROM_CHITCHAT } -#endif +#endif//EEPROM_SETTINGS void Config_ResetDefault() { @@ -379,7 +440,7 @@ void Config_ResetDefault() max_acceleration_units_per_sq_second[i]=tmp3[i]; #ifdef SCARA axis_scaling[i]=1; - #endif + #endif//SCARA } // steps per sq second need to be updated to agree with the units per sq second @@ -400,7 +461,7 @@ void Config_ResetDefault() delta_diagonal_rod= DELTA_DIAGONAL_ROD; delta_segments_per_second= DELTA_SEGMENTS_PER_SECOND; recalc_delta_settings(delta_radius, delta_diagonal_rod); -#endif +#endif//DELTA #ifdef ULTIPANEL plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP; plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP; @@ -408,24 +469,25 @@ void Config_ResetDefault() absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP; absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP; absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; -#endif +#endif//ULTIPANEL #ifdef ENABLE_AUTO_BED_LEVELING zprobe_zoffset = -Z_PROBE_OFFSET_FROM_EXTRUDER; -#endif +#endif//ENABLE_AUTO_BED_LEVELING #ifdef DOGLCD lcd_contrast = DEFAULT_LCD_CONTRAST; -#endif +#endif//DOGLCD #ifdef PIDTEMP - Kp = DEFAULT_Kp; - Ki = scalePID_i(DEFAULT_Ki); - Kd = scalePID_d(DEFAULT_Kd); - - // call updatePID (similar to when we have processed M301) - updatePID(); - + for (int e = 0; e < EXTRUDERS; e++) + { + Kp[e] = DEFAULT_Kp; + Ki[e] = scalePID_i(DEFAULT_Ki); + Kd[e] = scalePID_d(DEFAULT_Kd); #ifdef PID_ADD_EXTRUSION_RATE - Kc = DEFAULT_Kc; + Kc[e] = DEFAULT_Kc; #endif//PID_ADD_EXTRUSION_RATE + } + // call updatePID (similar to when we have processed M301) + updatePID(); #endif//PIDTEMP #ifdef FWRETRACT @@ -433,15 +495,15 @@ void Config_ResetDefault() retract_length = RETRACT_LENGTH; #if EXTRUDERS > 1 retract_length_swap = RETRACT_LENGTH_SWAP; -#endif +#endif//EXTRUDERS > 1 retract_feedrate = RETRACT_FEEDRATE; retract_zlift = RETRACT_ZLIFT; retract_recover_length = RETRACT_RECOVER_LENGTH; #if EXTRUDERS > 1 retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP; -#endif +#endif//EXTRUDERS > 1 retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE; -#endif +#endif//FWRETRACT volumetric_enabled = false; filament_size[0] = DEFAULT_NOMINAL_FILAMENT_DIA; @@ -449,11 +511,11 @@ void Config_ResetDefault() filament_size[1] = DEFAULT_NOMINAL_FILAMENT_DIA; #if EXTRUDERS > 2 filament_size[2] = DEFAULT_NOMINAL_FILAMENT_DIA; -#endif -#endif +#endif//EXTRUDERS > 2 +#endif//EXTRUDERS > 1 calculate_volumetric_multipliers(); SERIAL_ECHO_START; SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded"); -} +} \ No newline at end of file diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 0862e1fe0..203f52cb4 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -3196,30 +3196,50 @@ Sigma_Exit: #endif // M300 #ifdef PIDTEMP - case 301: // M301 - { - if(code_seen('P')) Kp = code_value(); - if(code_seen('I')) Ki = scalePID_i(code_value()); - if(code_seen('D')) Kd = scalePID_d(code_value()); + case 301: // M301 + { - #ifdef PID_ADD_EXTRUSION_RATE - if(code_seen('C')) Kc = code_value(); - #endif + // multi-extruder PID patch: M301 updates or prints a single extruder's PID values + // default behaviour (omitting E parameter) is to update for extruder 0 only + int e = 0; // extruder being updated + if (code_seen('E')) + { + e = (int)code_value(); + } + 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()); + #ifdef PID_ADD_EXTRUSION_RATE + if (code_seen('C')) Kc[e] = code_value(); + #endif + + updatePID(); + SERIAL_PROTOCOL(MSG_OK); + SERIAL_PROTOCOL(" e:"); // specify extruder in serial output + SERIAL_PROTOCOL(e); + SERIAL_PROTOCOL(" p:"); + SERIAL_PROTOCOL(Kp[e]); + SERIAL_PROTOCOL(" i:"); + SERIAL_PROTOCOL(unscalePID_i(Ki[e])); + SERIAL_PROTOCOL(" d:"); + SERIAL_PROTOCOL(unscalePID_d(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]); + #endif + SERIAL_PROTOCOLLN(""); + + } + else + { + SERIAL_ECHO_START; + SERIAL_ECHOLN(MSG_INVALID_EXTRUDER); + } - updatePID(); - SERIAL_PROTOCOL(MSG_OK); - SERIAL_PROTOCOL(" p:"); - SERIAL_PROTOCOL(Kp); - SERIAL_PROTOCOL(" i:"); - SERIAL_PROTOCOL(unscalePID_i(Ki)); - SERIAL_PROTOCOL(" d:"); - SERIAL_PROTOCOL(unscalePID_d(Kd)); - #ifdef PID_ADD_EXTRUSION_RATE - SERIAL_PROTOCOL(" c:"); - //Kc does not have scaling applied above, or in resetting defaults - SERIAL_PROTOCOL(Kc); - #endif - SERIAL_PROTOCOLLN(""); } break; #endif //PIDTEMP diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 8bdb7647f..6d6107a7c 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -50,14 +50,6 @@ float current_temperature_bed = 0.0; int redundant_temperature_raw = 0; float redundant_temperature = 0.0; #endif -#ifdef PIDTEMP - 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 -#endif //PIDTEMP #ifdef PIDTEMPBED float bedKp=DEFAULT_bedKp; @@ -133,6 +125,15 @@ static volatile bool temp_meas_ready = false; # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 } #endif +#ifdef PIDTEMP + 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 + float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc); +#endif +#endif //PIDTEMP + // Init min and max temp with extreme values to prevent false errors during startup static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP ); static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP ); @@ -342,7 +343,7 @@ void updatePID() { #ifdef PIDTEMP for(int e = 0; e < EXTRUDERS; e++) { - temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki; + temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e]; } #endif #ifdef PIDTEMPBED @@ -463,14 +464,14 @@ void manage_heater() temp_iState[e] = 0.0; pid_reset[e] = false; } - pTerm[e] = Kp * pid_error[e]; + pTerm[e] = 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 * temp_iState[e]; + iTerm[e] = Ki[e] * temp_iState[e]; //K1 defined in Configuration.h in the PID settings #define K2 (1.0-K1) - dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]); + dTerm[e] = (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 @@ -810,7 +811,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; + temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e]; #endif //PIDTEMP #ifdef PIDTEMPBED temp_iState_min_bed = 0.0; diff --git a/Marlin/temperature.h b/Marlin/temperature.h index 95c351489..1c7601964 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -58,7 +58,7 @@ extern float current_temperature_bed; #endif #ifdef PIDTEMP - extern float Kp,Ki,Kd,Kc; + extern float Kp[EXTRUDERS], Ki[EXTRUDERS], Kd[EXTRUDERS], Kc[EXTRUDERS]; float scalePID_i(float i); float scalePID_d(float d); float unscalePID_i(float i);