🧑‍💻 Adjust PID / MPC / ProUI

Changes to simplify #25232 WIP
This commit is contained in:
Scott Lahteine
2023-01-15 06:48:17 -06:00
parent d94defc545
commit 6fe387b6f0
34 changed files with 181 additions and 165 deletions

View File

@@ -1429,12 +1429,10 @@
#endif // HAS_MARLINUI_MENU #endif // HAS_MARLINUI_MENU
#if ANY(HAS_DISPLAY, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI) #if HAS_DISPLAY
//#define SOUND_MENU_ITEM // Add a mute option to the LCD menu //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu
#define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state #define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state
#endif
#if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI)
// The timeout to return to the status screen from sub-menus // The timeout to return to the status screen from sub-menus
//#define LCD_TIMEOUT_TO_STATUS 15000 // (ms) //#define LCD_TIMEOUT_TO_STATUS 15000 // (ms)
@@ -1483,7 +1481,7 @@
#endif #endif
#endif #endif
#endif // HAS_DISPLAY || DWIN_LCD_PROUI #endif // HAS_DISPLAY
// Add 'M73' to set print job progress, overrides Marlin's built-in estimate // Add 'M73' to set print job progress, overrides Marlin's built-in estimate
//#define SET_PROGRESS_MANUALLY //#define SET_PROGRESS_MANUALLY

View File

@@ -91,7 +91,7 @@ void GcodeSuite::M428() {
diff[i] = -current_position[i]; diff[i] = -current_position[i];
if (!WITHIN(diff[i], -20, 20)) { if (!WITHIN(diff[i], -20, 20)) {
SERIAL_ERROR_MSG(STR_ERR_M428_TOO_FAR); SERIAL_ERROR_MSG(STR_ERR_M428_TOO_FAR);
LCD_ALERTMESSAGE_F("Err: Too far!"); LCD_ALERTMESSAGE(MSG_ERR_M428_TOO_FAR);
ERR_BUZZ(); ERR_BUZZ();
return; return;
} }

View File

@@ -67,8 +67,8 @@ void GcodeSuite::M303() {
default: default:
SERIAL_ECHOPGM(STR_PID_AUTOTUNE); 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_HEATER_ID));
TERN_(DWIN_LCD_PROUI, DWIN_PidTuning(PID_BAD_EXTRUDER_NUM)); TERN_(DWIN_PID_TUNE, DWIN_PidTuning(PID_BAD_HEATER_ID));
return; return;
} }
@@ -78,20 +78,9 @@ void GcodeSuite::M303() {
const celsius_t temp = seenS ? parser.value_celsius() : default_temp; const celsius_t temp = seenS ? parser.value_celsius() : default_temp;
const bool u = parser.boolval('U'); const bool u = parser.boolval('U');
#if ENABLED(DWIN_LCD_PROUI) && EITHER(PIDTEMP, PIDTEMPBED) TERN_(DWIN_PID_TUNE, DWIN_StartM303(seenC, c, seenS, hid, temp));
if (seenC) HMI_data.PidCycles = c;
if (seenS) {
switch (hid) {
OPTCODE(PIDTEMP, case 0 ... HOTENDS - 1: HMI_data.HotendPidT = temp; break)
OPTCODE(PIDTEMPBED, case H_BED: HMI_data.BedPidT = temp; break)
default: break;
}
}
#endif
#if DISABLED(BUSY_WHILE_HEATING) IF_DISABLED(BUSY_WHILE_HEATING, KEEPALIVE_STATE(NOT_BUSY));
KEEPALIVE_STATE(NOT_BUSY);
#endif
LCD_MESSAGE(MSG_PID_AUTOTUNE); LCD_MESSAGE(MSG_PID_AUTOTUNE);
thermalManager.PID_autotune(temp, hid, c, u); thermalManager.PID_autotune(temp, hid, c, u);

View File

@@ -52,15 +52,15 @@ void GcodeSuite::M306() {
if (parser.seen("ACFPRH")) { if (parser.seen("ACFPRH")) {
const heater_id_t hid = (heater_id_t)parser.intval('E', 0); const heater_id_t hid = (heater_id_t)parser.intval('E', 0);
MPC_t &constants = thermalManager.temp_hotend[hid].constants; MPC_t &mpc = thermalManager.temp_hotend[hid].mpc;
if (parser.seenval('P')) constants.heater_power = parser.value_float(); if (parser.seenval('P')) mpc.heater_power = parser.value_float();
if (parser.seenval('C')) constants.block_heat_capacity = parser.value_float(); if (parser.seenval('C')) mpc.block_heat_capacity = parser.value_float();
if (parser.seenval('R')) constants.sensor_responsiveness = parser.value_float(); if (parser.seenval('R')) mpc.sensor_responsiveness = parser.value_float();
if (parser.seenval('A')) constants.ambient_xfer_coeff_fan0 = parser.value_float(); if (parser.seenval('A')) mpc.ambient_xfer_coeff_fan0 = parser.value_float();
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
if (parser.seenval('F')) constants.fan255_adjustment = parser.value_float() - constants.ambient_xfer_coeff_fan0; if (parser.seenval('F')) mpc.applyFanAdjustment(parser.value_float());
#endif #endif
if (parser.seenval('H')) constants.filament_heat_capacity_permm = parser.value_float(); if (parser.seenval('H')) mpc.filament_heat_capacity_permm = parser.value_float();
return; return;
} }
@@ -71,16 +71,16 @@ void GcodeSuite::M306_report(const bool forReplay/*=true*/) {
report_heading(forReplay, F("Model predictive control")); report_heading(forReplay, F("Model predictive control"));
HOTEND_LOOP() { HOTEND_LOOP() {
report_echo_start(forReplay); report_echo_start(forReplay);
MPC_t& constants = thermalManager.temp_hotend[e].constants; MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
SERIAL_ECHOPGM(" M306 E", e); SERIAL_ECHOPGM(" M306 E", e);
SERIAL_ECHOPAIR_F(" P", constants.heater_power, 2); SERIAL_ECHOPAIR_F(" P", mpc.heater_power, 2);
SERIAL_ECHOPAIR_F(" C", constants.block_heat_capacity, 2); SERIAL_ECHOPAIR_F(" C", mpc.block_heat_capacity, 2);
SERIAL_ECHOPAIR_F(" R", constants.sensor_responsiveness, 4); SERIAL_ECHOPAIR_F(" R", mpc.sensor_responsiveness, 4);
SERIAL_ECHOPAIR_F(" A", constants.ambient_xfer_coeff_fan0, 4); SERIAL_ECHOPAIR_F(" A", mpc.ambient_xfer_coeff_fan0, 4);
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
SERIAL_ECHOPAIR_F(" F", constants.ambient_xfer_coeff_fan0 + constants.fan255_adjustment, 4); SERIAL_ECHOPAIR_F(" F", mpc.fanCoefficient(), 4);
#endif #endif
SERIAL_ECHOPAIR_F(" H", constants.filament_heat_capacity_permm, 4); SERIAL_ECHOPAIR_F(" H", mpc.filament_heat_capacity_permm, 4);
SERIAL_EOL(); SERIAL_EOL();
} }
} }

View File

@@ -2504,6 +2504,9 @@
// PID heating // PID heating
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER) #if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
#define HAS_PID_HEATING 1 #define HAS_PID_HEATING 1
#if ENABLED(DWIN_LCD_PROUI) && EITHER(PIDTEMP, PIDTEMPBED)
#define DWIN_PID_TUNE 1
#endif
#endif #endif
// Thermal protection // Thermal protection

