@@ -660,13 +660,13 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
TERN_(HAS_FAN_LOGIC, fan_update_ms = next_temp_ms + fan_update_interval_ms);
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_STARTED));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(isbed ? PIDTEMPBED_START : PIDTEMP_START));
|
||||
TERN_(DWIN_PID_TUNE, DWIN_PidTuning(isbed ? PIDTEMPBED_START : PIDTEMP_START));
|
||||
|
||||
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);
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
||||
TERN_(DWIN_PID_TUNE, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)));
|
||||
return;
|
||||
}
|
||||
@@ -760,7 +760,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||
SERIAL_ECHOLNPGM(STR_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_PID_TUNE, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)));
|
||||
break;
|
||||
}
|
||||
@@ -797,7 +797,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
#endif
|
||||
if ((ms - _MIN(t1, t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) {
|
||||
TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_TUNING_TIMEOUT));
|
||||
TERN_(DWIN_PID_TUNE, DWIN_PidTuning(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)));
|
||||
SERIAL_ECHOPGM(STR_PID_AUTOTUNE);
|
||||
@@ -852,7 +852,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color));
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_DONE));
|
||||
TERN_(DWIN_PID_TUNE, DWIN_PidTuning(PID_DONE));
|
||||
|
||||
goto EXIT_M303;
|
||||
}
|
||||
@@ -870,7 +870,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color));
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_DONE));
|
||||
TERN_(DWIN_PID_TUNE, DWIN_PidTuning(PID_DONE));
|
||||
|
||||
EXIT_M303:
|
||||
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = true);
|
||||
@@ -882,7 +882,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
#if ENABLED(MPCTEMP)
|
||||
|
||||
void Temperature::MPC_autotune() {
|
||||
auto housekeeping = [] (millis_t& ms, celsius_float_t& current_temp, millis_t& next_report_ms) {
|
||||
auto housekeeping = [] (millis_t &ms, celsius_float_t ¤t_temp, millis_t &next_report_ms) {
|
||||
ms = millis();
|
||||
|
||||
if (updateTemperaturesIfReady()) { // temp sample ready
|
||||
@@ -929,7 +929,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
|
||||
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_START, active_extruder);
|
||||
MPCHeaterInfo &hotend = temp_hotend[active_extruder];
|
||||
MPC_t &constants = hotend.constants;
|
||||
MPC_t &mpc = hotend.mpc;
|
||||
|
||||
// Move to center of bed, just above bed height and cool with max fan
|
||||
gcode.home_all_axes(true);
|
||||
@@ -939,11 +939,11 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
set_fan_speed(EITHER(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
|
||||
planner.sync_fan_speeds(fan_speed);
|
||||
#endif
|
||||
const xyz_pos_t tuningpos = MPC_TUNING_POS;
|
||||
do_blocking_move_to(tuningpos);
|
||||
do_blocking_move_to(xyz_pos_t(MPC_TUNING_POS));
|
||||
|
||||
SERIAL_ECHOLNPGM(STR_MPC_COOLING_TO_AMBIENT);
|
||||
LCD_MESSAGE(MSG_COOLING);
|
||||
|
||||
millis_t ms = millis(), next_report_ms = ms, next_test_ms = ms + 10000UL;
|
||||
celsius_float_t current_temp = degHotend(active_extruder),
|
||||
ambient_temp = current_temp;
|
||||
@@ -961,6 +961,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
next_test_ms += 10000UL;
|
||||
}
|
||||
}
|
||||
wait_for_heatup = false;
|
||||
|
||||
#if HAS_FAN
|
||||
set_fan_speed(EITHER(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0);
|
||||
@@ -970,7 +971,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
hotend.modeled_ambient_temp = ambient_temp;
|
||||
|
||||
SERIAL_ECHOLNPGM(STR_MPC_HEATING_PAST_200);
|
||||
LCD_MESSAGE(MSG_HEATING);
|
||||
TERN(DWIN_LCD_PROUI, LCD_ALERTMESSAGE(MSG_MPC_HEATING_PAST_200), LCD_MESSAGE(MSG_HEATING));
|
||||
hotend.target = 200.0f; // So M105 looks nice
|
||||
hotend.soft_pwm_amount = MPC_MAX >> 1;
|
||||
const millis_t heat_start_time = next_test_ms = ms;
|
||||
@@ -1012,17 +1013,17 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
float asymp_temp = (t2 * t2 - t1 * t3) / (2 * t2 - t1 - t3),
|
||||
block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / (sample_distance * (sample_count >> 1));
|
||||
|
||||
constants.ambient_xfer_coeff_fan0 = constants.heater_power * (MPC_MAX) / 255 / (asymp_temp - ambient_temp);
|
||||
constants.fan255_adjustment = 0.0f;
|
||||
constants.block_heat_capacity = constants.ambient_xfer_coeff_fan0 / block_responsiveness;
|
||||
constants.sensor_responsiveness = block_responsiveness / (1.0f - (ambient_temp - asymp_temp) * exp(-block_responsiveness * t1_time) / (t1 - asymp_temp));
|
||||
mpc.ambient_xfer_coeff_fan0 = mpc.heater_power * (MPC_MAX) / 255 / (asymp_temp - ambient_temp);
|
||||
mpc.fan255_adjustment = 0.0f;
|
||||
mpc.block_heat_capacity = mpc.ambient_xfer_coeff_fan0 / block_responsiveness;
|
||||
mpc.sensor_responsiveness = block_responsiveness / (1.0f - (ambient_temp - asymp_temp) * exp(-block_responsiveness * t1_time) / (t1 - asymp_temp));
|
||||
|
||||
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;
|
||||
|
||||
// Allow the system to stabilize under MPC, then get a better measure of ambient loss with and without fan
|
||||
SERIAL_ECHOLNPGM(STR_MPC_MEASURING_AMBIENT, hotend.modeled_block_temp);
|
||||
LCD_MESSAGE(MSG_MPC_MEASURING_AMBIENT);
|
||||
TERN(DWIN_LCD_PROUI, LCD_ALERTMESSAGE(MSG_MPC_MEASURING_AMBIENT), LCD_MESSAGE(MSG_MPC_MEASURING_AMBIENT));
|
||||
hotend.target = hotend.modeled_block_temp;
|
||||
next_test_ms = ms + MPC_dT * 1000;
|
||||
constexpr millis_t settle_time = 20000UL, test_duration = 20000UL;
|
||||
@@ -1042,7 +1043,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
hotend.soft_pwm_amount = (int)get_pid_output_hotend(active_extruder) >> 1;
|
||||
|
||||
if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms) && TERN1(HAS_FAN, !fan0_done))
|
||||
total_energy_fan0 += constants.heater_power * hotend.soft_pwm_amount / 127 * MPC_dT + (last_temp - current_temp) * constants.block_heat_capacity;
|
||||
total_energy_fan0 += mpc.heater_power * hotend.soft_pwm_amount / 127 * MPC_dT + (last_temp - current_temp) * mpc.block_heat_capacity;
|
||||
#if HAS_FAN
|
||||
else if (ELAPSED(ms, test_end_ms) && !fan0_done) {
|
||||
set_fan_speed(EITHER(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 255);
|
||||
@@ -1052,7 +1053,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
fan0_done = true;
|
||||
}
|
||||
else if (ELAPSED(ms, settle_end_ms) && !ELAPSED(ms, test_end_ms))
|
||||
total_energy_fan255 += constants.heater_power * hotend.soft_pwm_amount / 127 * MPC_dT + (last_temp - current_temp) * constants.block_heat_capacity;
|
||||
total_energy_fan255 += mpc.heater_power * hotend.soft_pwm_amount / 127 * MPC_dT + (last_temp - current_temp) * mpc.block_heat_capacity;
|
||||
#endif
|
||||
else if (ELAPSED(ms, test_end_ms)) break;
|
||||
|
||||
@@ -1067,24 +1068,24 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
}
|
||||
|
||||
const float power_fan0 = total_energy_fan0 * 1000 / test_duration;
|
||||
constants.ambient_xfer_coeff_fan0 = power_fan0 / (hotend.target - ambient_temp);
|
||||
mpc.ambient_xfer_coeff_fan0 = power_fan0 / (hotend.target - ambient_temp);
|
||||
|
||||
#if HAS_FAN
|
||||
const float power_fan255 = total_energy_fan255 * 1000 / test_duration,
|
||||
ambient_xfer_coeff_fan255 = power_fan255 / (hotend.target - ambient_temp);
|
||||
constants.fan255_adjustment = ambient_xfer_coeff_fan255 - constants.ambient_xfer_coeff_fan0;
|
||||
mpc.applyFanAdjustment(ambient_xfer_coeff_fan255);
|
||||
#endif
|
||||
|
||||
// Calculate a new and better asymptotic temperature and re-evaluate the other constants
|
||||
asymp_temp = ambient_temp + constants.heater_power * (MPC_MAX) / 255 / constants.ambient_xfer_coeff_fan0;
|
||||
asymp_temp = ambient_temp + mpc.heater_power * (MPC_MAX) / 255 / mpc.ambient_xfer_coeff_fan0;
|
||||
block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / (sample_distance * (sample_count >> 1));
|
||||
constants.block_heat_capacity = constants.ambient_xfer_coeff_fan0 / block_responsiveness;
|
||||
constants.sensor_responsiveness = block_responsiveness / (1.0f - (ambient_temp - asymp_temp) * exp(-block_responsiveness * t1_time) / (t1 - asymp_temp));
|
||||
mpc.block_heat_capacity = mpc.ambient_xfer_coeff_fan0 / block_responsiveness;
|
||||
mpc.sensor_responsiveness = block_responsiveness / (1.0f - (ambient_temp - asymp_temp) * exp(-block_responsiveness * t1_time) / (t1 - asymp_temp));
|
||||
|
||||
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
|
||||
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_FINISHED);
|
||||
|
||||
/* <-- add a slash to enable
|
||||
#if 0
|
||||
SERIAL_ECHOLNPGM("t1_time ", t1_time);
|
||||
SERIAL_ECHOLNPGM("sample_count ", sample_count);
|
||||
SERIAL_ECHOLNPGM("sample_distance ", sample_distance);
|
||||
@@ -1093,10 +1094,11 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
SERIAL_ECHOLNPGM("t1 ", t1, " t2 ", t2, " t3 ", t3);
|
||||
SERIAL_ECHOLNPGM("asymp_temp ", asymp_temp);
|
||||
SERIAL_ECHOLNPAIR_F("block_responsiveness ", block_responsiveness, 4);
|
||||
//*/
|
||||
SERIAL_ECHOLNPGM("MPC_BLOCK_HEAT_CAPACITY ", constants.block_heat_capacity);
|
||||
SERIAL_ECHOLNPAIR_F("MPC_SENSOR_RESPONSIVENESS ", constants.sensor_responsiveness, 4);
|
||||
SERIAL_ECHOLNPAIR_F("MPC_AMBIENT_XFER_COEFF ", constants.ambient_xfer_coeff_fan0, 4);
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM("MPC_BLOCK_HEAT_CAPACITY ", mpc.block_heat_capacity);
|
||||
SERIAL_ECHOLNPAIR_F("MPC_SENSOR_RESPONSIVENESS ", mpc.sensor_responsiveness, 4);
|
||||
SERIAL_ECHOLNPAIR_F("MPC_AMBIENT_XFER_COEFF ", mpc.ambient_xfer_coeff_fan0, 4);
|
||||
TERN_(HAS_FAN, SERIAL_ECHOLNPAIR_F("MPC_AMBIENT_XFER_COEFF_FAN255 ", ambient_xfer_coeff_fan255, 4));
|
||||
}
|
||||
|
||||
@@ -1413,7 +1415,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id) {
|
||||
#elif ENABLED(MPCTEMP)
|
||||
|
||||
MPCHeaterInfo &hotend = temp_hotend[ee];
|
||||
MPC_t &constants = hotend.constants;
|
||||
MPC_t &mpc = hotend.mpc;
|
||||
|
||||
// At startup, initialize modeled temperatures
|
||||
if (isnan(hotend.modeled_block_temp)) {
|
||||
@@ -1427,11 +1429,11 @@ void Temperature::mintemp_error(const heater_id_t heater_id) {
|
||||
const bool this_hotend = (ee == active_extruder);
|
||||
#endif
|
||||
|
||||
float ambient_xfer_coeff = constants.ambient_xfer_coeff_fan0;
|
||||
float ambient_xfer_coeff = mpc.ambient_xfer_coeff_fan0;
|
||||
#if ENABLED(MPC_INCLUDE_FAN)
|
||||
const uint8_t fan_index = EITHER(MPC_FAN_0_ACTIVE_HOTEND, MPC_FAN_0_ALL_HOTENDS) ? 0 : ee;
|
||||
const float fan_fraction = TERN_(MPC_FAN_0_ACTIVE_HOTEND, !this_hotend ? 0.0f : ) fan_speed[fan_index] * RECIPROCAL(255);
|
||||
ambient_xfer_coeff += fan_fraction * constants.fan255_adjustment;
|
||||
ambient_xfer_coeff += fan_fraction * mpc.fan255_adjustment;
|
||||
#endif
|
||||
|
||||
if (this_hotend) {
|
||||
@@ -1442,17 +1444,17 @@ void Temperature::mintemp_error(const heater_id_t heater_id) {
|
||||
if (fabs(e_speed) > planner.settings.max_feedrate_mm_s[E_AXIS])
|
||||
mpc_e_position = e_position;
|
||||
else if (e_speed > 0.0f) { // Ignore retract/recover moves
|
||||
ambient_xfer_coeff += e_speed * constants.filament_heat_capacity_permm;
|
||||
ambient_xfer_coeff += e_speed * mpc.filament_heat_capacity_permm;
|
||||
mpc_e_position = e_position;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the modeled temperatures
|
||||
float blocktempdelta = hotend.soft_pwm_amount * constants.heater_power * (MPC_dT / 127) / constants.block_heat_capacity;
|
||||
blocktempdelta += (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff * MPC_dT / constants.block_heat_capacity;
|
||||
float blocktempdelta = hotend.soft_pwm_amount * mpc.heater_power * (MPC_dT / 127) / mpc.block_heat_capacity;
|
||||
blocktempdelta += (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff * MPC_dT / mpc.block_heat_capacity;
|
||||
hotend.modeled_block_temp += blocktempdelta;
|
||||
|
||||
const float sensortempdelta = (hotend.modeled_block_temp - hotend.modeled_sensor_temp) * (constants.sensor_responsiveness * MPC_dT);
|
||||
const float sensortempdelta = (hotend.modeled_block_temp - hotend.modeled_sensor_temp) * (mpc.sensor_responsiveness * MPC_dT);
|
||||
hotend.modeled_sensor_temp += sensortempdelta;
|
||||
|
||||
// Any delta between hotend.modeled_sensor_temp and hotend.celsius is either model
|
||||
@@ -1468,11 +1470,11 @@ void Temperature::mintemp_error(const heater_id_t heater_id) {
|
||||
float power = 0.0;
|
||||
if (hotend.target != 0 && !is_idling) {
|
||||
// Plan power level to get to target temperature in 2 seconds
|
||||
power = (hotend.target - hotend.modeled_block_temp) * constants.block_heat_capacity / 2.0f;
|
||||
power = (hotend.target - hotend.modeled_block_temp) * mpc.block_heat_capacity / 2.0f;
|
||||
power -= (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff;
|
||||
}
|
||||
|
||||
float pid_output = power * 254.0f / constants.heater_power + 1.0f; // Ensure correct quantization into a range of 0 to 127
|
||||
float pid_output = power * 254.0f / mpc.heater_power + 1.0f; // Ensure correct quantization into a range of 0 to 127
|
||||
pid_output = constrain(pid_output, 0, MPC_MAX);
|
||||
|
||||
/* <-- add a slash to enable
|
||||
|
Reference in New Issue
Block a user