From 37c7e8300ff3161f88ac8ad3a15541c45706cdbf Mon Sep 17 00:00:00 2001 From: grob6000 Date: Sat, 10 Jan 2015 14:46:08 +1100 Subject: [PATCH 1/4] 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 8e4a32805b..58335ea0e1 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); - + 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[e] = DEFAULT_Kc; +#endif//PID_ADD_EXTRUSION_RATE + } // 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 #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 0862e1fe03..203f52cb47 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 8bdb7647f8..6d6107a7c4 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 95c3514890..1c7601964b 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); From 3e2af67ce3ebdf148801b48cfbe3614bd2e6eaf1 Mon Sep 17 00:00:00 2001 From: grob6000 Date: Sat, 10 Jan 2015 16:44:28 +1100 Subject: [PATCH 2/4] Fix R-H compatibility * R-H reads incorrect M301 line from EEPROM output if more than one is present. Reverted to original output format, using only E0 value. --- Marlin/ConfigurationStore.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index 58335ea0e1..d0fdde75a2 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -231,18 +231,11 @@ SERIAL_ECHOLNPGM("Scaling factors:"); #ifdef PIDTEMP SERIAL_ECHO_START; SERIAL_ECHOLNPGM("PID settings:"); - 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(""); - } + 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_ECHOLN(""); #endif//PIDTEMP #ifdef FWRETRACT SERIAL_ECHO_START; From 7d32c7f36def22a6241f1a7b4d243000610e25fa Mon Sep 17 00:00:00 2001 From: grob6000 Date: Sun, 11 Jan 2015 01:14:02 +1100 Subject: [PATCH 3/4] Multiple PID parameter edit for ultralcd * Depending on extruder count, will add menu items for ultralcd to edit individual PID parameters for each extruder * Added menu items to each language_xx.h * Builds OK, but recommend testing with typical LCD --- Marlin/language_ca.h | 8 +++++++ Marlin/language_de.h | 8 +++++++ Marlin/language_en.h | 8 +++++++ Marlin/language_es.h | 8 +++++++ Marlin/language_eu.h | 8 +++++++ Marlin/language_fi.h | 8 +++++++ Marlin/language_fr.h | 8 +++++++ Marlin/language_it.h | 8 +++++++ Marlin/language_nl.h | 8 +++++++ Marlin/language_pl.h | 8 +++++++ Marlin/language_pt.h | 8 +++++++ Marlin/language_ru.h | 8 +++++++ Marlin/ultralcd.cpp | 53 ++++++++++++++++++++++++++++++++------------ 13 files changed, 135 insertions(+), 14 deletions(-) diff --git a/Marlin/language_ca.h b/Marlin/language_ca.h index ba5d37127f..db0e8021af 100644 --- a/Marlin/language_ca.h +++ b/Marlin/language_ca.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Accel" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_de.h b/Marlin/language_de.h index e442448af6..a019290dca 100644 --- a/Marlin/language_de.h +++ b/Marlin/language_de.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Acc" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_en.h b/Marlin/language_en.h index 014b42e51e..ecf87fc1d4 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Accel" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_es.h b/Marlin/language_es.h index 064c770604..8f5fb73d34 100644 --- a/Marlin/language_es.h +++ b/Marlin/language_es.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Acel" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_eu.h b/Marlin/language_eu.h index 7e65ca59d1..66962543cf 100644 --- a/Marlin/language_eu.h +++ b/Marlin/language_eu.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Azelerazioa" #define MSG_VXY_JERK "Vxy-astindua" #define MSG_VZ_JERK "Vz-astindua" diff --git a/Marlin/language_fi.h b/Marlin/language_fi.h index 0b1ac9cad9..c04637dc8b 100644 --- a/Marlin/language_fi.h +++ b/Marlin/language_fi.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Kiihtyv" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_fr.h b/Marlin/language_fr.h index 59066b1268..29922c3270 100644 --- a/Marlin/language_fr.h +++ b/Marlin/language_fr.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Accel" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_it.h b/Marlin/language_it.h index cb7dc466ae..d7abee458f 100644 --- a/Marlin/language_it.h +++ b/Marlin/language_it.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Accel." #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_nl.h b/Marlin/language_nl.h index e9dc380605..77e256e589 100644 --- a/Marlin/language_nl.h +++ b/Marlin/language_nl.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Versn" #define MSG_VXY_JERK "Vxy-jerk" #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_pl.h b/Marlin/language_pl.h index 55ec20ee36..8992097286 100644 --- a/Marlin/language_pl.h +++ b/Marlin/language_pl.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I" #define MSG_PID_D "PID-D" #define MSG_PID_C "PID-C" +#define MSG_PID_P1 "PID-P E2" +#define MSG_PID_I1 "PID-I E2" +#define MSG_PID_D1 "PID-D E2" +#define MSG_PID_C1 "PID-C E2" +#define MSG_PID_P2 "PID-P E3" +#define MSG_PID_I2 "PID-I E3" +#define MSG_PID_D2 "PID-D E3" +#define MSG_PID_C2 "PID-C E3" #define MSG_ACC "Przyspieszenie" #define MSG_VXY_JERK "Zryw Vxy" #define MSG_VZ_JERK "Zryw Vz" diff --git a/Marlin/language_pt.h b/Marlin/language_pt.h index 09e346748f..473bed3e96 100644 --- a/Marlin/language_pt.h +++ b/Marlin/language_pt.h @@ -67,6 +67,14 @@ #define MSG_PID_I "PID-I: " #define MSG_PID_D "PID-D: " #define MSG_PID_C "PID-C: " +#define MSG_PID_P1 "PID-P E2: " +#define MSG_PID_I1 "PID-I E2: " +#define MSG_PID_D1 "PID-D E2: " +#define MSG_PID_C1 "PID-C E2: " +#define MSG_PID_P2 "PID-P E3: " +#define MSG_PID_I2 "PID-I E3: " +#define MSG_PID_D2 "PID-D E3: " +#define MSG_PID_C2 "PID-C E3: " #define MSG_ACC "Acc:" #define MSG_VXY_JERK "Vxy-jerk: " #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/language_ru.h b/Marlin/language_ru.h index ec666f186b..87c5b1db73 100644 --- a/Marlin/language_ru.h +++ b/Marlin/language_ru.h @@ -69,6 +69,14 @@ #define MSG_PID_I "PID-I: " #define MSG_PID_D "PID-D: " #define MSG_PID_C "PID-C: " +#define MSG_PID_P1 "PID-P E2: " +#define MSG_PID_I1 "PID-I E2: " +#define MSG_PID_D1 "PID-D E2: " +#define MSG_PID_C1 "PID-C E2: " +#define MSG_PID_P2 "PID-P E3: " +#define MSG_PID_I2 "PID-I E3: " +#define MSG_PID_D2 "PID-D E3: " +#define MSG_PID_C2 "PID-C E3: " #define MSG_ACC "Acc:" #define MSG_VXY_JERK "Vxy-jerk: " #define MSG_VZ_JERK "Vz-jerk" diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index d790266d92..f380d45ccc 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -185,8 +185,9 @@ void* editValue; int32_t minEditValue, maxEditValue; menuFunc_t callbackFunc; -// place-holders for Ki and Kd edits +// place-holders for Ki and Kd edits, and the extruder # being edited float raw_Ki, raw_Kd; +int pid_current_extruder; static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder=0, const bool feedback=true) { if (currentMenu != menu) { @@ -764,12 +765,6 @@ static void lcd_control_menu() static void lcd_control_temperature_menu() { -#ifdef PIDTEMP - // set up temp variables - undo the default scaling - raw_Ki = unscalePID_i(Ki); - raw_Kd = unscalePID_d(Kd); -#endif - START_MENU(); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); #if TEMP_SENSOR_0 != 0 @@ -792,13 +787,43 @@ static void lcd_control_temperature_menu() MENU_ITEM_EDIT(float32, MSG_FACTOR, &autotemp_factor, 0.0, 1.0); #endif #ifdef PIDTEMP - MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp, 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); + // 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); + // 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); + MENU_ITEM_EDIT(float3, MSG_PID_C, &Kc[0], 1, 9990); # endif//PID_ADD_EXTRUSION_RATE +#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); + // 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 + // 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); + // 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 #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); @@ -1705,7 +1730,7 @@ char *ftostr52(const float &x) void copy_and_scalePID_i() { #ifdef PIDTEMP - Ki = scalePID_i(raw_Ki); + Ki[pid_current_extruder] = scalePID_i(raw_Ki); updatePID(); #endif } @@ -1715,7 +1740,7 @@ void copy_and_scalePID_i() void copy_and_scalePID_d() { #ifdef PIDTEMP - Kd = scalePID_d(raw_Kd); + Kd[pid_current_extruder] = scalePID_d(raw_Kd); updatePID(); #endif } From bf2c923db57cf8d41a2d163a8ad691fc51d59635 Mon Sep 17 00:00:00 2001 From: grob6000 Date: Sun, 11 Jan 2015 13:50:17 +1100 Subject: [PATCH 4/4] 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. --- Marlin/Configuration.h | 2 + Marlin/ConfigurationStore.cpp | 38 ++++++++++--------- Marlin/Marlin_main.cpp | 22 ++++++----- Marlin/temperature.cpp | 25 +++++++++---- Marlin/temperature.h | 9 ++++- Marlin/ultralcd.cpp | 70 ++++++++++++++++++----------------- 6 files changed, 96 insertions(+), 70 deletions(-) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index dfc1965e6e..4e0786199d 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -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 diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp index d0fdde75a2..9a64d19f54 100644 --- a/Marlin/ConfigurationStore.cpp +++ b/Marlin/ConfigurationStore.cpp @@ -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(); diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 203f52cb47..38af8cda97 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -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); - SERIAL_PROTOCOL(" e:"); // specify extruder in serial output - SERIAL_PROTOCOL(e); + #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(""); diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index 6d6107a7c4..f6eadaa483 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -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 - float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc); -#endif + #ifdef PID_ADD_EXTRUSION_RATE + float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc); + #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; diff --git a/Marlin/temperature.h b/Marlin/temperature.h index 1c7601964b..287b92b3bb 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -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); diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index db9073e18f..0f7645c873 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -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 - // 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); - // 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 - // 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); - // 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_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 = 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, &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 = 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, &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 }