View File

@@ -1500,7 +1500,8 @@ void DWIN_LevelingDone() {
// PID process // PID process
#if HAS_PIDPLOT #if BOTH(HAS_PIDPLOT, DWIN_PID_TUNE)
void DWIN_Draw_PIDPopup() { void DWIN_Draw_PIDPopup() {
frame_rect_t gfrm = { 40, 180, DWIN_WIDTH - 80, 120 }; frame_rect_t gfrm = { 40, 180, DWIN_WIDTH - 80, 120 };
DWINUI::ClearMainArea(); DWINUI::ClearMainArea();
@@ -1525,9 +1526,21 @@ void DWIN_LevelingDone() {
default: break; default: break;
} }
} }
#endif #endif
#if EITHER(PIDTEMP, PIDTEMPBED) #if DWIN_PID_TUNE
void DWIN_StartM303(const bool seenC, const int c, const bool seenS, const heater_id_t hid, const celsius_t temp) {
if (seenC) HMI_data.PidCycles = c;
if (seenS) {
switch (hid) {
OPTCODE(PIDTEMP, case 0 ... HOTENDS - 1: HMI_data.HotendPidT = temp; break)
OPTCODE(PIDTEMPBED, case H_BED: HMI_data.BedPidT = temp; break)
default: break;
}
}
}
void DWIN_PidTuning(pidresult_t result) { void DWIN_PidTuning(pidresult_t result) {
HMI_value.pidresult = result; HMI_value.pidresult = result;
@@ -1541,9 +1554,9 @@ void DWIN_LevelingDone() {
DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for Nozzle is running.")); DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for Nozzle is running."));
#endif #endif
break; break;
case PID_BAD_EXTRUDER_NUM: case PID_BAD_HEATER_ID:
checkkey = last_checkkey; checkkey = last_checkkey;
DWIN_Popup_Confirm(ICON_TempTooLow, GET_TEXT_F(MSG_PID_AUTOTUNE_FAILED), GET_TEXT_F(MSG_BAD_EXTRUDER_NUM)); DWIN_Popup_Confirm(ICON_TempTooLow, GET_TEXT_F(MSG_PID_AUTOTUNE_FAILED), GET_TEXT_F(MSG_BAD_HEATER_ID));
break; break;
#endif #endif
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
@@ -1568,11 +1581,13 @@ void DWIN_LevelingDone() {
checkkey = last_checkkey; checkkey = last_checkkey;
DWIN_Popup_Confirm(ICON_TempTooLow, GET_TEXT_F(MSG_PID_AUTOTUNE), GET_TEXT_F(MSG_BUTTON_DONE)); DWIN_Popup_Confirm(ICON_TempTooLow, GET_TEXT_F(MSG_PID_AUTOTUNE), GET_TEXT_F(MSG_BUTTON_DONE));
break; break;
default: checkkey = last_checkkey; break; default:
checkkey = last_checkkey;
break;
} }
} }
#endif // PIDTEMP || PIDTEMPBED #endif // DWIN_PID_TUNE
// Started a Print Job // Started a Print Job
void DWIN_Print_Started() { void DWIN_Print_Started() {
@@ -1667,7 +1682,7 @@ void DWIN_SetDataDefaults() {
DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color); DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color);
TERN_(PIDTEMP, HMI_data.HotendPidT = DEF_HOTENDPIDT); TERN_(PIDTEMP, HMI_data.HotendPidT = DEF_HOTENDPIDT);
TERN_(PIDTEMPBED, HMI_data.BedPidT = DEF_BEDPIDT); TERN_(PIDTEMPBED, HMI_data.BedPidT = DEF_BEDPIDT);
TERN_(HAS_PID_HEATING, HMI_data.PidCycles = DEF_PIDCYCLES); TERN_(DWIN_PID_TUNE, HMI_data.PidCycles = DEF_PIDCYCLES);
#if ENABLED(PREVENT_COLD_EXTRUSION) #if ENABLED(PREVENT_COLD_EXTRUSION)
HMI_data.ExtMinT = EXTRUDE_MINTEMP; HMI_data.ExtMinT = EXTRUDE_MINTEMP;
ApplyExtMinT(); ApplyExtMinT();
@@ -2057,7 +2072,7 @@ void SetMoveZ() { HMI_value.axis = Z_AXIS; SetPFloatOnClick(Z_MIN_POS, Z_MAX_POS
} }
#endif #endif
#if EITHER(PIDTEMP, PIDTEMPBED) #if DWIN_PID_TUNE
void SetPID(celsius_t t, heater_id_t h) { void SetPID(celsius_t t, heater_id_t h) {
char cmd[53] = ""; char cmd[53] = "";
char str_1[5] = "", str_2[5] = ""; char str_1[5] = "", str_2[5] = "";
@@ -2523,7 +2538,7 @@ void SetStepsZ() { HMI_value.axis = Z_AXIS, SetPFloatOnClick( MIN_STEP, MAX_STEP
void SetBedPidT() { SetPIntOnClick(MIN_BEDTEMP, MAX_BEDTEMP); } void SetBedPidT() { SetPIntOnClick(MIN_BEDTEMP, MAX_BEDTEMP); }
#endif #endif
#if EITHER(PIDTEMP, PIDTEMPBED) #if DWIN_PID_TUNE
void SetPidCycles() { SetPIntOnClick(3, 50); } void SetPidCycles() { SetPIntOnClick(3, 50); }
void SetKp() { SetPFloatOnClick(0, 1000, 2); } void SetKp() { SetPFloatOnClick(0, 1000, 2); }
void ApplyPIDi() { void ApplyPIDi() {
@@ -2694,7 +2709,7 @@ void onDrawGetColorItem(MenuItemClass* menuitem, int8_t line) {
DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240); DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240);
} }
#if EITHER(PIDTEMP, PIDTEMPBED) #if DWIN_PID_TUNE
void onDrawPIDi(MenuItemClass* menuitem, int8_t line) { onDrawFloatMenu(menuitem, line, 2, unscalePID_i(*(float*)static_cast<MenuItemPtrClass*>(menuitem)->value)); } void onDrawPIDi(MenuItemClass* menuitem, int8_t line) { onDrawFloatMenu(menuitem, line, 2, unscalePID_i(*(float*)static_cast<MenuItemPtrClass*>(menuitem)->value)); }
void onDrawPIDd(MenuItemClass* menuitem, int8_t line) { onDrawFloatMenu(menuitem, line, 2, unscalePID_d(*(float*)static_cast<MenuItemPtrClass*>(menuitem)->value)); } void onDrawPIDd(MenuItemClass* menuitem, int8_t line) { onDrawFloatMenu(menuitem, line, 2, unscalePID_d(*(float*)static_cast<MenuItemPtrClass*>(menuitem)->value)); }
#endif #endif

View File

@@ -76,7 +76,7 @@ enum processID : uint8_t {
enum pidresult_t : uint8_t { enum pidresult_t : uint8_t {
PIDTEMP_START = 0, PIDTEMP_START = 0,
PIDTEMPBED_START, PIDTEMPBED_START,
PID_BAD_EXTRUDER_NUM, PID_BAD_HEATER_ID,
PID_TEMP_TOO_HIGH, PID_TEMP_TOO_HIGH,
PID_TUNING_TIMEOUT, PID_TUNING_TIMEOUT,
PID_DONE, PID_DONE,
@@ -107,14 +107,14 @@ typedef struct {
uint16_t Coordinate_Color; uint16_t Coordinate_Color;
// Temperatures // Temperatures
#if DWIN_PID_TUNE
int16_t PidCycles = DEF_PIDCYCLES;
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
int16_t HotendPidT = DEF_HOTENDPIDT; int16_t HotendPidT = DEF_HOTENDPIDT;
#endif #endif
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
int16_t BedPidT = DEF_BEDPIDT; int16_t BedPidT = DEF_BEDPIDT;
#endif #endif
#if (HAS_HOTEND || HAS_HEATED_BED) && HAS_PID_HEATING
int16_t PidCycles = DEF_PIDCYCLES;
#endif #endif
#if ENABLED(PREVENT_COLD_EXTRUSION) #if ENABLED(PREVENT_COLD_EXTRUSION)
int16_t ExtMinT = EXTRUDE_MINTEMP; int16_t ExtMinT = EXTRUDE_MINTEMP;
@@ -141,8 +141,8 @@ static constexpr size_t eeprom_data_size = sizeof(HMI_data_t);
typedef struct { typedef struct {
int8_t Color[3]; // Color components int8_t Color[3]; // Color components
#if HAS_PID_HEATING #if DWIN_PID_TUNE
tempcontrol_t pidresult = PID_DONE; pidresult_t pidresult = PID_DONE;
#endif #endif
uint8_t Select = 0; // Auxiliary selector variable uint8_t Select = 0; // Auxiliary selector variable
AxisEnum axis = X_AXIS; // Axis Select AxisEnum axis = X_AXIS; // Axis Select
@@ -358,8 +358,10 @@ void Draw_Steps_Menu();
#endif #endif
// PID // PID
#if HAS_PID_HEATING #if DWIN_PID_TUNE
void DWIN_PidTuning(tempcontrol_t result); #include "../../../module/temperature.h"
void DWIN_StartM303(const bool seenC, const int c, const bool seenS, const heater_id_t hid, const celsius_t temp);
void DWIN_PidTuning(pidresult_t result);
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
void Draw_HotendPID_Menu(); void Draw_HotendPID_Menu();
#endif #endif
@@ -367,4 +369,3 @@ void Draw_Steps_Menu();
void Draw_BedPID_Menu(); void Draw_BedPID_Menu();
#endif #endif
#endif #endif
#endif

View File

@@ -74,7 +74,7 @@ void PlotClass::Draw(const frame_rect_t frame, const float max, const float ref)
DWIN_Draw_HLine(Color_Red, frame.x, r, frame.w); DWIN_Draw_HLine(Color_Red, frame.x, r, frame.w);
} }
void PlotClass::Update(const float value) { void PlotClass::Update(const_float_t value) {
if (!scale) return; if (!scale) return;
uint16_t y = round((y2) - value * scale); uint16_t y = round((y2) - value * scale);
if (grphpoints < grphframe.w) { if (grphpoints < grphframe.w) {

View File

@@ -48,7 +48,7 @@
class PlotClass { class PlotClass {
public: public:
void Draw(frame_rect_t frame, float max, float ref = 0); void Draw(frame_rect_t frame, float max, float ref = 0);
void Update(float value); void Update(const_float_t value);
}; };
extern PlotClass Plot; extern PlotClass Plot;

View File

@@ -295,11 +295,11 @@ void DGUSScreenHandler::DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variable &var)
// Don't let the user in the dark why there is no reaction. // Don't let the user in the dark why there is no reaction.
if (!ExtUI::isMediaInserted()) { if (!ExtUI::isMediaInserted()) {
setstatusmessagePGM(GET_TEXT(MSG_NO_MEDIA)); setstatusmessage(GET_TEXT_F(MSG_NO_MEDIA));
return; return;
} }
if (card.flag.abort_sd_printing) { if (card.flag.abort_sd_printing) {
setstatusmessagePGM(GET_TEXT(MSG_MEDIA_ABORTING)); setstatusmessage(GET_TEXT_F(MSG_MEDIA_ABORTING));
return; return;
} }
} }

View File

@@ -51,6 +51,7 @@ public:
static void setstatusmessage(const char *msg); static void setstatusmessage(const char *msg);
// The same for messages from Flash // The same for messages from Flash
static void setstatusmessagePGM(PGM_P const msg); static void setstatusmessagePGM(PGM_P const msg);
static void setstatusmessage(FSTR_P const fmsg) { setstatusmessagePGM(FTOP(fmsg)); }
// Callback for VP "Display wants to change screen on idle printer" // Callback for VP "Display wants to change screen on idle printer"
static void ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr); static void ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr);
// Callback for VP "Screen has been changed" // Callback for VP "Screen has been changed"

View File

@@ -137,19 +137,19 @@ namespace ExtUI {
// Called for temperature PID tuning result // Called for temperature PID tuning result
switch (rst) { switch (rst) {
case PID_STARTED: case PID_STARTED:
ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_AUTOTUNE)); ScreenHandler.setstatusmessage(GET_TEXT_F(MSG_PID_AUTOTUNE));
break; break;
case PID_BAD_EXTRUDER_NUM: case PID_BAD_HEATER_ID:
ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_BAD_EXTRUDER_NUM)); ScreenHandler.setstatusmessage(GET_TEXT_F(MSG_PID_BAD_HEATER_ID));
break; break;
case PID_TEMP_TOO_HIGH: case PID_TEMP_TOO_HIGH:
ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_TEMP_TOO_HIGH)); ScreenHandler.setstatusmessage(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH));
break; break;
case PID_TUNING_TIMEOUT: case PID_TUNING_TIMEOUT:
ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_TIMEOUT)); ScreenHandler.setstatusmessage(GET_TEXT_F(MSG_PID_TIMEOUT));
break; break;
case PID_DONE: case PID_DONE:
ScreenHandler.setstatusmessagePGM(GET_TEXT(MSG_PID_AUTOTUNE_DONE)); ScreenHandler.setstatusmessage(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE));
break; break;
} }
ScreenHandler.GotoScreen(DGUSLCD_SCREEN_MAIN); ScreenHandler.GotoScreen(DGUSLCD_SCREEN_MAIN);

