@@ -350,11 +350,13 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
350
350
PID_t tune_pid = { 0 , 0 , 0 };
351
351
float max = 0 , min = 10000 ;
352
352
353
+ const bool isbed = (heater < 0 );
354
+
353
355
#if HAS_PID_FOR_BOTH
354
- #define GHV (B,H ) (heater < 0 ? (B) : (H))
355
- #define SHV (B,H ) do { if (heater < 0 ) temp_bed.soft_pwm_amount = B; else temp_hotend[heater].soft_pwm_amount = H; }while (0 )
356
- #define ONHEATINGSTART () (heater < 0 ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart())
357
- #define ONHEATING (S,C,T ) do { if (heater < 0 ) printerEventLEDs.onBedHeating (S,C,T); else printerEventLEDs.onHotendHeating (S,C,T); } while ( 0 )
356
+ #define GHV (B,H ) (isbed ? (B) : (H))
357
+ #define SHV (B,H ) do { if (isbed ) temp_bed.soft_pwm_amount = B; else temp_hotend[heater].soft_pwm_amount = H; }while (0 )
358
+ #define ONHEATINGSTART () (isbed ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart())
359
+ #define ONHEATING (S,C,T ) (isbed ? printerEventLEDs.onBedHeating(S,C,T) : printerEventLEDs.onHotendHeating(S,C,T))
358
360
#elif ENABLED(PIDTEMPBED)
359
361
#define GHV (B,H ) B
360
362
#define SHV (B,H ) (temp_bed.soft_pwm_amount = B)
@@ -370,7 +372,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
370
372
#if WATCH_BED || WATCH_HOTENDS
371
373
#define HAS_TP_BED BOTH (THERMAL_PROTECTION_BED, PIDTEMPBED)
372
374
#if HAS_TP_BED && BOTH(THERMAL_PROTECTION_HOTENDS, PIDTEMP)
373
- #define GTV (B,H ) (heater < 0 ? (B) : (H))
375
+ #define GTV (B,H ) (isbed ? (B) : (H))
374
376
#elif HAS_TP_BED
375
377
#define GTV (B,H ) (B)
376
378
#else
@@ -456,23 +458,25 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
456
458
457
459
SERIAL_ECHOPAIR (MSG_BIAS, bias, MSG_D, d, MSG_T_MIN, min, MSG_T_MAX, max);
458
460
if (cycles > 2 ) {
459
- float Ku = (4 .0f * d) / (float (M_PI) * (max - min) * 0 .5f ),
460
- Tu = ((float )(t_low + t_high) * 0 .001f );
461
- tune_pid.Kp = 0 .6f * Ku;
461
+ const float Ku = (4 .0f * d) / (float (M_PI) * (max - min) * 0 .5f ),
462
+ Tu = float (t_low + t_high) * 0 .001f ,
463
+ pf = isbed ? 0 .2f : 0 .6f ,
464
+ df = isbed ? 1 .0f / 3 .0f : 1 .0f / 8 .0f ;
465
+ tune_pid.Kp = Ku * pf;
466
+ tune_pid.Kd = tune_pid.Kp * Tu * df;
462
467
tune_pid.Ki = 2 * tune_pid.Kp / Tu;
463
- tune_pid.Kd = tune_pid.Kp * Tu * 0 .125f ;
464
468
SERIAL_ECHOPAIR (MSG_KU, Ku, MSG_TU, Tu);
465
469
SERIAL_ECHOLNPGM (" \n " MSG_CLASSIC_PID);
466
470
SERIAL_ECHOLNPAIR (MSG_KP, tune_pid.Kp , MSG_KI, tune_pid.Ki , MSG_KD, tune_pid.Kd );
467
471
/* *
468
- tune_pid.Kp = 0.33* Ku;
469
- tune_pid.Ki = tune_pid.Kp/ Tu;
470
- tune_pid.Kd = tune_pid.Kp*Tu/ 3;
472
+ tune_pid.Kp = 0.33 * Ku;
473
+ tune_pid.Ki = tune_pid.Kp / Tu;
474
+ tune_pid.Kd = tune_pid.Kp * Tu / 3;
471
475
SERIAL_ECHOLNPGM(" Some overshoot");
472
476
SERIAL_ECHOLNPAIR(" Kp: ", tune_pid.Kp, " Ki: ", tune_pid.Ki, " Kd: ", tune_pid.Kd, " No overshoot");
473
- tune_pid.Kp = 0.2* Ku;
474
- tune_pid.Ki = 2* tune_pid.Kp/ Tu;
475
- tune_pid.Kd = tune_pid.Kp*Tu/ 3;
477
+ tune_pid.Kp = 0.2 * Ku;
478
+ tune_pid.Ki = 2 * tune_pid.Kp / Tu;
479
+ tune_pid.Kd = tune_pid.Kp * Tu / 3;
476
480
SERIAL_ECHOPAIR(" Kp: ", tune_pid.Kp, " Ki: ", tune_pid.Ki, " Kd: ", tune_pid.Kd);
477
481
*/
478
482
}
@@ -496,7 +500,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
496
500
// Report heater states every 2 seconds
497
501
if (ELAPSED (ms, next_temp_ms)) {
498
502
#if HAS_TEMP_SENSOR
499
- print_heater_states (heater >= 0 ? heater : active_extruder );
503
+ print_heater_states (isbed ? active_extruder : heater );
500
504
SERIAL_EOL ();
501
505
#endif
502
506
next_temp_ms = ms + 2000UL ;
@@ -507,9 +511,9 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
507
511
#if WATCH_BED && WATCH_HOTENDS
508
512
true
509
513
#elif WATCH_HOTENDS
510
- heater >= 0
514
+ !isbed
511
515
#else
512
- heater < 0
516
+ isbed
513
517
#endif
514
518
) {
515
519
if (!heated) { // If not yet reached target...
@@ -569,7 +573,7 @@ temp_range_t Temperature::temp_range[HOTENDS] = ARRAY_BY_HOTENDS(sensor_heater_0
569
573
// Use the result? (As with "M303 U1")
570
574
if (set_result) {
571
575
#if HAS_PID_FOR_BOTH
572
- if (heater < 0 ) _SET_BED_PID (); else _SET_EXTRUDER_PID ();
576
+ if (isbed ) _SET_BED_PID (); else _SET_EXTRUDER_PID ();
573
577
#elif ENABLED(PIDTEMP)
574
578
_SET_EXTRUDER_PID ();
575
579
#else
@@ -805,9 +809,7 @@ float Temperature::get_pid_output(const int8_t e) {
805
809
static float temp_iState[HOTENDS] = { 0 },
806
810
temp_dState[HOTENDS] = { 0 };
807
811
static bool pid_reset[HOTENDS] = { false };
808
- float pid_error = temp_hotend[HOTEND_INDEX].target - temp_hotend[HOTEND_INDEX].current ;
809
- work_pid[HOTEND_INDEX].Kd = PID_K2 * PID_PARAM (Kd, HOTEND_INDEX) * (temp_hotend[HOTEND_INDEX].current - temp_dState[HOTEND_INDEX]) + float (PID_K1) * work_pid[HOTEND_INDEX].Kd ;
810
- temp_dState[HOTEND_INDEX] = temp_hotend[HOTEND_INDEX].current ;
812
+ const float pid_error = temp_hotend[HOTEND_INDEX].target - temp_hotend[HOTEND_INDEX].current ;
811
813
812
814
if (temp_hotend[HOTEND_INDEX].target == 0
813
815
|| pid_error < -(PID_FUNCTIONAL_RANGE)
@@ -825,13 +827,17 @@ float Temperature::get_pid_output(const int8_t e) {
825
827
else {
826
828
if (pid_reset[HOTEND_INDEX]) {
827
829
temp_iState[HOTEND_INDEX] = 0.0 ;
830
+ work_pid[HOTEND_INDEX].Kd = 0.0 ;
828
831
pid_reset[HOTEND_INDEX] = false ;
829
832
}
830
- temp_iState[HOTEND_INDEX] += pid_error;
833
+
834
+ work_pid[HOTEND_INDEX].Kd = work_pid[HOTEND_INDEX].Kd + PID_K2 * (PID_PARAM (Kd, HOTEND_INDEX) * (temp_dState[HOTEND_INDEX] - temp_hotend[HOTEND_INDEX].current ) - work_pid[HOTEND_INDEX].Kd );
835
+ const float max_power_over_i_gain = (float )PID_MAX / PID_PARAM (Ki, HOTEND_INDEX);
836
+ temp_iState[HOTEND_INDEX] = constrain (temp_iState[HOTEND_INDEX] + pid_error, 0 , max_power_over_i_gain);
831
837
work_pid[HOTEND_INDEX].Kp = PID_PARAM (Kp, HOTEND_INDEX) * pid_error;
832
838
work_pid[HOTEND_INDEX].Ki = PID_PARAM (Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX];
833
839
834
- pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki - work_pid[HOTEND_INDEX].Kd ;
840
+ pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki + work_pid[HOTEND_INDEX].Kd ;
835
841
836
842
#if ENABLED(PID_EXTRUSION_SCALING)
837
843
work_pid[HOTEND_INDEX].Kc = 0 ;
@@ -850,15 +856,9 @@ float Temperature::get_pid_output(const int8_t e) {
850
856
}
851
857
#endif // PID_EXTRUSION_SCALING
852
858
853
- if (pid_output > PID_MAX) {
854
- if (pid_error > 0 ) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration
855
- pid_output = PID_MAX;
856
- }
857
- else if (pid_output < 0 ) {
858
- if (pid_error < 0 ) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration
859
- pid_output = 0 ;
860
- }
859
+ pid_output = constrain (pid_output, 0 , PID_MAX);
861
860
}
861
+ temp_dState[HOTEND_INDEX] = temp_hotend[HOTEND_INDEX].current ;
862
862
863
863
#else // PID_OPENLOOP
864
864
@@ -908,23 +908,18 @@ float Temperature::get_pid_output(const int8_t e) {
908
908
static PID_t work_pid = { 0 };
909
909
static float temp_iState = 0 , temp_dState = 0 ;
910
910
911
- float pid_error = temp_bed.target - temp_bed.current ;
912
- temp_iState += pid_error;
911
+ const float max_power_over_i_gain = (float )MAX_BED_POWER / temp_bed.pid .Ki ,
912
+ pid_error = temp_bed.target - temp_bed.current ;
913
+
914
+ temp_iState = constrain (temp_iState + pid_error, 0 , max_power_over_i_gain);
915
+
913
916
work_pid.Kp = temp_bed.pid .Kp * pid_error;
914
917
work_pid.Ki = temp_bed.pid .Ki * temp_iState;
915
- work_pid.Kd = PID_K2 * temp_bed.pid .Kd * (temp_bed.current - temp_dState) + PID_K1 * work_pid.Kd ;
918
+ work_pid.Kd = work_pid. Kd + PID_K2 * ( temp_bed.pid .Kd * (temp_dState - temp_bed.current ) - work_pid.Kd ) ;
916
919
917
920
temp_dState = temp_bed.current ;
918
921
919
- float pid_output = work_pid.Kp + work_pid.Ki - work_pid.Kd ;
920
- if (pid_output > MAX_BED_POWER) {
921
- if (pid_error > 0 ) temp_iState -= pid_error; // conditional un-integration
922
- pid_output = MAX_BED_POWER;
923
- }
924
- else if (pid_output < 0 ) {
925
- if (pid_error < 0 ) temp_iState -= pid_error; // conditional un-integration
926
- pid_output = 0 ;
927
- }
922
+ const float pid_output = constrain (work_pid.Kp + work_pid.Ki + work_pid.Kd , 0 , MAX_BED_POWER);
928
923
929
924
#else // PID_OPENLOOP
930
925
0 commit comments