|
@@ -632,6 +632,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
632
|
632
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(isbed ? PID_BED_START : PID_EXTR_START));
|
633
|
633
|
|
634
|
634
|
if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, temp_range[heater_id].maxtemp - (HOTEND_OVERSHOOT))) {
|
|
635
|
+ SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
635
|
636
|
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
|
636
|
637
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
637
|
638
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
|
@@ -639,6 +640,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
639
|
640
|
return;
|
640
|
641
|
}
|
641
|
642
|
|
|
643
|
+ SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
642
|
644
|
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_START);
|
643
|
645
|
|
644
|
646
|
disable_all_heaters();
|
|
@@ -654,10 +656,11 @@ volatile bool Temperature::raw_temps_ready = false;
|
654
|
656
|
|
655
|
657
|
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = false);
|
656
|
658
|
|
657
|
|
- // PID Tuning loop
|
658
|
|
- wait_for_heatup = true; // Can be interrupted with M108
|
659
|
659
|
LCD_MESSAGE(MSG_HEATING);
|
660
|
|
- while (wait_for_heatup) {
|
|
660
|
+
|
|
661
|
+ // PID Tuning loop
|
|
662
|
+ wait_for_heatup = true;
|
|
663
|
+ while (wait_for_heatup) { // Can be interrupted with M108
|
661
|
664
|
|
662
|
665
|
const millis_t ms = millis();
|
663
|
666
|
|
|
@@ -723,6 +726,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
723
|
726
|
#define MAX_OVERSHOOT_PID_AUTOTUNE 30
|
724
|
727
|
#endif
|
725
|
728
|
if (current_temp > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
|
|
729
|
+ SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
726
|
730
|
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
|
727
|
731
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
728
|
732
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
|
@@ -765,11 +769,13 @@ volatile bool Temperature::raw_temps_ready = false;
|
765
|
769
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TUNING_TIMEOUT));
|
766
|
770
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT));
|
767
|
771
|
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TIMEOUT)));
|
|
772
|
+ SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
768
|
773
|
SERIAL_ECHOLNPGM(STR_PID_TIMEOUT);
|
769
|
774
|
break;
|
770
|
775
|
}
|
771
|
776
|
|
772
|
777
|
if (cycles > ncycles && cycles > 2) {
|
|
778
|
+ SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
773
|
779
|
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_FINISHED);
|
774
|
780
|
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE)));
|
775
|
781
|
|
|
@@ -869,7 +875,6 @@ volatile bool Temperature::raw_temps_ready = false;
|
869
|
875
|
MPC_t& constants = hotend.constants;
|
870
|
876
|
|
871
|
877
|
// move to center of bed, just above bed height and cool with max fan
|
872
|
|
- SERIAL_ECHOLNPGM("Moving to tuning position");
|
873
|
878
|
TERN_(HAS_FAN, zero_fan_speeds());
|
874
|
879
|
disable_all_heaters();
|
875
|
880
|
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255));
|
|
@@ -896,6 +901,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
896
|
901
|
next_test_ms += 10000UL;
|
897
|
902
|
}
|
898
|
903
|
}
|
|
904
|
+
|
899
|
905
|
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0));
|
900
|
906
|
TERN_(HAS_FAN, planner.sync_fan_speeds(fan_speed));
|
901
|
907
|
|
|
@@ -903,8 +909,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
903
|
909
|
|
904
|
910
|
SERIAL_ECHOLNPGM("Heating to 200C");
|
905
|
911
|
hotend.soft_pwm_amount = MPC_MAX >> 1;
|
906
|
|
- const millis_t heat_start_time = ms;
|
907
|
|
- next_test_ms = ms;
|
|
912
|
+ const millis_t heat_start_time = next_test_ms = ms;
|
908
|
913
|
celsius_float_t temp_samples[16];
|
909
|
914
|
uint8_t sample_count = 0;
|
910
|
915
|
uint16_t sample_distance = 1;
|
|
@@ -935,7 +940,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
935
|
940
|
}
|
936
|
941
|
hotend.soft_pwm_amount = 0;
|
937
|
942
|
|
938
|
|
- // calculate physical constants from three equally spaced samples
|
|
943
|
+ // Calculate physical constants from three equally-spaced samples
|
939
|
944
|
sample_count = (sample_count + 1) / 2 * 2 - 1;
|
940
|
945
|
const float t1 = temp_samples[0],
|
941
|
946
|
t2 = temp_samples[(sample_count - 1) >> 1],
|
|
@@ -951,14 +956,13 @@ volatile bool Temperature::raw_temps_ready = false;
|
951
|
956
|
hotend.modeled_block_temp = asymp_temp + (ambient_temp - asymp_temp) * exp(-block_responsiveness * (ms - heat_start_time) / 1000.0f);
|
952
|
957
|
hotend.modeled_sensor_temp = current_temp;
|
953
|
958
|
|
954
|
|
- // let the system stabilise under MPC control then get a better measure of ambient loss without and with fan
|
|
959
|
+ // Allow the system to stabilize under MPC, then get a better measure of ambient loss with and without fan
|
955
|
960
|
SERIAL_ECHOLNPGM("Measuring ambient heatloss at target ", hotend.modeled_block_temp);
|
956
|
961
|
hotend.target = hotend.modeled_block_temp;
|
957
|
962
|
next_test_ms = ms + MPC_dT * 1000;
|
958
|
|
- constexpr millis_t settle_time = 20000UL,
|
959
|
|
- test_length = 20000UL;
|
|
963
|
+ constexpr millis_t settle_time = 20000UL, test_duration = 20000UL;
|
960
|
964
|
millis_t settle_end_ms = ms + settle_time,
|
961
|
|
- test_end_ms = settle_end_ms + test_length;
|
|
965
|
+ test_end_ms = settle_end_ms + test_duration;
|
962
|
966
|
float total_energy_fan0 = 0.0f;
|
963
|
967
|
#if HAS_FAN
|
964
|
968
|
bool fan0_done = false;
|
|
@@ -981,7 +985,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
981
|
985
|
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
|
982
|
986
|
planner.sync_fan_speeds(fan_speed);
|
983
|
987
|
settle_end_ms = ms + settle_time;
|
984
|
|
- test_end_ms = settle_end_ms + test_length;
|
|
988
|
+ test_end_ms = settle_end_ms + test_duration;
|
985
|
989
|
fan0_done = true;
|
986
|
990
|
}
|
987
|
991
|
else if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms))
|
|
@@ -999,11 +1003,11 @@ volatile bool Temperature::raw_temps_ready = false;
|
999
|
1003
|
}
|
1000
|
1004
|
}
|
1001
|
1005
|
|
1002
|
|
- const float power_fan0 = total_energy_fan0 * 1000 / test_length;
|
|
1006
|
+ const float power_fan0 = total_energy_fan0 * 1000 / test_duration;
|
1003
|
1007
|
constants.ambient_xfer_coeff_fan0 = power_fan0 / (hotend.target - ambient_temp);
|
1004
|
1008
|
|
1005
|
1009
|
#if HAS_FAN
|
1006
|
|
- const float power_fan255 = total_energy_fan255 * 1000 / test_length,
|
|
1010
|
+ const float power_fan255 = total_energy_fan255 * 1000 / test_duration,
|
1007
|
1011
|
ambient_xfer_coeff_fan255 = power_fan255 / (hotend.target - ambient_temp);
|
1008
|
1012
|
constants.fan255_adjustment = ambient_xfer_coeff_fan255 - constants.ambient_xfer_coeff_fan0;
|
1009
|
1013
|
#endif
|
|
@@ -1369,8 +1373,8 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
|
1369
|
1373
|
#endif
|
1370
|
1374
|
|
1371
|
1375
|
#elif ENABLED(MPCTEMP)
|
1372
|
|
- MPCHeaterInfo& hotend = temp_hotend[ee];
|
1373
|
|
- MPC_t& constants = hotend.constants;
|
|
1376
|
+ MPCHeaterInfo &hotend = temp_hotend[ee];
|
|
1377
|
+ MPC_t &constants = hotend.constants;
|
1374
|
1378
|
|
1375
|
1379
|
// At startup, initialize modeled temperatures
|
1376
|
1380
|
if (isnan(hotend.modeled_block_temp)) {
|