View File

@@ -325,8 +325,8 @@ void DGUSScreenHandler::FilamentRunout(const ExtUI::extruder_t extruder) {
case ExtUI::PID_STARTED: case ExtUI::PID_STARTED:
SetStatusMessage(GET_TEXT_F(MSG_PID_AUTOTUNE)); SetStatusMessage(GET_TEXT_F(MSG_PID_AUTOTUNE));
break; break;
case ExtUI::PID_BAD_EXTRUDER_NUM: case ExtUI::PID_BAD_HEATER_ID:
SetStatusMessage(GET_TEXT_F(MSG_PID_BAD_EXTRUDER_NUM)); SetStatusMessage(GET_TEXT_F(MSG_PID_BAD_HEATER_ID));
break; break;
case ExtUI::PID_TEMP_TOO_HIGH: case ExtUI::PID_TEMP_TOO_HIGH:
SetStatusMessage(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)); SetStatusMessage(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH));

View File

@@ -122,7 +122,7 @@ namespace ExtUI {
// Called for temperature PID tuning result // Called for temperature PID tuning result
switch (rst) { switch (rst) {
case PID_STARTED: break; case PID_STARTED: break;
case PID_BAD_EXTRUDER_NUM: break; case PID_BAD_HEATER_ID: break;
case PID_TEMP_TOO_HIGH: break; case PID_TEMP_TOO_HIGH: break;
case PID_TUNING_TIMEOUT: break; case PID_TUNING_TIMEOUT: break;
case PID_DONE: break; case PID_DONE: break;

View File

@@ -136,8 +136,8 @@ namespace ExtUI {
case PID_STARTED: case PID_STARTED:
StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_AUTOTUNE)); StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_AUTOTUNE));
break; break;
case PID_BAD_EXTRUDER_NUM: case PID_BAD_HEATER_ID:
StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_BAD_EXTRUDER_NUM)); StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_BAD_HEATER_ID));
break; break;
case PID_TEMP_TOO_HIGH: case PID_TEMP_TOO_HIGH:
StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)); StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH));

View File

@@ -111,8 +111,8 @@ namespace ExtUI {
case PID_STARTED: case PID_STARTED:
set_lcd_error(GET_TEXT_F(MSG_PID_AUTOTUNE)); set_lcd_error(GET_TEXT_F(MSG_PID_AUTOTUNE));
break; break;
case PID_BAD_EXTRUDER_NUM: case PID_BAD_HEATER_ID:
set_lcd_error(GET_TEXT_F(MSG_PID_BAD_EXTRUDER_NUM)); set_lcd_error(GET_TEXT_F(MSG_PID_BAD_HEATER_ID));
break; break;
case PID_TEMP_TOO_HIGH: case PID_TEMP_TOO_HIGH:
set_lcd_error(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)); set_lcd_error(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH));

View File

@@ -61,7 +61,7 @@ namespace ExtUI {
enum extruder_t : uint8_t { E0, E1, E2, E3, E4, E5, E6, E7 }; enum extruder_t : uint8_t { E0, E1, E2, E3, E4, E5, E6, E7 };
enum heater_t : uint8_t { H0, H1, H2, H3, H4, H5, BED, CHAMBER, COOLER }; enum heater_t : uint8_t { H0, H1, H2, H3, H4, H5, BED, CHAMBER, COOLER };
enum fan_t : uint8_t { FAN0, FAN1, FAN2, FAN3, FAN4, FAN5, FAN6, FAN7 }; enum fan_t : uint8_t { FAN0, FAN1, FAN2, FAN3, FAN4, FAN5, FAN6, FAN7 };
enum result_t : uint8_t { PID_STARTED, PID_BAD_EXTRUDER_NUM, PID_TEMP_TOO_HIGH, PID_TUNING_TIMEOUT, PID_DONE }; enum result_t : uint8_t { PID_STARTED, PID_BAD_HEATER_ID, PID_TEMP_TOO_HIGH, PID_TUNING_TIMEOUT, PID_DONE };
constexpr uint8_t extruderCount = EXTRUDERS; constexpr uint8_t extruderCount = EXTRUDERS;
constexpr uint8_t hotendCount = HOTENDS; constexpr uint8_t hotendCount = HOTENDS;

View File

@@ -343,10 +343,10 @@ namespace Language_de {
LSTR MSG_PID_CYCLE = _UxGT("PID Zyklus"); LSTR MSG_PID_CYCLE = _UxGT("PID Zyklus");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID Tuning fertig"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID Tuning fertig");
LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("PID Autotune fehlge.!"); LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("PID Autotune fehlge.!");
LSTR MSG_BAD_EXTRUDER_NUM = _UxGT("ungültiger Extruder."); LSTR MSG_BAD_HEATER_ID = _UxGT("ungültiger Extruder.");
LSTR MSG_TEMP_TOO_HIGH = _UxGT("Temperatur zu hoch."); LSTR MSG_TEMP_TOO_HIGH = _UxGT("Temperatur zu hoch.");
LSTR MSG_TIMEOUT = _UxGT("Timeout."); LSTR MSG_TIMEOUT = _UxGT("Timeout.");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune fehlge.! Ungültiger Extruder"); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Autotune fehlge.! Ungültiger Extruder");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune fehlge.! Temperatur zu hoch."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune fehlge.! Temperatur zu hoch.");
LSTR MSG_PID_TIMEOUT = _UxGT("Autotune fehlge.! Timeout."); LSTR MSG_PID_TIMEOUT = _UxGT("Autotune fehlge.! Timeout.");
LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("teste Wärmeverlust"); LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("teste Wärmeverlust");

View File

