🐛 Fix Bed/Chamber PID Autotune with MPCTEMP (#23983)
This commit is contained in:
parent
a6ce9bf559
commit
6c557a2480
|
@ -417,7 +417,9 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
||||||
if (do_reset_timeout) gcode.reset_stepper_timeout(ms);
|
if (do_reset_timeout) gcode.reset_stepper_timeout(ms);
|
||||||
|
|
||||||
if (gcode.stepper_max_timed_out(ms)) {
|
if (gcode.stepper_max_timed_out(ms)) {
|
||||||
SERIAL_ERROR_MSG(STR_KILL_INACTIVE_TIME, parser.command_ptr);
|
SERIAL_ERROR_START();
|
||||||
|
SERIAL_ECHOPGM(STR_KILL_PRE);
|
||||||
|
SERIAL_ECHOLNPGM(STR_KILL_INACTIVE_TIME, parser.command_ptr);
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +477,9 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
||||||
// KILL the machine
|
// KILL the machine
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
if (killCount >= KILL_DELAY) {
|
if (killCount >= KILL_DELAY) {
|
||||||
SERIAL_ERROR_MSG(STR_KILL_BUTTON);
|
SERIAL_ERROR_START();
|
||||||
|
SERIAL_ECHOPGM(STR_KILL_PRE);
|
||||||
|
SERIAL_ECHOLNPGM(STR_KILL_BUTTON);
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -199,16 +199,20 @@
|
||||||
#define STR_FILAMENT_CHANGE_INSERT_M108 "Insert filament and send M108"
|
#define STR_FILAMENT_CHANGE_INSERT_M108 "Insert filament and send M108"
|
||||||
#define STR_FILAMENT_CHANGE_WAIT_M108 "Send M108 to resume"
|
#define STR_FILAMENT_CHANGE_WAIT_M108 "Send M108 to resume"
|
||||||
|
|
||||||
#define STR_STOP_BLTOUCH "!! STOP called because of BLTouch error - restart with M999"
|
#define STR_STOP_PRE "!! STOP called because of "
|
||||||
#define STR_STOP_UNHOMED "!! STOP called because of unhomed error - restart with M999"
|
#define STR_STOP_POST " error - restart with M999"
|
||||||
#define STR_KILL_INACTIVE_TIME "!! KILL caused by too much inactive time - current command: "
|
#define STR_STOP_BLTOUCH "BLTouch"
|
||||||
#define STR_KILL_BUTTON "!! KILL caused by KILL button/pin"
|
#define STR_STOP_UNHOMED "unhomed"
|
||||||
|
#define STR_KILL_PRE "!! KILL caused by "
|
||||||
|
#define STR_KILL_INACTIVE_TIME "too much inactive time - current command: "
|
||||||
|
#define STR_KILL_BUTTON "KILL button/pin"
|
||||||
|
|
||||||
// temperature.cpp strings
|
// temperature.cpp strings
|
||||||
#define STR_PID_AUTOTUNE_START "PID Autotune start"
|
#define STR_PID_AUTOTUNE "PID Autotune"
|
||||||
#define STR_PID_BAD_HEATER_ID "PID Autotune failed! Bad heater id"
|
#define STR_PID_AUTOTUNE_START " start"
|
||||||
#define STR_PID_TEMP_TOO_HIGH "PID Autotune failed! Temperature too high"
|
#define STR_PID_BAD_HEATER_ID " failed! Bad heater id"
|
||||||
#define STR_PID_TIMEOUT "PID Autotune failed! timeout"
|
#define STR_PID_TEMP_TOO_HIGH " failed! Temperature too high"
|
||||||
|
#define STR_PID_TIMEOUT " failed! timeout"
|
||||||
#define STR_BIAS " bias: "
|
#define STR_BIAS " bias: "
|
||||||
#define STR_D_COLON " d: "
|
#define STR_D_COLON " d: "
|
||||||
#define STR_T_MIN " min: "
|
#define STR_T_MIN " min: "
|
||||||
|
@ -219,7 +223,7 @@
|
||||||
#define STR_KP " Kp: "
|
#define STR_KP " Kp: "
|
||||||
#define STR_KI " Ki: "
|
#define STR_KI " Ki: "
|
||||||
#define STR_KD " Kd: "
|
#define STR_KD " Kd: "
|
||||||
#define STR_PID_AUTOTUNE_FINISHED "PID Autotune finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
|
#define STR_PID_AUTOTUNE_FINISHED " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
|
||||||
#define STR_PID_DEBUG " PID_DEBUG "
|
#define STR_PID_DEBUG " PID_DEBUG "
|
||||||
#define STR_PID_DEBUG_INPUT ": Input "
|
#define STR_PID_DEBUG_INPUT ": Input "
|
||||||
#define STR_PID_DEBUG_OUTPUT " Output "
|
#define STR_PID_DEBUG_OUTPUT " Output "
|
||||||
|
|
|
@ -111,11 +111,8 @@ bool BLTouch::deploy_proc() {
|
||||||
// Last attempt to DEPLOY
|
// Last attempt to DEPLOY
|
||||||
if (_deploy_query_alarm()) {
|
if (_deploy_query_alarm()) {
|
||||||
// The deploy might have failed or the probe is actually triggered (nozzle too low?) again
|
// The deploy might have failed or the probe is actually triggered (nozzle too low?) again
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Recovery Failed");
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Deploy Failed");
|
||||||
|
probe.probe_error_stop(); // Something is wrong, needs action, but not too bad, allow restart
|
||||||
SERIAL_ERROR_MSG(STR_STOP_BLTOUCH); // Tell the user something is wrong, needs action
|
|
||||||
stop(); // but it's not too bad, no need to kill, allow restart
|
|
||||||
|
|
||||||
return true; // Tell our caller we goofed in case he cares to know
|
return true; // Tell our caller we goofed in case he cares to know
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,12 +150,8 @@ bool BLTouch::stow_proc() {
|
||||||
// But one more STOW will catch that
|
// But one more STOW will catch that
|
||||||
// Last attempt to STOW
|
// Last attempt to STOW
|
||||||
if (_stow_query_alarm()) { // so if there is now STILL an ALARM condition:
|
if (_stow_query_alarm()) { // so if there is now STILL an ALARM condition:
|
||||||
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Stow Failed");
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Recovery Failed");
|
probe.probe_error_stop(); // Something is wrong, needs action, but not too bad, allow restart
|
||||||
|
|
||||||
SERIAL_ERROR_MSG(STR_STOP_BLTOUCH); // Tell the user something is wrong, needs action
|
|
||||||
stop(); // but it's not too bad, no need to kill, allow restart
|
|
||||||
|
|
||||||
return true; // Tell our caller we goofed in case he cares to know
|
return true; // Tell our caller we goofed in case he cares to know
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ void GcodeSuite::M303() {
|
||||||
case H_CHAMBER: default_temp = PREHEAT_1_TEMP_CHAMBER; break;
|
case H_CHAMBER: default_temp = PREHEAT_1_TEMP_CHAMBER; break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||||
SERIAL_ECHOLNPGM(STR_PID_BAD_HEATER_ID);
|
SERIAL_ECHOLNPGM(STR_PID_BAD_HEATER_ID);
|
||||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_BAD_EXTRUDER_NUM));
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_BAD_EXTRUDER_NUM));
|
||||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_BAD_EXTRUDER_NUM));
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_BAD_EXTRUDER_NUM));
|
||||||
|
|
|
@ -2854,10 +2854,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
|
||||||
#if ENABLED(DWIN_CREALITY_LCD)
|
#if ENABLED(DWIN_CREALITY_LCD)
|
||||||
#if DISABLED(SDSUPPORT)
|
#if DISABLED(SDSUPPORT)
|
||||||
#error "DWIN_CREALITY_LCD requires SDSUPPORT to be enabled."
|
#error "DWIN_CREALITY_LCD requires SDSUPPORT to be enabled."
|
||||||
#elif ENABLED(PID_EDIT_MENU)
|
#elif EITHER(PID_EDIT_MENU, PID_AUTOTUNE_MENU)
|
||||||
#error "DWIN_CREALITY_LCD does not support PID_EDIT_MENU."
|
#error "DWIN_CREALITY_LCD does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU."
|
||||||
#elif ENABLED(PID_AUTOTUNE_MENU)
|
|
||||||
#error "DWIN_CREALITY_LCD does not support PID_AUTOTUNE_MENU."
|
|
||||||
#elif ENABLED(LEVEL_BED_CORNERS)
|
#elif ENABLED(LEVEL_BED_CORNERS)
|
||||||
#error "DWIN_CREALITY_LCD does not support LEVEL_BED_CORNERS."
|
#error "DWIN_CREALITY_LCD does not support LEVEL_BED_CORNERS."
|
||||||
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
|
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
|
||||||
|
@ -2866,10 +2864,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
|
||||||
#elif ENABLED(DWIN_LCD_PROUI)
|
#elif ENABLED(DWIN_LCD_PROUI)
|
||||||
#if DISABLED(SDSUPPORT)
|
#if DISABLED(SDSUPPORT)
|
||||||
#error "DWIN_LCD_PROUI requires SDSUPPORT to be enabled."
|
#error "DWIN_LCD_PROUI requires SDSUPPORT to be enabled."
|
||||||
#elif ENABLED(PID_EDIT_MENU)
|
#elif EITHER(PID_EDIT_MENU, PID_AUTOTUNE_MENU)
|
||||||
#error "DWIN_LCD_PROUI does not support PID_EDIT_MENU."
|
#error "DWIN_LCD_PROUI does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU."
|
||||||
#elif ENABLED(PID_AUTOTUNE_MENU)
|
|
||||||
#error "DWIN_LCD_PROUI does not support PID_AUTOTUNE_MENU."
|
|
||||||
#elif ENABLED(LEVEL_BED_CORNERS)
|
#elif ENABLED(LEVEL_BED_CORNERS)
|
||||||
#error "DWIN_LCD_PROUI does not support LEVEL_BED_CORNERS."
|
#error "DWIN_LCD_PROUI does not support LEVEL_BED_CORNERS."
|
||||||
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
|
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
|
||||||
|
|
|
@ -211,7 +211,7 @@ void menu_backlash();
|
||||||
|
|
||||||
// Helpers for editing PID Ki & Kd values
|
// Helpers for editing PID Ki & Kd values
|
||||||
// grab the PID value out of the temp variable; scale it; then update the PID driver
|
// grab the PID value out of the temp variable; scale it; then update the PID driver
|
||||||
void copy_and_scalePID_i(int16_t e) {
|
void copy_and_scalePID_i(const int8_t e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
#if ENABLED(PIDTEMPBED)
|
#if ENABLED(PIDTEMPBED)
|
||||||
case H_BED: thermalManager.temp_bed.pid.Ki = scalePID_i(raw_Ki); break;
|
case H_BED: thermalManager.temp_bed.pid.Ki = scalePID_i(raw_Ki); break;
|
||||||
|
@ -227,7 +227,7 @@ void menu_backlash();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void copy_and_scalePID_d(int16_t e) {
|
void copy_and_scalePID_d(const int8_t e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
#if ENABLED(PIDTEMPBED)
|
#if ENABLED(PIDTEMPBED)
|
||||||
case H_BED: thermalManager.temp_bed.pid.Kd = scalePID_d(raw_Kd); break;
|
case H_BED: thermalManager.temp_bed.pid.Kd = scalePID_d(raw_Kd); break;
|
||||||
|
@ -243,30 +243,6 @@ void menu_backlash();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _DEFINE_PIDTEMP_BASE_FUNCS(N) \
|
|
||||||
void copy_and_scalePID_i_E##N() { copy_and_scalePID_i(N); } \
|
|
||||||
void copy_and_scalePID_d_E##N() { copy_and_scalePID_d(N); }
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define _DEFINE_PIDTEMP_BASE_FUNCS(N) //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(PID_AUTOTUNE_MENU)
|
|
||||||
#define DEFINE_PIDTEMP_FUNCS(N) \
|
|
||||||
_DEFINE_PIDTEMP_BASE_FUNCS(N); \
|
|
||||||
void lcd_autotune_callback_E##N() { _lcd_autotune(heater_id_t(N)); }
|
|
||||||
#else
|
|
||||||
#define DEFINE_PIDTEMP_FUNCS(N) _DEFINE_PIDTEMP_BASE_FUNCS(N);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAS_HOTEND
|
|
||||||
DEFINE_PIDTEMP_FUNCS(0);
|
|
||||||
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
|
||||||
REPEAT_S(1, HOTENDS, DEFINE_PIDTEMP_FUNCS)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOTH(AUTOTEMP, HAS_TEMP_HOTEND) || EITHER(PID_AUTOTUNE_MENU, PID_EDIT_MENU)
|
#if BOTH(AUTOTEMP, HAS_TEMP_HOTEND) || EITHER(PID_AUTOTUNE_MENU, PID_EDIT_MENU)
|
||||||
|
@ -281,6 +257,7 @@ void menu_backlash();
|
||||||
void menu_advanced_temperature() {
|
void menu_advanced_temperature() {
|
||||||
START_MENU();
|
START_MENU();
|
||||||
BACK_ITEM(MSG_ADVANCED_SETTINGS);
|
BACK_ITEM(MSG_ADVANCED_SETTINGS);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Autotemp, Min, Max, Fact
|
// Autotemp, Min, Max, Fact
|
||||||
//
|
//
|
||||||
|
@ -300,14 +277,7 @@ void menu_backlash();
|
||||||
// PID-P E5, PID-I E5, PID-D E5, PID-C E5, PID Autotune E5
|
// PID-P E5, PID-I E5, PID-D E5, PID-C E5, PID Autotune E5
|
||||||
//
|
//
|
||||||
|
|
||||||
#if ENABLED(PID_EDIT_MENU)
|
#if BOTH(PIDTEMP, PID_EDIT_MENU)
|
||||||
#define _PID_EDIT_ITEMS_TMPL(N,T) \
|
|
||||||
raw_Ki = unscalePID_i(T.pid.Ki); \
|
|
||||||
raw_Kd = unscalePID_d(T.pid.Kd); \
|
|
||||||
EDIT_ITEM_FAST_N(float41sign, N, MSG_PID_P_E, &T.pid.Kp, 1, 9990); \
|
|
||||||
EDIT_ITEM_FAST_N(float52sign, N, MSG_PID_I_E, &raw_Ki, 0.01f, 9990, []{ copy_and_scalePID_i(N); }); \
|
|
||||||
EDIT_ITEM_FAST_N(float41sign, N, MSG_PID_D_E, &raw_Kd, 1, 9990, []{ copy_and_scalePID_d(N); })
|
|
||||||
|
|
||||||
#define __PID_HOTEND_MENU_ITEMS(N) \
|
#define __PID_HOTEND_MENU_ITEMS(N) \
|
||||||
raw_Ki = unscalePID_i(PID_PARAM(Ki, N)); \
|
raw_Ki = unscalePID_i(PID_PARAM(Ki, N)); \
|
||||||
raw_Kd = unscalePID_d(PID_PARAM(Kd, N)); \
|
raw_Kd = unscalePID_d(PID_PARAM(Kd, N)); \
|
||||||
|
@ -337,6 +307,16 @@ void menu_backlash();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(PID_EDIT_MENU) && EITHER(PIDTEMPBED, PIDTEMPCHAMBER)
|
||||||
|
#define _PID_EDIT_ITEMS_TMPL(N,T) \
|
||||||
|
raw_Ki = unscalePID_i(T.pid.Ki); \
|
||||||
|
raw_Kd = unscalePID_d(T.pid.Kd); \
|
||||||
|
EDIT_ITEM_FAST_N(float41sign, N, MSG_PID_P_E, &T.pid.Kp, 1, 9990); \
|
||||||
|
EDIT_ITEM_FAST_N(float52sign, N, MSG_PID_I_E, &raw_Ki, 0.01f, 9990, []{ copy_and_scalePID_i(N); }); \
|
||||||
|
EDIT_ITEM_FAST_N(float41sign, N, MSG_PID_D_E, &raw_Kd, 1, 9990, []{ copy_and_scalePID_d(N); })
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(PIDTEMP)
|
||||||
#if ENABLED(PID_AUTOTUNE_MENU)
|
#if ENABLED(PID_AUTOTUNE_MENU)
|
||||||
#define HOTEND_PID_EDIT_MENU_ITEMS(N) \
|
#define HOTEND_PID_EDIT_MENU_ITEMS(N) \
|
||||||
_HOTEND_PID_EDIT_MENU_ITEMS(N); \
|
_HOTEND_PID_EDIT_MENU_ITEMS(N); \
|
||||||
|
@ -347,7 +327,8 @@ void menu_backlash();
|
||||||
|
|
||||||
HOTEND_PID_EDIT_MENU_ITEMS(0);
|
HOTEND_PID_EDIT_MENU_ITEMS(0);
|
||||||
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
||||||
REPEAT_S(1, HOTENDS, HOTEND_PID_EDIT_MENU_ITEMS)
|
REPEAT_S(1, HOTENDS, HOTEND_PID_EDIT_MENU_ITEMS);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(PIDTEMPBED)
|
#if ENABLED(PIDTEMPBED)
|
||||||
|
|
|
@ -415,6 +415,21 @@ FORCE_INLINE void probe_specific_action(const bool deploy) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print an error and stop()
|
||||||
|
*/
|
||||||
|
void Probe::probe_error_stop() {
|
||||||
|
SERIAL_ERROR_START();
|
||||||
|
SERIAL_ECHOPGM(STR_STOP_PRE);
|
||||||
|
#if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
|
||||||
|
SERIAL_ECHOPGM(STR_STOP_UNHOMED);
|
||||||
|
#elif ENABLED(BLTOUCH)
|
||||||
|
SERIAL_ECHOPGM(STR_STOP_BLTOUCH);
|
||||||
|
#endif
|
||||||
|
SERIAL_ECHOLNPGM(STR_STOP_POST);
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to deploy or stow the probe
|
* Attempt to deploy or stow the probe
|
||||||
*
|
*
|
||||||
|
@ -443,8 +458,7 @@ bool Probe::set_deployed(const bool deploy) {
|
||||||
|
|
||||||
#if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
|
#if EITHER(Z_PROBE_SLED, Z_PROBE_ALLEN_KEY)
|
||||||
if (homing_needed_error(TERN_(Z_PROBE_SLED, _BV(X_AXIS)))) {
|
if (homing_needed_error(TERN_(Z_PROBE_SLED, _BV(X_AXIS)))) {
|
||||||
SERIAL_ERROR_MSG(STR_STOP_UNHOMED);
|
probe_error_stop();
|
||||||
stop();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -484,15 +498,12 @@ bool Probe::set_deployed(const bool deploy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used by run_z_probe to do a single Z probe move.
|
* @brief Move down until the probe triggers or the low limit is reached
|
||||||
|
* Used by run_z_probe to do a single Z probe move.
|
||||||
*
|
*
|
||||||
* @param z Z destination
|
* @param z Z destination
|
||||||
* @param fr_mm_s Feedrate in mm/s
|
* @param fr_mm_s Feedrate in mm/s
|
||||||
* @return true to indicate an error
|
* @return true to indicate an error
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Move down until the probe triggers or the low limit is reached
|
|
||||||
*
|
*
|
||||||
* @details Used by run_z_probe to get each bed Z height measurement.
|
* @details Used by run_z_probe to get each bed Z height measurement.
|
||||||
* Sets current_position.z to the height where the probe triggered
|
* Sets current_position.z to the height where the probe triggered
|
||||||
|
|
|
@ -78,6 +78,8 @@ public:
|
||||||
static void preheat_for_probing(const celsius_t hotend_temp, const celsius_t bed_temp);
|
static void preheat_for_probing(const celsius_t hotend_temp, const celsius_t bed_temp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void probe_error_stop();
|
||||||
|
|
||||||
static bool set_deployed(const bool deploy);
|
static bool set_deployed(const bool deploy);
|
||||||
|
|
||||||
#if IS_KINEMATIC
|
#if IS_KINEMATIC
|
||||||
|
|
|
@ -638,6 +638,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(isbed ? PID_BED_START : PID_EXTR_START));
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(isbed ? PID_BED_START : PID_EXTR_START));
|
||||||
|
|
||||||
if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, temp_range[heater_id].maxtemp - (HOTEND_OVERSHOOT))) {
|
if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, temp_range[heater_id].maxtemp - (HOTEND_OVERSHOOT))) {
|
||||||
|
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||||
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
|
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
|
||||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
||||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
||||||
|
@ -645,6 +646,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||||
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_START);
|
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_START);
|
||||||
|
|
||||||
disable_all_heaters();
|
disable_all_heaters();
|
||||||
|
@ -660,10 +662,11 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
|
|
||||||
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = false);
|
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = false);
|
||||||
|
|
||||||
// PID Tuning loop
|
|
||||||
wait_for_heatup = true; // Can be interrupted with M108
|
|
||||||
LCD_MESSAGE(MSG_HEATING);
|
LCD_MESSAGE(MSG_HEATING);
|
||||||
while (wait_for_heatup) {
|
|
||||||
|
// PID Tuning loop
|
||||||
|
wait_for_heatup = true;
|
||||||
|
while (wait_for_heatup) { // Can be interrupted with M108
|
||||||
|
|
||||||
const millis_t ms = millis();
|
const millis_t ms = millis();
|
||||||
|
|
||||||
|
@ -729,6 +732,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
#define MAX_OVERSHOOT_PID_AUTOTUNE 30
|
#define MAX_OVERSHOOT_PID_AUTOTUNE 30
|
||||||
#endif
|
#endif
|
||||||
if (current_temp > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
|
if (current_temp > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
|
||||||
|
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||||
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
|
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
|
||||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
||||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
||||||
|
@ -771,11 +775,13 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TUNING_TIMEOUT));
|
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TUNING_TIMEOUT));
|
||||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT));
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT));
|
||||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TIMEOUT)));
|
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TIMEOUT)));
|
||||||
|
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||||
SERIAL_ECHOLNPGM(STR_PID_TIMEOUT);
|
SERIAL_ECHOLNPGM(STR_PID_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycles > ncycles && cycles > 2) {
|
if (cycles > ncycles && cycles > 2) {
|
||||||
|
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||||
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_FINISHED);
|
SERIAL_ECHOLNPGM(STR_PID_AUTOTUNE_FINISHED);
|
||||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE)));
|
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE)));
|
||||||
|
|
||||||
|
@ -875,7 +881,6 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
MPC_t& constants = hotend.constants;
|
MPC_t& constants = hotend.constants;
|
||||||
|
|
||||||
// move to center of bed, just above bed height and cool with max fan
|
// move to center of bed, just above bed height and cool with max fan
|
||||||
SERIAL_ECHOLNPGM("Moving to tuning position");
|
|
||||||
TERN_(HAS_FAN, zero_fan_speeds());
|
TERN_(HAS_FAN, zero_fan_speeds());
|
||||||
disable_all_heaters();
|
disable_all_heaters();
|
||||||
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255));
|
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255));
|
||||||
|
@ -902,6 +907,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
next_test_ms += 10000UL;
|
next_test_ms += 10000UL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0));
|
TERN_(HAS_FAN, set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0));
|
||||||
TERN_(HAS_FAN, planner.sync_fan_speeds(fan_speed));
|
TERN_(HAS_FAN, planner.sync_fan_speeds(fan_speed));
|
||||||
|
|
||||||
|
@ -909,8 +915,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
|
|
||||||
SERIAL_ECHOLNPGM("Heating to 200C");
|
SERIAL_ECHOLNPGM("Heating to 200C");
|
||||||
hotend.soft_pwm_amount = MPC_MAX >> 1;
|
hotend.soft_pwm_amount = MPC_MAX >> 1;
|
||||||
const millis_t heat_start_time = ms;
|
const millis_t heat_start_time = next_test_ms = ms;
|
||||||
next_test_ms = ms;
|
|
||||||
celsius_float_t temp_samples[16];
|
celsius_float_t temp_samples[16];
|
||||||
uint8_t sample_count = 0;
|
uint8_t sample_count = 0;
|
||||||
uint16_t sample_distance = 1;
|
uint16_t sample_distance = 1;
|
||||||
|
@ -941,7 +946,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
}
|
}
|
||||||
hotend.soft_pwm_amount = 0;
|
hotend.soft_pwm_amount = 0;
|
||||||
|
|
||||||
// calculate physical constants from three equally spaced samples
|
// Calculate physical constants from three equally-spaced samples
|
||||||
sample_count = (sample_count + 1) / 2 * 2 - 1;
|
sample_count = (sample_count + 1) / 2 * 2 - 1;
|
||||||
const float t1 = temp_samples[0],
|
const float t1 = temp_samples[0],
|
||||||
t2 = temp_samples[(sample_count - 1) >> 1],
|
t2 = temp_samples[(sample_count - 1) >> 1],
|
||||||
|
@ -957,14 +962,13 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
hotend.modeled_block_temp = asymp_temp + (ambient_temp - asymp_temp) * exp(-block_responsiveness * (ms - heat_start_time) / 1000.0f);
|
hotend.modeled_block_temp = asymp_temp + (ambient_temp - asymp_temp) * exp(-block_responsiveness * (ms - heat_start_time) / 1000.0f);
|
||||||
hotend.modeled_sensor_temp = current_temp;
|
hotend.modeled_sensor_temp = current_temp;
|
||||||
|
|
||||||
// let the system stabilise under MPC control then get a better measure of ambient loss without and with fan
|
// Allow the system to stabilize under MPC, then get a better measure of ambient loss with and without fan
|
||||||
SERIAL_ECHOLNPGM("Measuring ambient heatloss at target ", hotend.modeled_block_temp);
|
SERIAL_ECHOLNPGM("Measuring ambient heatloss at target ", hotend.modeled_block_temp);
|
||||||
hotend.target = hotend.modeled_block_temp;
|
hotend.target = hotend.modeled_block_temp;
|
||||||
next_test_ms = ms + MPC_dT * 1000;
|
next_test_ms = ms + MPC_dT * 1000;
|
||||||
constexpr millis_t settle_time = 20000UL,
|
constexpr millis_t settle_time = 20000UL, test_duration = 20000UL;
|
||||||
test_length = 20000UL;
|
|
||||||
millis_t settle_end_ms = ms + settle_time,
|
millis_t settle_end_ms = ms + settle_time,
|
||||||
test_end_ms = settle_end_ms + test_length;
|
test_end_ms = settle_end_ms + test_duration;
|
||||||
float total_energy_fan0 = 0.0f;
|
float total_energy_fan0 = 0.0f;
|
||||||
#if HAS_FAN
|
#if HAS_FAN
|
||||||
bool fan0_done = false;
|
bool fan0_done = false;
|
||||||
|
@ -987,7 +991,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
|
set_fan_speed(ANY(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
|
||||||
planner.sync_fan_speeds(fan_speed);
|
planner.sync_fan_speeds(fan_speed);
|
||||||
settle_end_ms = ms + settle_time;
|
settle_end_ms = ms + settle_time;
|
||||||
test_end_ms = settle_end_ms + test_length;
|
test_end_ms = settle_end_ms + test_duration;
|
||||||
fan0_done = true;
|
fan0_done = true;
|
||||||
}
|
}
|
||||||
else if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms))
|
else if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms))
|
||||||
|
@ -1005,11 +1009,11 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float power_fan0 = total_energy_fan0 * 1000 / test_length;
|
const float power_fan0 = total_energy_fan0 * 1000 / test_duration;
|
||||||
constants.ambient_xfer_coeff_fan0 = power_fan0 / (hotend.target - ambient_temp);
|
constants.ambient_xfer_coeff_fan0 = power_fan0 / (hotend.target - ambient_temp);
|
||||||
|
|
||||||
#if HAS_FAN
|
#if HAS_FAN
|
||||||
const float power_fan255 = total_energy_fan255 * 1000 / test_length,
|
const float power_fan255 = total_energy_fan255 * 1000 / test_duration,
|
||||||
ambient_xfer_coeff_fan255 = power_fan255 / (hotend.target - ambient_temp);
|
ambient_xfer_coeff_fan255 = power_fan255 / (hotend.target - ambient_temp);
|
||||||
constants.fan255_adjustment = ambient_xfer_coeff_fan255 - constants.ambient_xfer_coeff_fan0;
|
constants.fan255_adjustment = ambient_xfer_coeff_fan255 - constants.ambient_xfer_coeff_fan0;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue