|
@@ -75,6 +75,10 @@
|
75
|
75
|
//============================= public variables ============================
|
76
|
76
|
//===========================================================================
|
77
|
77
|
|
|
78
|
+#ifdef K1 // Defined in Configuration.h in the PID settings
|
|
79
|
+ #define K2 (1.0-K1)
|
|
80
|
+#endif
|
|
81
|
+
|
78
|
82
|
// Sampling period of the temperature routine
|
79
|
83
|
#ifdef PID_dT
|
80
|
84
|
#undef PID_dT
|
|
@@ -546,12 +550,102 @@ void bed_max_temp_error(void) {
|
546
|
550
|
_temp_error(-1, MSG_MAXTEMP_BED_OFF, MSG_ERR_MAXTEMP_BED);
|
547
|
551
|
}
|
548
|
552
|
|
|
553
|
+float get_pid_output(int e) {
|
|
554
|
+ float pid_output;
|
|
555
|
+ #ifdef PIDTEMP
|
|
556
|
+ #ifndef PID_OPENLOOP
|
|
557
|
+ pid_error[e] = target_temperature[e] - current_temperature[e];
|
|
558
|
+ if (pid_error[e] > PID_FUNCTIONAL_RANGE) {
|
|
559
|
+ pid_output = BANG_MAX;
|
|
560
|
+ pid_reset[e] = true;
|
|
561
|
+ }
|
|
562
|
+ else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
|
|
563
|
+ pid_output = 0;
|
|
564
|
+ pid_reset[e] = true;
|
|
565
|
+ }
|
|
566
|
+ else {
|
|
567
|
+ if (pid_reset[e]) {
|
|
568
|
+ temp_iState[e] = 0.0;
|
|
569
|
+ pid_reset[e] = false;
|
|
570
|
+ }
|
|
571
|
+ pTerm[e] = PID_PARAM(Kp,e) * pid_error[e];
|
|
572
|
+ temp_iState[e] += pid_error[e];
|
|
573
|
+ temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
|
574
|
+ iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
|
|
575
|
+
|
|
576
|
+ dTerm[e] = K2 * PID_PARAM(Kd,e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e];
|
|
577
|
+ pid_output = pTerm[e] + iTerm[e] - dTerm[e];
|
|
578
|
+ if (pid_output > PID_MAX) {
|
|
579
|
+ if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
|
580
|
+ pid_output = PID_MAX;
|
|
581
|
+ }
|
|
582
|
+ else if (pid_output < 0) {
|
|
583
|
+ if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
|
584
|
+ pid_output = 0;
|
|
585
|
+ }
|
|
586
|
+ }
|
|
587
|
+ temp_dState[e] = current_temperature[e];
|
|
588
|
+ #else
|
|
589
|
+ pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
|
590
|
+ #endif //PID_OPENLOOP
|
|
591
|
+
|
|
592
|
+ #ifdef PID_DEBUG
|
|
593
|
+ SERIAL_ECHO_START;
|
|
594
|
+ SERIAL_ECHO(MSG_PID_DEBUG);
|
|
595
|
+ SERIAL_ECHO(e);
|
|
596
|
+ SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
|
|
597
|
+ SERIAL_ECHO(current_temperature[e]);
|
|
598
|
+ SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
|
|
599
|
+ SERIAL_ECHO(pid_output);
|
|
600
|
+ SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
|
|
601
|
+ SERIAL_ECHO(pTerm[e]);
|
|
602
|
+ SERIAL_ECHO(MSG_PID_DEBUG_ITERM);
|
|
603
|
+ SERIAL_ECHO(iTerm[e]);
|
|
604
|
+ SERIAL_ECHO(MSG_PID_DEBUG_DTERM);
|
|
605
|
+ SERIAL_ECHOLN(dTerm[e]);
|
|
606
|
+ #endif //PID_DEBUG
|
|
607
|
+
|
|
608
|
+ #else /* PID off */
|
|
609
|
+ pid_output = (current_temperature[e] < target_temperature[e]) ? PID_MAX : 0;
|
|
610
|
+ #endif
|
|
611
|
+
|
|
612
|
+ return pid_output;
|
|
613
|
+}
|
|
614
|
+
|
|
615
|
+#ifdef PIDTEMPBED
|
|
616
|
+ float get_pid_output_bed() {
|
|
617
|
+ float pid_output;
|
|
618
|
+ #ifndef PID_OPENLOOP
|
|
619
|
+ pid_error_bed = target_temperature_bed - current_temperature_bed;
|
|
620
|
+ pTerm_bed = bedKp * pid_error_bed;
|
|
621
|
+ temp_iState_bed += pid_error_bed;
|
|
622
|
+ temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
|
|
623
|
+ iTerm_bed = bedKi * temp_iState_bed;
|
|
624
|
+
|
|
625
|
+ dTerm_bed = K2 * bedKd * (current_temperature_bed - temp_dState_bed) + K1 * dTerm_bed;
|
|
626
|
+ temp_dState_bed = current_temperature_bed;
|
|
627
|
+
|
|
628
|
+ pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
|
|
629
|
+ if (pid_output > MAX_BED_POWER) {
|
|
630
|
+ if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
|
631
|
+ pid_output = MAX_BED_POWER;
|
|
632
|
+ }
|
|
633
|
+ else if (pid_output < 0) {
|
|
634
|
+ if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
|
635
|
+ pid_output = 0;
|
|
636
|
+ }
|
|
637
|
+ #else
|
|
638
|
+ pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
|
639
|
+ #endif // PID_OPENLOOP
|
|
640
|
+
|
|
641
|
+ return pid_output;
|
|
642
|
+ }
|
|
643
|
+#endif
|
|
644
|
+
|
549
|
645
|
void manage_heater() {
|
550
|
646
|
|
551
|
647
|
if (!temp_meas_ready) return;
|
552
|
648
|
|
553
|
|
- float pid_input, pid_output;
|
554
|
|
-
|
555
|
649
|
updateTemperaturesFromRawValues();
|
556
|
650
|
|
557
|
651
|
#ifdef HEATER_0_USES_MAX6675
|
|
@@ -569,69 +663,7 @@ void manage_heater() {
|
569
|
663
|
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
|
570
|
664
|
#endif
|
571
|
665
|
|
572
|
|
- #ifdef PIDTEMP
|
573
|
|
- pid_input = current_temperature[e];
|
574
|
|
-
|
575
|
|
- #ifndef PID_OPENLOOP
|
576
|
|
- pid_error[e] = target_temperature[e] - pid_input;
|
577
|
|
- if (pid_error[e] > PID_FUNCTIONAL_RANGE) {
|
578
|
|
- pid_output = BANG_MAX;
|
579
|
|
- pid_reset[e] = true;
|
580
|
|
- }
|
581
|
|
- else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
|
582
|
|
- pid_output = 0;
|
583
|
|
- pid_reset[e] = true;
|
584
|
|
- }
|
585
|
|
- else {
|
586
|
|
- if (pid_reset[e] == true) {
|
587
|
|
- temp_iState[e] = 0.0;
|
588
|
|
- pid_reset[e] = false;
|
589
|
|
- }
|
590
|
|
- pTerm[e] = PID_PARAM(Kp,e) * pid_error[e];
|
591
|
|
- temp_iState[e] += pid_error[e];
|
592
|
|
- temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
593
|
|
- iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
|
594
|
|
-
|
595
|
|
- //K1 defined in Configuration.h in the PID settings
|
596
|
|
- #define K2 (1.0-K1)
|
597
|
|
- dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e])) * K2 + (K1 * dTerm[e]);
|
598
|
|
- pid_output = pTerm[e] + iTerm[e] - dTerm[e];
|
599
|
|
- if (pid_output > PID_MAX) {
|
600
|
|
- if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
601
|
|
- pid_output = PID_MAX;
|
602
|
|
- }
|
603
|
|
- else if (pid_output < 0) {
|
604
|
|
- if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
|
605
|
|
- pid_output = 0;
|
606
|
|
- }
|
607
|
|
- }
|
608
|
|
- temp_dState[e] = pid_input;
|
609
|
|
- #else
|
610
|
|
- pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
611
|
|
- #endif //PID_OPENLOOP
|
612
|
|
-
|
613
|
|
- #ifdef PID_DEBUG
|
614
|
|
- SERIAL_ECHO_START;
|
615
|
|
- SERIAL_ECHO(MSG_PID_DEBUG);
|
616
|
|
- SERIAL_ECHO(e);
|
617
|
|
- SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
|
618
|
|
- SERIAL_ECHO(pid_input);
|
619
|
|
- SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
|
620
|
|
- SERIAL_ECHO(pid_output);
|
621
|
|
- SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
|
622
|
|
- SERIAL_ECHO(pTerm[e]);
|
623
|
|
- SERIAL_ECHO(MSG_PID_DEBUG_ITERM);
|
624
|
|
- SERIAL_ECHO(iTerm[e]);
|
625
|
|
- SERIAL_ECHO(MSG_PID_DEBUG_DTERM);
|
626
|
|
- SERIAL_ECHOLN(dTerm[e]);
|
627
|
|
- #endif //PID_DEBUG
|
628
|
|
-
|
629
|
|
- #else /* PID off */
|
630
|
|
-
|
631
|
|
- pid_output = 0;
|
632
|
|
- if (current_temperature[e] < target_temperature[e]) pid_output = PID_MAX;
|
633
|
|
-
|
634
|
|
- #endif
|
|
666
|
+ float pid_output = get_pid_output(e);
|
635
|
667
|
|
636
|
668
|
// Check if temperature is within the correct range
|
637
|
669
|
soft_pwm[e] = current_temperature[e] > minttemp[e] && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0;
|
|
@@ -678,33 +710,7 @@ void manage_heater() {
|
678
|
710
|
#endif
|
679
|
711
|
|
680
|
712
|
#ifdef PIDTEMPBED
|
681
|
|
- pid_input = current_temperature_bed;
|
682
|
|
-
|
683
|
|
- #ifndef PID_OPENLOOP
|
684
|
|
- pid_error_bed = target_temperature_bed - pid_input;
|
685
|
|
- pTerm_bed = bedKp * pid_error_bed;
|
686
|
|
- temp_iState_bed += pid_error_bed;
|
687
|
|
- temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
|
688
|
|
- iTerm_bed = bedKi * temp_iState_bed;
|
689
|
|
-
|
690
|
|
- //K1 defined in Configuration.h in the PID settings
|
691
|
|
- #define K2 (1.0-K1)
|
692
|
|
- dTerm_bed = (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
|
693
|
|
- temp_dState_bed = pid_input;
|
694
|
|
-
|
695
|
|
- pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
|
696
|
|
- if (pid_output > MAX_BED_POWER) {
|
697
|
|
- if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
698
|
|
- pid_output = MAX_BED_POWER;
|
699
|
|
- }
|
700
|
|
- else if (pid_output < 0) {
|
701
|
|
- if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
702
|
|
- pid_output = 0;
|
703
|
|
- }
|
704
|
|
-
|
705
|
|
- #else
|
706
|
|
- pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
707
|
|
- #endif //PID_OPENLOOP
|
|
713
|
+ pid_output = get_pid_output_bed();
|
708
|
714
|
|
709
|
715
|
soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0;
|
710
|
716
|
|