@@ -107,6 +107,7 @@ namespace Language_en {
LSTR MSG_HOME_OFFSET_Y = _UxGT("Home Offset Y"); LSTR MSG_HOME_OFFSET_Y = _UxGT("Home Offset Y");
LSTR MSG_HOME_OFFSET_Z = _UxGT("Home Offset Z"); LSTR MSG_HOME_OFFSET_Z = _UxGT("Home Offset Z");
LSTR MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsets Applied"); LSTR MSG_HOME_OFFSETS_APPLIED = _UxGT("Offsets Applied");
LSTR MSG_ERR_M428_TOO_FAR = _UxGT("Err: Too far!");
LSTR MSG_TRAMMING_WIZARD = _UxGT("Tramming Wizard"); LSTR MSG_TRAMMING_WIZARD = _UxGT("Tramming Wizard");
LSTR MSG_SELECT_ORIGIN = _UxGT("Select Origin"); LSTR MSG_SELECT_ORIGIN = _UxGT("Select Origin");
LSTR MSG_LAST_VALUE_SP = _UxGT("Last value "); LSTR MSG_LAST_VALUE_SP = _UxGT("Last value ");
@@ -364,20 +365,22 @@ namespace Language_en {
LSTR MSG_PID_CYCLE = _UxGT("PID Cycles"); LSTR MSG_PID_CYCLE = _UxGT("PID Cycles");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done");
LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("PID Autotune failed!"); LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("PID Autotune failed!");
LSTR MSG_BAD_EXTRUDER_NUM = _UxGT("Bad extruder."); LSTR MSG_BAD_HEATER_ID = _UxGT("Bad extruder.");
LSTR MSG_TEMP_TOO_HIGH = _UxGT("Temperature too high."); LSTR MSG_TEMP_TOO_HIGH = _UxGT("Temperature too high.");
LSTR MSG_TIMEOUT = _UxGT("Timeout."); LSTR MSG_TIMEOUT = _UxGT("Timeout.");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune failed! Bad extruder."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Autotune failed! Bad extruder.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed! Temperature too high."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed! Temperature too high.");
LSTR MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout."); LSTR MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout.");
LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Testing heat loss"); LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Testing heat loss");
LSTR MSG_MPC_HEATING_PAST_200 = _UxGT("Heating to >200C");
LSTR MSG_MPC_COOLING_TO_AMBIENT = _UxGT("Cooling to ambient");
LSTR MSG_MPC_AUTOTUNE = _UxGT("MPC Autotune"); LSTR MSG_MPC_AUTOTUNE = _UxGT("MPC Autotune");
LSTR MSG_MPC_EDIT = _UxGT("Edit * MPC"); LSTR MSG_MPC_EDIT = _UxGT("Edit * MPC");
LSTR MSG_MPC_POWER_E = _UxGT("Power *"); LSTR MSG_MPC_POWER_E = _UxGT("Power *");
LSTR MSG_MPC_BLOCK_HEAT_CAPACITY_E = _UxGT("Block C *"); LSTR MSG_MPC_BLOCK_HEAT_CAPACITY_E = _UxGT("Heat Cap. *");
LSTR MSG_SENSOR_RESPONSIVENESS_E = _UxGT("Sensor res *"); LSTR MSG_SENSOR_RESPONSIVENESS_E = _UxGT("Sensor Resp. *");
LSTR MSG_MPC_AMBIENT_XFER_COEFF_E = _UxGT("Ambient h *"); LSTR MSG_MPC_AMBIENT_XFER_COEFF_E = _UxGT("Ambient Co. *");
LSTR MSG_MPC_AMBIENT_XFER_COEFF_FAN_E = _UxGT("Amb. h fan *"); LSTR MSG_MPC_AMBIENT_XFER_COEFF_FAN_E = _UxGT("Fan coeff. *");
LSTR MSG_SELECT_E = _UxGT("Select *"); LSTR MSG_SELECT_E = _UxGT("Select *");
LSTR MSG_ACC = _UxGT("Accel"); LSTR MSG_ACC = _UxGT("Accel");
LSTR MSG_JERK = _UxGT("Jerk"); LSTR MSG_JERK = _UxGT("Jerk");

View File

@@ -269,7 +269,7 @@ namespace Language_fr {
LSTR MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); LSTR MSG_PID_AUTOTUNE = _UxGT("PID Autotune");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Tuning PID terminé"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Tuning PID terminé");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Echec Autotune! E incorrect"); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Echec Autotune! E incorrect");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Echec Autotune! Temp. trop haute"); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Echec Autotune! Temp. trop haute");
LSTR MSG_PID_TIMEOUT = _UxGT("Echec Autotune! Opér. expirée"); LSTR MSG_PID_TIMEOUT = _UxGT("Echec Autotune! Opér. expirée");
LSTR MSG_SELECT_E = _UxGT("Sélectionner *"); LSTR MSG_SELECT_E = _UxGT("Sélectionner *");

View File

@@ -263,7 +263,7 @@ namespace Language_gl {
LSTR MSG_PID_AUTOTUNE = _UxGT("Auto-Sint. PID"); LSTR MSG_PID_AUTOTUNE = _UxGT("Auto-Sint. PID");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("Auto-Sint. PID *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("Auto-Sint. PID *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Fin Auto-Sint PID"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Fin Auto-Sint PID");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Auto-Sint. fallida! Extrusor danado."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Auto-Sint. fallida! Extrusor danado.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Auto-Sint. fallida! Temperatura moi alta."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Auto-Sint. fallida! Temperatura moi alta.");
LSTR MSG_PID_TIMEOUT = _UxGT("Auto-Sint. fallida! Tempo excedido."); LSTR MSG_PID_TIMEOUT = _UxGT("Auto-Sint. fallida! Tempo excedido.");
LSTR MSG_SELECT_E = _UxGT("Escolla *"); LSTR MSG_SELECT_E = _UxGT("Escolla *");

View File

@@ -306,7 +306,7 @@ namespace Language_hu {
LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID hangolás *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID hangolás *");
LSTR MSG_PID_CYCLE = _UxGT("PID ciklus"); LSTR MSG_PID_CYCLE = _UxGT("PID ciklus");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID hangolás kész"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID hangolás kész");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Hangolási hiba! Rossz adagoló."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Hangolási hiba! Rossz adagoló.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Hangolási hiba! Magas hömérséklet."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Hangolási hiba! Magas hömérséklet.");
LSTR MSG_PID_TIMEOUT = _UxGT("Hangolási hiba! Idötúllépés."); LSTR MSG_PID_TIMEOUT = _UxGT("Hangolási hiba! Idötúllépés.");
LSTR MSG_SELECT_E = _UxGT("Kiválaszt *"); LSTR MSG_SELECT_E = _UxGT("Kiválaszt *");

View File

@@ -356,10 +356,10 @@ namespace Language_it {
LSTR MSG_PID_CYCLE = _UxGT("Ciclo PID"); LSTR MSG_PID_CYCLE = _UxGT("Ciclo PID");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Calibr.PID eseguita"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Calibr.PID eseguita");
LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("Calibr.PID fallito!"); LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("Calibr.PID fallito!");
LSTR MSG_BAD_EXTRUDER_NUM = _UxGT("Estrusore invalido."); LSTR MSG_BAD_HEATER_ID = _UxGT("Estrusore invalido.");
LSTR MSG_TEMP_TOO_HIGH = _UxGT("Temp.troppo alta."); LSTR MSG_TEMP_TOO_HIGH = _UxGT("Temp.troppo alta.");
LSTR MSG_TIMEOUT = _UxGT("Tempo scaduto."); LSTR MSG_TIMEOUT = _UxGT("Tempo scaduto.");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Calibrazione fallita! Estrusore errato."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Calibrazione fallita! Estrusore errato.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Calibrazione fallita! Temperatura troppo alta."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Calibrazione fallita! Temperatura troppo alta.");
LSTR MSG_PID_TIMEOUT = _UxGT("Calibrazione fallita! Tempo scaduto."); LSTR MSG_PID_TIMEOUT = _UxGT("Calibrazione fallita! Tempo scaduto.");
LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Testing heat loss"); LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Testing heat loss");

View File

