From 537cd9fa33f7585c46ab27bc4de3301628419b60 Mon Sep 17 00:00:00 2001 From: Aron List Date: Sun, 21 Apr 2024 03:18:49 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20PID=20upon=20entering=20PI?= =?UTF-8?q?D=5FFUNCTIONAL=5FRANGE=20(#26926)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PID algorithm did not cache the last seen temperature until it entered the PID_FUNCTIONAL_RANGE. This caused an incorrect output power to be calculated temporarily while the algorithm caught up. This has likely always been a problem for bed and chamber PID. For the hotend this error was introduced in refactoring in commit 54e7b933cdb6d0bf0d69fd661b585100d76e3c88. --- Marlin/src/module/temperature.h | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 088a17ec1b99..16d4a38e0811 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -204,31 +204,35 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t; float get_pid_output(const float target, const float current) { const float pid_error = target - current; + float output_pow; if (!target || pid_error < -(PID_FUNCTIONAL_RANGE)) { pid_reset = true; - return 0; + output_pow = 0; } else if (pid_error > PID_FUNCTIONAL_RANGE) { pid_reset = true; - return MAX_POW; + output_pow = MAX_POW; } + else { + if (pid_reset) { + pid_reset = false; + temp_iState = 0.0; + work_d = 0.0; + } - if (pid_reset) { - pid_reset = false; - temp_iState = 0.0; - work_d = 0.0; - } + const float max_power_over_i_gain = float(MAX_POW) / Ki - float(MIN_POW); + temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain); - const float max_power_over_i_gain = float(MAX_POW) / Ki - float(MIN_POW); - temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain); + work_p = Kp * pid_error; + work_i = Ki * temp_iState; + work_d = work_d + PID_K2 * (Kd * (temp_dState - current) - work_d); - work_p = Kp * pid_error; - work_i = Ki * temp_iState; - work_d = work_d + PID_K2 * (Kd * (temp_dState - current) - work_d); + output_pow = constrain(work_p + work_i + work_d + float(MIN_POW), 0, MAX_POW); + } temp_dState = current; - return constrain(work_p + work_i + work_d + float(MIN_POW), 0, MAX_POW); + return output_pow; } };