@@ -884,41 +884,51 @@ void Temperature::factory_reset() {
884884 ONHEATING (start_temp, current_temp, target);
885885 #endif
886886
887- if (heating && current_temp > target && ELAPSED (ms, t2, 5000UL )) {
887+ // Logic for dynamic delay: fast response for hotends (3s), slower for beds/chambers (5s)
888+ const millis_t relay_delay = (isbed || ischamber) ? 5000UL : 3000UL ;
889+
890+ if (heating && current_temp > target && ELAPSED (ms, t2, relay_delay)) {
888891 heating = false ;
889892 SET_CBH (soft_pwm_amount, (bias - d) >> 1 );
890893 t1 = ms;
891894 t_high = t1 - t2;
892895 maxT = target;
893896 }
894897
895- if (!heating && current_temp < target && ELAPSED (ms, t1, 5000UL )) {
898+ if (!heating && current_temp < target && ELAPSED (ms, t1, relay_delay )) {
896899 heating = true ;
897900 t2 = ms;
898901 t_low = t2 - t1;
899902 if (cycles > 0 ) {
900903 const long max_pow = PER_CBH (MAX_CHAMBER_POWER, MAX_BED_POWER, PID_MAX);
901- bias += (d * (t_high - t_low)) / (t_low + t_high);
904+
905+ const float delta_t = t_high - t_low,
906+ total_t = t_high + t_low;
907+
908+ if (total_t ) bias += LROUND (float (d) * delta_t / total_t );
902909 LIMIT (bias, 20 , max_pow - 20 );
903910 d = (bias > max_pow >> 1 ) ? max_pow - 1 - bias : bias;
904911
905912 SERIAL_ECHOPGM (STR_BIAS, bias, STR_D_COLON, d, STR_T_MIN, minT, STR_T_MAX, maxT);
906913 if (cycles > 2 ) {
907- const float Ku = (4 .0f * d) / (float (M_PI) * (maxT - minT) * 0 .5f ),
908- Tu = float (t_low + t_high) * 0 .001f ,
909- pf = (ischamber || isbed) ? 0 .2f : 0 .6f ,
910- df = (ischamber || isbed) ? 1 .0f / 3 .0f : 1 .0f / 8 .0f ;
911-
912- tune_pid.p = Ku * pf;
913- tune_pid.i = tune_pid.p * 2 .0f / Tu;
914- tune_pid.d = tune_pid.p * Tu * df;
915-
916- SERIAL_ECHOLNPGM (STR_KU, Ku, STR_TU, Tu);
917- if (ischamber || isbed)
918- SERIAL_ECHOLNPGM (" No overshoot" );
919- else
920- SERIAL_ECHOLNPGM (STR_CLASSIC_PID);
921- SERIAL_ECHOLNPGM (STR_KP, tune_pid.p , STR_KI, tune_pid.i , STR_KD, tune_pid.d );
914+ const float diff = maxT - minT;
915+ if (diff > 0 .001f ) { // Division-by-zero guard
916+ const float Ku = (4 .0f * d) / (float (M_PI) * diff * 0 .5f ),
917+ Tu = total_t * 0 .001f ,
918+ pf = (ischamber || isbed) ? 0 .2f : 0 .6f ,
919+ df = (ischamber || isbed) ? 1 .0f / 3 .0f : 1 .0f / 8 .0f ;
920+
921+ tune_pid.p = Ku * pf;
922+ tune_pid.i = tune_pid.p * 2 .0f / Tu;
923+ tune_pid.d = tune_pid.p * Tu * df;
924+
925+ SERIAL_ECHOLNPGM (STR_KU, Ku, STR_TU, Tu);
926+ if (ischamber || isbed)
927+ SERIAL_ECHOLNPGM (" No overshoot" );
928+ else
929+ SERIAL_ECHOLNPGM (STR_CLASSIC_PID);
930+ SERIAL_ECHOLNPGM (STR_KP, tune_pid.p , STR_KI, tune_pid.i , STR_KD, tune_pid.d );
931+ }
922932 }
923933 }
924934 SET_CBH (soft_pwm_amount, (bias + d) >> 1 );
0 commit comments