diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 58d0955290..50be513edb 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -41,7 +41,8 @@ // if Kc is chosen well, the additional required power due to increased melting should be compensated. #define PID_ADD_EXTRUSION_RATE #if ENABLED(PID_ADD_EXTRUSION_RATE) - #define DEFAULT_Kc (1) //heating power=Kc*(e_speed) + #define DEFAULT_Kc (100) //heating power=Kc*(e_speed) + #define LPQ_MAX_LEN 50 #endif #endif diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 1acc4596d1..7c244dcc2e 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -329,6 +329,10 @@ extern int fanSpeed; extern int meas_delay_cm; //delay distance #endif +#if ENABLED(PID_ADD_EXTRUSION_RATE) + extern int lpq_len; +#endif + #if ENABLED(FWRETRACT) extern bool autoretract_enabled; extern bool retracted[EXTRUDERS]; // extruder[n].retracted diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 525a611634..bce975c34b 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -420,6 +420,10 @@ bool target_direction; boolean chdkActive = false; #endif +#if ENABLED(PID_ADD_EXTRUSION_RATE) + int lpq_len = 20; +#endif + //=========================================================================== //================================ Functions ================================ //=========================================================================== @@ -4770,7 +4774,16 @@ inline void gcode_M226() { #if ENABLED(PIDTEMP) /** - * M301: Set PID parameters P I D (and optionally C) + * M301: Set PID parameters P I D (and optionally C, L) + * + * P[float] Kp term + * I[float] Ki term (unscaled) + * D[float] Kd term (unscaled) + * + * With PID_ADD_EXTRUSION_RATE: + * + * C[float] Kc term + * L[float] LPQ length */ inline void gcode_M301() { @@ -4784,6 +4797,8 @@ inline void gcode_M226() { if (code_seen('D')) PID_PARAM(Kd, e) = scalePID_d(code_value()); #if ENABLED(PID_ADD_EXTRUSION_RATE) if (code_seen('C')) PID_PARAM(Kc, e) = code_value(); + if (code_seen('L')) lpq_len = code_value(); + NOMORE(lpq_len, LPQ_MAX_LEN); #endif updatePID(); diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index edb2d97a2d..ffaeb5be1c 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -14,7 +14,7 @@ * */ -#define EEPROM_VERSION "V20" +#define EEPROM_VERSION "V21" /** * V19 EEPROM Layout: @@ -60,6 +60,7 @@ * M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] * M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] * M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] + * M301 L lpq_len * * PIDTEMPBED: * M304 PID bedKp, bedKi, bedKd @@ -227,6 +228,11 @@ void Config_StoreSettings() { } // Extruders Loop + #if DISABLED(PID_ADD_EXTRUSION_RATE) + int lpq_len = 20; + #endif + EEPROM_WRITE_VAR(i, lpq_len); + #if DISABLED(PIDTEMPBED) float bedKp = DUMMY_PID_VALUE, bedKi = DUMMY_PID_VALUE, bedKd = DUMMY_PID_VALUE; #endif @@ -393,6 +399,11 @@ void Config_RetrieveSettings() { for (int q=16; q--;) EEPROM_READ_VAR(i, dummy); // 4x Kp, Ki, Kd, Kc #endif // !PIDTEMP + #if DISABLED(PID_ADD_EXTRUSION_RATE) + int lpq_len; + #endif + EEPROM_READ_VAR(i, lpq_len); + #if DISABLED(PIDTEMPBED) float bedKp, bedKi, bedKd; #endif @@ -539,6 +550,9 @@ void Config_ResetDefault() { PID_PARAM(Kc, e) = DEFAULT_Kc; #endif } + #if ENABLED(PID_ADD_EXTRUSION_RATE) + lpq_len = 20; // default last-position-queue size + #endif // call updatePID (similar to when we have processed M301) updatePID(); #endif // PIDTEMP @@ -744,7 +758,8 @@ void Config_PrintSettings(bool forReplay) { SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, i))); #if ENABLED(PID_ADD_EXTRUSION_RATE) SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, i)); - #endif + if (i == 0) SERIAL_ECHOPAIR(" L", lpq_len); + #endif SERIAL_EOL; } } @@ -758,7 +773,8 @@ void Config_PrintSettings(bool forReplay) { SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0))); #if ENABLED(PID_ADD_EXTRUSION_RATE) SERIAL_ECHOPAIR(" C", PID_PARAM(Kc, 0)); - #endif + SERIAL_ECHOPAIR(" L", lpq_len); + #endif SERIAL_EOL; } #endif // PIDTEMP diff --git a/Marlin/language.h b/Marlin/language.h index 1a16a04270..fa72989926 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -200,6 +200,7 @@ #define MSG_PID_DEBUG_PTERM " pTerm " #define MSG_PID_DEBUG_ITERM " iTerm " #define MSG_PID_DEBUG_DTERM " dTerm " +#define MSG_PID_DEBUG_CTERM " cTerm " #define MSG_INVALID_EXTRUDER_NUM " - Invalid extruder number !" #define MSG_HEATER_BED "bed" diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index fa064adccf..9c45d1050b 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -99,6 +99,12 @@ static volatile bool temp_meas_ready = false; static float pTerm[EXTRUDERS]; static float iTerm[EXTRUDERS]; static float dTerm[EXTRUDERS]; + #if ENABLED(PID_ADD_EXTRUSION_RATE) + static float cTerm[EXTRUDERS]; + static long last_position[EXTRUDERS]; + static long lpq[LPQ_MAX_LEN]; + static int lpq_ptr = 0; + #endif //int output; static float pid_error[EXTRUDERS]; static float temp_iState_min[EXTRUDERS]; @@ -357,6 +363,9 @@ void updatePID() { #if ENABLED(PIDTEMP) for (int e = 0; e < EXTRUDERS; e++) { temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e); + #if ENABLED(PID_ADD_EXTRUSION_RATE) + last_position[e] = 0; + #endif } #endif #if ENABLED(PIDTEMPBED) @@ -497,6 +506,23 @@ float get_pid_output(int e) { iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e]; pid_output = pTerm[e] + iTerm[e] - dTerm[e]; + + #if ENABLED(PID_ADD_EXTRUSION_RATE) + cTerm[e] = 0; + if (e == active_extruder) { + long e_position = st_get_position(E_AXIS); + if (e_position > last_position[e]) { + lpq[lpq_ptr++] = e_position - last_position[e]; + last_position[e] = e_position; + } else { + lpq[lpq_ptr++] = 0; + } + if (lpq_ptr >= lpq_len) lpq_ptr = 0; + cTerm[e] = (lpq[lpq_ptr] / axis_steps_per_unit[E_AXIS]) * Kc; + pid_output += cTerm[e]; + } + #endif //PID_ADD_EXTRUSION_RATE + if (pid_output > PID_MAX) { if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration pid_output = PID_MAX; @@ -512,18 +538,16 @@ float get_pid_output(int e) { #if ENABLED(PID_DEBUG) SERIAL_ECHO_START; - SERIAL_ECHO(MSG_PID_DEBUG); - SERIAL_ECHO(e); - SERIAL_ECHO(MSG_PID_DEBUG_INPUT); - SERIAL_ECHO(current_temperature[e]); - SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT); - SERIAL_ECHO(pid_output); - SERIAL_ECHO(MSG_PID_DEBUG_PTERM); - SERIAL_ECHO(pTerm[e]); - SERIAL_ECHO(MSG_PID_DEBUG_ITERM); - SERIAL_ECHO(iTerm[e]); - SERIAL_ECHO(MSG_PID_DEBUG_DTERM); - SERIAL_ECHOLN(dTerm[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG, e); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[e]); + SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[e]); + #if ENABLED(PID_ADD_EXTRUSION_RATE) + SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[e]); + #endif + SERIAL_EOL; #endif //PID_DEBUG #else /* PID off */ @@ -837,6 +861,9 @@ void tp_init() { #if ENABLED(PIDTEMP) temp_iState_min[e] = 0.0; temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e); + #if ENABLED(PID_ADD_EXTRUSION_RATE) + last_position[e] = 0; + #endif #endif //PIDTEMP #if ENABLED(PIDTEMPBED) temp_iState_min_bed = 0.0;