@@ -261,7 +261,7 @@ namespace Language_ro {
LSTR MSG_PID_AUTOTUNE = _UxGT("PID Autotune"); LSTR MSG_PID_AUTOTUNE = _UxGT("PID Autotune");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID Autotune *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autotune failed! Bad extruder."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Autotune failed! Bad extruder.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed! Temperature too high."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autotune failed! Temperature too high.");
LSTR MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout."); LSTR MSG_PID_TIMEOUT = _UxGT("Autotune failed! Timeout.");
LSTR MSG_SELECT_E = _UxGT("Select *"); LSTR MSG_SELECT_E = _UxGT("Select *");

View File

@@ -382,7 +382,7 @@ namespace Language_ru {
LSTR MSG_PID_AUTOTUNE = _UxGT("Автоподбор PID"); LSTR MSG_PID_AUTOTUNE = _UxGT("Автоподбор PID");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("Автоподбор PID *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("Автоподбор PID *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Подбор PID выполнен"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Подбор PID выполнен");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Сбой автоподбора! Плохой экструдер."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Сбой автоподбора! Плохой экструдер.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Сбой автоподбора! Температура повышена."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Сбой автоподбора! Температура повышена.");
LSTR MSG_PID_TIMEOUT = _UxGT("Сбой автоподбора! Завершение времени."); LSTR MSG_PID_TIMEOUT = _UxGT("Сбой автоподбора! Завершение времени.");

View File

@@ -354,10 +354,10 @@ namespace Language_sk {
LSTR MSG_PID_CYCLE = _UxGT("Cykly PID"); LSTR MSG_PID_CYCLE = _UxGT("Cykly PID");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Kal. PID dokončená"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Kal. PID dokončená");
LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("Kal. PID zlyhala!"); LSTR MSG_PID_AUTOTUNE_FAILED = _UxGT("Kal. PID zlyhala!");
LSTR MSG_BAD_EXTRUDER_NUM = _UxGT("Zlý extrudér"); LSTR MSG_BAD_HEATER_ID = _UxGT("Zlý extrudér");
LSTR MSG_TEMP_TOO_HIGH = _UxGT("Príliš vysoká tepl."); LSTR MSG_TEMP_TOO_HIGH = _UxGT("Príliš vysoká tepl.");
LSTR MSG_TIMEOUT = _UxGT("Čas vypršal."); LSTR MSG_TIMEOUT = _UxGT("Čas vypršal.");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Auto-kal. zlyhala! Zlý extrúder."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Auto-kal. zlyhala! Zlý extrúder.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Auto-kal. zlyhala! Príliš vysoká tepl."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Auto-kal. zlyhala! Príliš vysoká tepl.");
LSTR MSG_PID_TIMEOUT = _UxGT("Auto-kal. zlyhala! Čas vypršal."); LSTR MSG_PID_TIMEOUT = _UxGT("Auto-kal. zlyhala! Čas vypršal.");
LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Test. tepl. straty"); LSTR MSG_MPC_MEASURING_AMBIENT = _UxGT("Test. tepl. straty");

View File

@@ -291,7 +291,7 @@ namespace Language_sv {
LSTR MSG_PID_AUTOTUNE = _UxGT("PID Autojustera"); LSTR MSG_PID_AUTOTUNE = _UxGT("PID Autojustera");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID Autojustera *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("PID Autojustera *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID tuning done");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Autojustera misslyckad! Dålig extruder."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Autojustera misslyckad! Dålig extruder.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autojustera misslyckad! Temperatur för hög."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Autojustera misslyckad! Temperatur för hög.");
LSTR MSG_PID_TIMEOUT = _UxGT("Autojustera misslyckad! Tidsgräns."); LSTR MSG_PID_TIMEOUT = _UxGT("Autojustera misslyckad! Tidsgräns.");
LSTR MSG_SELECT_E = _UxGT("Välj *"); LSTR MSG_SELECT_E = _UxGT("Välj *");

View File

@@ -387,7 +387,7 @@ namespace Language_uk {
LSTR MSG_PID_AUTOTUNE = _UxGT("Автопідбір PID"); LSTR MSG_PID_AUTOTUNE = _UxGT("Автопідбір PID");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("Автопідбір PID *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("Автопідбір PID *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Підбір PID виконано"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("Підбір PID виконано");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("Збій автопідбору! Поганий екструдер."); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("Збій автопідбору! Поганий екструдер.");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Збій автопідбору! Температура завищена."); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("Збій автопідбору! Температура завищена.");
LSTR MSG_PID_TIMEOUT = _UxGT("Збій автопідбору! Вичерпан час."); LSTR MSG_PID_TIMEOUT = _UxGT("Збій автопідбору! Вичерпан час.");

View File

@@ -261,7 +261,7 @@ namespace Language_zh_CN {
LSTR MSG_PID_AUTOTUNE = _UxGT("自动PID"); LSTR MSG_PID_AUTOTUNE = _UxGT("自动PID");
LSTR MSG_PID_AUTOTUNE_E = _UxGT("自动PID *"); LSTR MSG_PID_AUTOTUNE_E = _UxGT("自动PID *");
LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID调整完成"); LSTR MSG_PID_AUTOTUNE_DONE = _UxGT("PID调整完成");
LSTR MSG_PID_BAD_EXTRUDER_NUM = _UxGT("自动调失败! 坏的挤出机"); LSTR MSG_PID_BAD_HEATER_ID = _UxGT("自动调失败! 坏的挤出机");
LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("自动调失败! 温度太高"); LSTR MSG_PID_TEMP_TOO_HIGH = _UxGT("自动调失败! 温度太高");
LSTR MSG_PID_TIMEOUT = _UxGT("自动调失败! 超时"); LSTR MSG_PID_TIMEOUT = _UxGT("自动调失败! 超时");
LSTR MSG_SELECT_E = _UxGT("选择 *"); LSTR MSG_SELECT_E = _UxGT("选择 *");

View File

@@ -41,7 +41,7 @@
#include "../../module/probe.h" #include "../../module/probe.h"
#endif #endif
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER) #if HAS_PID_HEATING
#include "../../module/temperature.h" #include "../../module/temperature.h"
#endif #endif
@@ -277,10 +277,10 @@ void menu_backlash();
// //
#if SHOW_MENU_ADVANCED_TEMPERATURE #if SHOW_MENU_ADVANCED_TEMPERATURE
#if ENABLED(MPC_EDIT_MENU) #if BOTH(MPC_EDIT_MENU, MPC_INCLUDE_FAN)
#define MPC_EDIT_DEFS(N) \ #define MPC_EDIT_DEFS(N) editable.decimal = thermalManager.temp_hotend[N].fanCoefficient()
MPC_t &c = thermalManager.temp_hotend[N].constants; \ #else
TERN_(MPC_INCLUDE_FAN, editable.decimal = c.ambient_xfer_coeff_fan0 + c.fan255_adjustment) #define MPC_EDIT_DEFS(...)
#endif #endif
void menu_advanced_temperature() { void menu_advanced_temperature() {
@@ -370,17 +370,17 @@ void menu_backlash();
#if ENABLED(MPC_EDIT_MENU) #if ENABLED(MPC_EDIT_MENU)
#define _MPC_EDIT_ITEMS(N) \ #define _MPC_EDIT_ITEMS(N) \
EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_POWER_E, &c.heater_power, 1, 200); \ EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_POWER_E, &mpc.heater_power, 1, 200); \
EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_BLOCK_HEAT_CAPACITY_E, &c.block_heat_capacity, 0, 40); \ EDIT_ITEM_FAST_N(float31sign, N, MSG_MPC_BLOCK_HEAT_CAPACITY_E, &mpc.block_heat_capacity, 0, 40); \
EDIT_ITEM_FAST_N(float43, N, MSG_SENSOR_RESPONSIVENESS_E, &c.sensor_responsiveness, 0, 1); \ EDIT_ITEM_FAST_N(float43, N, MSG_SENSOR_RESPONSIVENESS_E, &mpc.sensor_responsiveness, 0, 1); \
EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_E, &c.ambient_xfer_coeff_fan0, 0, 1) EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_E, &mpc.ambient_xfer_coeff_fan0, 0, 1)
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
#define MPC_EDIT_ITEMS(N) \ #define MPC_EDIT_ITEMS(N) \
MPC_t &mpc = thermalManager.temp_hotend[MenuItemBase::itemIndex].constants; \
_MPC_EDIT_ITEMS(N); \ _MPC_EDIT_ITEMS(N); \
EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_FAN_E, &editable.decimal, 0, 1, []{ \ EDIT_ITEM_FAST_N(float43, N, MSG_MPC_AMBIENT_XFER_COEFF_FAN_E, &editable.decimal, 0, 1, []{ \
MPC_t &c = thermalManager.temp_hotend[MenuItemBase::itemIndex].constants; \ thermalManager.temp_hotend[MenuItemBase::itemIndex].applyFanAdjustment(editable.decimal); \
c.fan255_adjustment = editable.decimal - c.ambient_xfer_coeff_fan0; \
}) })
#else #else
#define MPC_EDIT_ITEMS _MPC_EDIT_ITEMS #define MPC_EDIT_ITEMS _MPC_EDIT_ITEMS

