diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 3208364c3c..1d7c1a7277 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1743,19 +1743,20 @@ */ //#define POWER_LOSS_RECOVERY #if ENABLED(POWER_LOSS_RECOVERY) - #define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) - //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss - //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS) - //#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module. - //#define POWER_LOSS_STATE HIGH // State of pin indicating power loss - //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor + #define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) + //#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable) + //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss + //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS) + //#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module. + //#define POWER_LOSS_STATE HIGH // State of pin indicating power loss + //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor //#define POWER_LOSS_PULLDOWN - //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume - //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power. + //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume + //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power. // Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card, // especially with "vase mode" printing. Set too high and vases cannot be continued. - #define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data + #define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data // Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled! //#define POWER_LOSS_RECOVER_ZHOME diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 5a25710084..ce34b3a95c 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -37,6 +37,10 @@ bool PrintJobRecovery::enabled; // Initialized by settings.load() +#if HAS_PLR_BED_THRESHOLD + celsius_t PrintJobRecovery::bed_temp_threshold; // Initialized by settings.load() +#endif + MediaFile PrintJobRecovery::file; job_recovery_info_t PrintJobRecovery::info; const char PrintJobRecovery::filename[5] = "/PLR"; diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index a69862b259..1fdc42db26 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -175,6 +175,10 @@ class PrintJobRecovery { static void enable(const bool onoff); static void changed(); + #if HAS_PLR_BED_THRESHOLD + static celsius_t bed_temp_threshold; + #endif + static bool exists() { return card.jobRecoverFileExists(); } static void open(const bool read) { card.openJobRecoveryFile(read); } static void close() { file.close(); } diff --git a/Marlin/src/gcode/feature/powerloss/M1000.cpp b/Marlin/src/gcode/feature/powerloss/M1000.cpp index 1a1ebd517b..033bcf4ebb 100644 --- a/Marlin/src/gcode/feature/powerloss/M1000.cpp +++ b/Marlin/src/gcode/feature/powerloss/M1000.cpp @@ -28,6 +28,10 @@ #include "../../../feature/powerloss.h" #include "../../../module/motion.h" +#if HAS_PLR_BED_THRESHOLD + #include "../../../module/temperature.h" // for degBed +#endif + #include "../../../lcd/marlinui.h" #if ENABLED(EXTENSIBLE_UI) #include "../../../lcd/extui/ui_api.h" @@ -60,12 +64,15 @@ inline void plr_error(FSTR_P const prefix) { /** * M1000: Resume from power-loss (undocumented) * - With 'S' go to the Resume/Cancel menu + * ...unless the bed temperature is already above a configured minimum temperature. * - With no parameters, run recovery commands */ void GcodeSuite::M1000() { if (recovery.valid()) { - if (parser.seen_test('S')) { + const bool force_resume = TERN0(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold && (thermalManager.degBed() >= recovery.bed_temp_threshold)); + + if (!force_resume && parser.seen_test('S')) { #if HAS_MARLINUI_MENU ui.goto_screen(menu_job_recovery); #elif HAS_DWIN_E3V2_BASIC diff --git a/Marlin/src/gcode/feature/powerloss/M413.cpp b/Marlin/src/gcode/feature/powerloss/M413.cpp index 5e508d4f28..8cbe468476 100644 --- a/Marlin/src/gcode/feature/powerloss/M413.cpp +++ b/Marlin/src/gcode/feature/powerloss/M413.cpp @@ -35,6 +35,9 @@ * Parameters * S[bool] - Flag to enable / disable. * If omitted, report current state. + * + * With PLR_BED_THRESHOLD: + * B Bed Temperature above which recovery will proceed without asking permission. */ void GcodeSuite::M413() { @@ -43,6 +46,11 @@ void GcodeSuite::M413() { else M413_report(); + #if HAS_PLR_BED_THRESHOLD + if (parser.seenval('B')) + recovery.bed_temp_threshold = parser.value_celsius(); + #endif + #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) if (parser.seen("RL")) recovery.load(); if (parser.seen_test('W')) recovery.save(true); @@ -57,7 +65,11 @@ void GcodeSuite::M413() { void GcodeSuite::M413_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F(STR_POWER_LOSS_RECOVERY)); - SERIAL_ECHOPGM(" M413 S", AS_DIGIT(recovery.enabled), " ; "); + SERIAL_ECHOPGM(" M413 S", AS_DIGIT(recovery.enabled) + #if HAS_PLR_BED_THRESHOLD + , " B", recovery.bed_temp_threshold + #endif + ); serialprintln_onoff(recovery.enabled); } diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index d535553ca9..20b357c9e3 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -1355,3 +1355,8 @@ #if DISABLED(INCH_MODE_SUPPORT) #undef MANUAL_MOVE_DISTANCE_IN #endif + +// Power-Loss Recovery +#if ENABLED(POWER_LOSS_RECOVERY) && defined(PLR_BED_THRESHOLD) + #define HAS_PLR_BED_THRESHOLD 1 +#endif diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h index 97d8183f52..553d9013a2 100644 --- a/Marlin/src/lcd/language/language_en.h +++ b/Marlin/src/lcd/language/language_en.h @@ -501,6 +501,7 @@ namespace LanguageNarrow_en { LSTR MSG_RESUME_PRINT = _UxGT("Resume Print"); LSTR MSG_STOP_PRINT = _UxGT("Stop Print"); LSTR MSG_OUTAGE_RECOVERY = _UxGT("Power Outage"); + LSTR MSG_RESUME_BED_TEMP = _UxGT("Resume Bed Temp"); LSTR MSG_HOST_START_PRINT = _UxGT("Host Start"); LSTR MSG_PRINTING_OBJECT = _UxGT("Print Obj"); LSTR MSG_CANCEL_OBJECT = _UxGT("Cancel Obj"); diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index 3280b23e5b..44021ce35a 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -640,6 +640,9 @@ void menu_configuration() { #if ENABLED(POWER_LOSS_RECOVERY) EDIT_ITEM(bool, MSG_OUTAGE_RECOVERY, &recovery.enabled, recovery.changed); + #if HAS_PLR_BED_THRESHOLD + EDIT_ITEM(int3, MSG_RESUME_BED_TEMP, &recovery.bed_temp_threshold, 0, BED_MAX_TARGET); + #endif #endif // Preheat configurations diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp index d3b1c58063..a12728a003 100644 --- a/Marlin/src/module/settings.cpp +++ b/Marlin/src/module/settings.cpp @@ -444,6 +444,7 @@ typedef struct SettingsDataStruct { // POWER_LOSS_RECOVERY // bool recovery_enabled; // M413 S + celsius_t bed_temp_threshold; // M413 B // // FWRETRACT @@ -1268,8 +1269,10 @@ void MarlinSettings::postprocess() { // { _FIELD_TEST(recovery_enabled); - const bool recovery_enabled = TERN(POWER_LOSS_RECOVERY, recovery.enabled, ENABLED(PLR_ENABLED_DEFAULT)); + const bool recovery_enabled = TERN0(POWER_LOSS_RECOVERY, recovery.enabled); + const celsius_t bed_temp_threshold = TERN0(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold); EEPROM_WRITE(recovery_enabled); + EEPROM_WRITE(bed_temp_threshold); } // @@ -2310,10 +2313,15 @@ void MarlinSettings::postprocess() { // Power-Loss Recovery // { - bool recovery_enabled; _FIELD_TEST(recovery_enabled); + bool recovery_enabled; + celsius_t bed_temp_threshold; EEPROM_READ(recovery_enabled); - TERN_(POWER_LOSS_RECOVERY, if (!validating) recovery.enabled = recovery_enabled); + EEPROM_READ(bed_temp_threshold); + if (!validating) { + TERN_(POWER_LOSS_RECOVERY, recovery.enabled = recovery_enabled); + TERN_(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold = bed_temp_threshold); + } } // @@ -3460,7 +3468,10 @@ void MarlinSettings::reset() { // // Power-Loss Recovery // - TERN_(POWER_LOSS_RECOVERY, recovery.enable(ENABLED(PLR_ENABLED_DEFAULT))); + #if ENABLED(POWER_LOSS_RECOVERY) + recovery.enable(ENABLED(PLR_ENABLED_DEFAULT)); + TERN_(HAS_PLR_BED_THRESHOLD, recovery.bed_temp_threshold = PLR_BED_THRESHOLD); + #endif // // Firmware Retraction