View File

@@ -1632,8 +1632,7 @@ void MarlinSettings::postprocess() {
// Model predictive control // Model predictive control
// //
#if ENABLED(MPCTEMP) #if ENABLED(MPCTEMP)
HOTEND_LOOP() HOTEND_LOOP() EEPROM_WRITE(thermalManager.temp_hotend[e].mpc);
EEPROM_WRITE(thermalManager.temp_hotend[e].constants);
#endif #endif
// //
@@ -2627,8 +2626,7 @@ void MarlinSettings::postprocess() {
// //
#if ENABLED(MPCTEMP) #if ENABLED(MPCTEMP)
{ {
HOTEND_LOOP() HOTEND_LOOP() EEPROM_READ(thermalManager.temp_hotend[e].mpc);
EEPROM_READ(thermalManager.temp_hotend[e].constants);
} }
#endif #endif
@@ -3416,15 +3414,15 @@ void MarlinSettings::reset() {
static_assert(COUNT(_filament_heat_capacity_permm) == HOTENDS, "FILAMENT_HEAT_CAPACITY_PERMM must have HOTENDS items."); static_assert(COUNT(_filament_heat_capacity_permm) == HOTENDS, "FILAMENT_HEAT_CAPACITY_PERMM must have HOTENDS items.");
HOTEND_LOOP() { HOTEND_LOOP() {
MPC_t &constants = thermalManager.temp_hotend[e].constants; MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
constants.heater_power = _mpc_heater_power[e]; mpc.heater_power = _mpc_heater_power[e];
constants.block_heat_capacity = _mpc_block_heat_capacity[e]; mpc.block_heat_capacity = _mpc_block_heat_capacity[e];
constants.sensor_responsiveness = _mpc_sensor_responsiveness[e]; mpc.sensor_responsiveness = _mpc_sensor_responsiveness[e];
constants.ambient_xfer_coeff_fan0 = _mpc_ambient_xfer_coeff[e]; mpc.ambient_xfer_coeff_fan0 = _mpc_ambient_xfer_coeff[e];
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
constants.fan255_adjustment = _mpc_ambient_xfer_coeff_fan255[e] - _mpc_ambient_xfer_coeff[e]; mpc.fan255_adjustment = _mpc_ambient_xfer_coeff_fan255[e] - _mpc_ambient_xfer_coeff[e];
#endif #endif
constants.filament_heat_capacity_permm = _filament_heat_capacity_permm[e]; mpc.filament_heat_capacity_permm = _filament_heat_capacity_permm[e];
} }
#endif #endif

View File

@@ -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_(HAS_FAN_LOGIC, fan_update_ms = next_temp_ms + fan_update_interval_ms);
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_STARTED)); 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))) { if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, temp_range[heater_id].maxtemp - (HOTEND_OVERSHOOT))) {
SERIAL_ECHOPGM(STR_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_PID_TUNE, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH))); TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)));
return; return;
} }
@@ -760,7 +760,7 @@ volatile bool Temperature::raw_temps_ready = false;
SERIAL_ECHOPGM(STR_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_PID_TUNE, DWIN_PidTuning(PID_TEMP_TOO_HIGH));
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH))); TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)));
break; break;
} }
@@ -797,7 +797,7 @@ volatile bool Temperature::raw_temps_ready = false;
#endif #endif
if ((ms - _MIN(t1, t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) { if ((ms - _MIN(t1, t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) {
TERN_(DWIN_CREALITY_LCD, DWIN_Popup_Temperature(0)); 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_(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_ECHOPGM(STR_PID_AUTOTUNE);
@@ -852,7 +852,7 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color)); TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE)); 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; goto EXIT_M303;
} }
@@ -870,7 +870,7 @@ volatile bool Temperature::raw_temps_ready = false;
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color)); TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onPidTuningDone(color));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_DONE)); 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: EXIT_M303:
TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = true); TERN_(NO_FAN_SLOWING_IN_PID_TUNING, adaptive_fan_slowing = true);
@@ -929,7 +929,7 @@ volatile bool Temperature::raw_temps_ready = false;
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE); SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_START, active_extruder); SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_START, active_extruder);
MPCHeaterInfo &hotend = temp_hotend[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 // Move to center of bed, just above bed height and cool with max fan
gcode.home_all_axes(true); 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); set_fan_speed(EITHER(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);
#endif #endif
const xyz_pos_t tuningpos = MPC_TUNING_POS; do_blocking_move_to(xyz_pos_t(MPC_TUNING_POS));
do_blocking_move_to(tuningpos);
SERIAL_ECHOLNPGM(STR_MPC_COOLING_TO_AMBIENT); SERIAL_ECHOLNPGM(STR_MPC_COOLING_TO_AMBIENT);
LCD_MESSAGE(MSG_COOLING); LCD_MESSAGE(MSG_COOLING);
millis_t ms = millis(), next_report_ms = ms, next_test_ms = ms + 10000UL; millis_t ms = millis(), next_report_ms = ms, next_test_ms = ms + 10000UL;
celsius_float_t current_temp = degHotend(active_extruder), celsius_float_t current_temp = degHotend(active_extruder),
ambient_temp = current_temp; ambient_temp = current_temp;
@@ -961,6 +961,7 @@ volatile bool Temperature::raw_temps_ready = false;
next_test_ms += 10000UL; next_test_ms += 10000UL;
} }
} }
wait_for_heatup = false;
#if HAS_FAN #if HAS_FAN
set_fan_speed(EITHER(MPC_FAN_0_ALL_HOTENDS, MPC_FAN_0_ACTIVE_HOTEND) ? 0 : active_extruder, 0); 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; hotend.modeled_ambient_temp = ambient_temp;
SERIAL_ECHOLNPGM(STR_MPC_HEATING_PAST_200); 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.target = 200.0f; // So M105 looks nice
hotend.soft_pwm_amount = MPC_MAX >> 1; hotend.soft_pwm_amount = MPC_MAX >> 1;
const millis_t heat_start_time = next_test_ms = ms; 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), 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)); 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); mpc.ambient_xfer_coeff_fan0 = mpc.heater_power * (MPC_MAX) / 255 / (asymp_temp - ambient_temp);
constants.fan255_adjustment = 0.0f; mpc.fan255_adjustment = 0.0f;
constants.block_heat_capacity = constants.ambient_xfer_coeff_fan0 / block_responsiveness; mpc.block_heat_capacity = mpc.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.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_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;
// Allow the system to stabilize under MPC, then get a better measure of ambient loss with and without fan // 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); 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; 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, test_duration = 20000UL; 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; 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)) 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 #if HAS_FAN
else if (ELAPSED(ms, test_end_ms) && !fan0_done) { 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); 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; 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))
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 #endif
else if (ELAPSED(ms, test_end_ms)) break; 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; 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 #if HAS_FAN
const float power_fan255 = total_energy_fan255 * 1000 / test_duration, 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; mpc.applyFanAdjustment(ambient_xfer_coeff_fan255);
#endif #endif
// Calculate a new and better asymptotic temperature and re-evaluate the other constants // 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)); 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; mpc.block_heat_capacity = mpc.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.sensor_responsiveness = block_responsiveness / (1.0f - (ambient_temp - asymp_temp) * exp(-block_responsiveness * t1_time) / (t1 - asymp_temp));
SERIAL_ECHOPGM(STR_MPC_AUTOTUNE); SERIAL_ECHOPGM(STR_MPC_AUTOTUNE);
SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_FINISHED); SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_FINISHED);
/* <-- add a slash to enable #if 0
SERIAL_ECHOLNPGM("t1_time ", t1_time); SERIAL_ECHOLNPGM("t1_time ", t1_time);
SERIAL_ECHOLNPGM("sample_count ", sample_count); SERIAL_ECHOLNPGM("sample_count ", sample_count);
SERIAL_ECHOLNPGM("sample_distance ", sample_distance); 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("t1 ", t1, " t2 ", t2, " t3 ", t3);
SERIAL_ECHOLNPGM("asymp_temp ", asymp_temp); SERIAL_ECHOLNPGM("asymp_temp ", asymp_temp);
SERIAL_ECHOLNPAIR_F("block_responsiveness ", block_responsiveness, 4); SERIAL_ECHOLNPAIR_F("block_responsiveness ", block_responsiveness, 4);
//*/ #endif
SERIAL_ECHOLNPGM("MPC_BLOCK_HEAT_CAPACITY ", constants.block_heat_capacity);
SERIAL_ECHOLNPAIR_F("MPC_SENSOR_RESPONSIVENESS ", constants.sensor_responsiveness, 4); SERIAL_ECHOLNPGM("MPC_BLOCK_HEAT_CAPACITY ", mpc.block_heat_capacity);
SERIAL_ECHOLNPAIR_F("MPC_AMBIENT_XFER_COEFF ", constants.ambient_xfer_coeff_fan0, 4); 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)); 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) #elif ENABLED(MPCTEMP)
MPCHeaterInfo &hotend = temp_hotend[ee]; MPCHeaterInfo &hotend = temp_hotend[ee];
MPC_t &constants = hotend.constants; MPC_t &mpc = hotend.mpc;
// At startup, initialize modeled temperatures // At startup, initialize modeled temperatures
if (isnan(hotend.modeled_block_temp)) { 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); const bool this_hotend = (ee == active_extruder);
#endif #endif
float ambient_xfer_coeff = constants.ambient_xfer_coeff_fan0; float ambient_xfer_coeff = mpc.ambient_xfer_coeff_fan0;
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
const uint8_t fan_index = EITHER(MPC_FAN_0_ACTIVE_HOTEND, MPC_FAN_0_ALL_HOTENDS) ? 0 : ee; 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); 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 #endif
if (this_hotend) { 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]) if (fabs(e_speed) > planner.settings.max_feedrate_mm_s[E_AXIS])
mpc_e_position = e_position; mpc_e_position = e_position;
else if (e_speed > 0.0f) { // Ignore retract/recover moves 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; mpc_e_position = e_position;
} }
} }
// Update the modeled temperatures // Update the modeled temperatures
float blocktempdelta = hotend.soft_pwm_amount * constants.heater_power * (MPC_dT / 127) / 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 / constants.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; 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; hotend.modeled_sensor_temp += sensortempdelta;
// Any delta between hotend.modeled_sensor_temp and hotend.celsius is either model // 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; float power = 0.0;
if (hotend.target != 0 && !is_idling) { if (hotend.target != 0 && !is_idling) {
// Plan power level to get to target temperature in 2 seconds // 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; 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); pid_output = constrain(pid_output, 0, MPC_MAX);
/* <-- add a slash to enable /* <-- add a slash to enable

View File

@@ -382,10 +382,14 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t;
float block_heat_capacity; // M306 C float block_heat_capacity; // M306 C
float sensor_responsiveness; // M306 R float sensor_responsiveness; // M306 R
float ambient_xfer_coeff_fan0; // M306 A float ambient_xfer_coeff_fan0; // M306 A
float filament_heat_capacity_permm; // M306 H
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
float fan255_adjustment; // M306 F float fan255_adjustment; // M306 F
void applyFanAdjustment(const_float_t cf) { fan255_adjustment = cf - ambient_xfer_coeff_fan0; }
#else
void applyFanAdjustment(const_float_t) {}
#endif #endif
float filament_heat_capacity_permm; // M306 H float fanCoefficient() { return SUM_TERN(MPC_INCLUDE_FAN, ambient_xfer_coeff_fan0, fan255_adjustment); }
} MPC_t; } MPC_t;
#define MPC_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (TEMP_TIMER_FREQUENCY)) #define MPC_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (TEMP_TIMER_FREQUENCY))
@@ -433,10 +437,12 @@ struct PIDHeaterInfo : public HeaterInfo {
#if ENABLED(MPCTEMP) #if ENABLED(MPCTEMP)
struct MPCHeaterInfo : public HeaterInfo { struct MPCHeaterInfo : public HeaterInfo {
MPC_t constants; MPC_t mpc;
float modeled_ambient_temp, float modeled_ambient_temp,
modeled_block_temp, modeled_block_temp,
modeled_sensor_temp; modeled_sensor_temp;
float fanCoefficient() { return mpc.fanCoefficient(); }
void applyFanAdjustment(const_float_t cf) { mpc.applyFanAdjustment(cf); }
}; };
#endif #endif