@@ -149,6 +149,8 @@ void PrintJobRecovery::prepare() {
149149 */
150150void PrintJobRecovery::save (const bool force/* =false*/ , const float zraise/* =0*/ , const bool raised/* =false*/ ) {
151151
152+ // We don't check IS_SD_PRINTING here so a save may occur during a pause
153+
152154 #if SAVE_INFO_INTERVAL_MS > 0
153155 static millis_t next_save_ms; // = 0
154156 millis_t ms = millis ();
@@ -292,7 +294,8 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=0*/
292294 constexpr float zraise = 0 ;
293295 #endif
294296
295- // Save, including the limited Z raise
297+ // Save the current position, distance that Z will be raised,
298+ // and a flag whether the raise was already done here.
296299 if (IS_SD_PRINTING ()) save (true , zraise, ENABLED (BACKUP_POWER_SUPPLY));
297300
298301 // Disable all heaters to reduce power loss
@@ -368,22 +371,29 @@ void PrintJobRecovery::resume() {
368371 }
369372 #endif
370373
371- // Reset E, raise Z, home XY...
374+ //
375+ // Home the axes that can safely be homed, and
376+ // establish the current position as best we can
377+ //
372378 #if Z_HOME_DIR > 0
373379
374- // If Z homing goes to max, just reset E and home all
380+ // If Z homing goes to max...
375381 gcode.process_subcommands_now_P (PSTR (
376- " G92.9 E0\n "
377- " G28R0"
382+ " G92.9 E0\n " // Reset E to 0
383+ " G28R0" // Home all axes (no raise)
378384 ));
379385
380386 #else // "G92.9 E0 ..."
381387
388+ // Reset Z and E to 0
382389 gcode.process_subcommands_now_P (" G92.9E0Z0" );
383390
384- // If a Z raise occurred at outage set Z to the Z raise value (over zero), otherwise raise Z now
385- sprintf_P (cmd, info.flag .raised ? PSTR (" G92.9Z%s" ) : PSTR (" G1Z%sF200" ), dtostrf (info.zraise , 1 , 3 , str_1));
386- gcode.process_subcommands_now (cmd);
391+ // Is there a "raise" value?
392+ if (info.zraise ) {
393+ // If a Z raise occurred at outage set Z to the Z raise value, otherwise raise Z now
394+ sprintf_P (cmd, info.flag .raised ? PSTR (" G92.9Z%s" ) : PSTR (" G1Z%sF500" ), dtostrf (info.zraise , 1 , 3 , str_1));
395+ gcode.process_subcommands_now (cmd);
396+ }
387397
388398 // Home safely with no Z raise
389399 gcode.process_subcommands_now_P (PSTR (
@@ -395,19 +405,20 @@ void PrintJobRecovery::resume() {
395405
396406 #endif
397407
398- #ifdef POWER_LOSS_ZHOME_POS
399- // If defined move to a safe Z homing position that avoids the print
408+ #if ENABLED(POWER_LOSS_RECOVER_ZHOME) && defined(POWER_LOSS_ZHOME_POS)
409+ // Move to a safe XY position where Z can home while avoiding the print.
410+ // If Z_SAFE_HOMING is enabled, its position must also be outside the print area!
400411 constexpr xy_pos_t p = POWER_LOSS_ZHOME_POS;
401- sprintf_P (cmd, PSTR (" G1 X%s Y%s F1000 \n G28Z" ), dtostrf (p.x , 1 , 3 , str_1), dtostrf (p.y , 1 , 3 , str_2));
412+ sprintf_P (cmd, PSTR (" G1X%sY%sF1000 \n G28Z" ), dtostrf (p.x , 1 , 3 , str_1), dtostrf (p.y , 1 , 3 , str_2));
402413 gcode.process_subcommands_now (cmd);
403414 #endif
404415
405- // Ensure that all axes are marked as homed
416+ // Mark all axes as having been homed (no effect on current_position)
406417 set_all_homed ();
407418
408419 #if ENABLED(POWER_LOSS_RECOVER_ZHOME)
409- // Now move to ZsavedPos + POWER_LOSS_ZRAISE
410- sprintf_P (cmd, PSTR (" G1 Z%s F500 " ), dtostrf (info.current_position .z + POWER_LOSS_ZRAISE, 1 , 3 , str_1));
420+ // Z was homed. Now move Z back up to the saved Z height, plus the POWER_LOSS_ZRAISE.
421+ sprintf_P (cmd, PSTR (" G1Z%sF500 " ), dtostrf (info.current_position .z + POWER_LOSS_ZRAISE, 1 , 3 , str_1));
411422 gcode.process_subcommands_now (cmd);
412423 #endif
413424
@@ -447,7 +458,7 @@ void PrintJobRecovery::resume() {
447458 }
448459 #endif
449460
450- // Restore retract and hop state
461+ // Restore retract and hop state from an active `G10` command
451462 #if ENABLED(FWRETRACT)
452463 LOOP_L_N (e, EXTRUDERS) {
453464 if (info.retract [e] != 0.0 ) {
@@ -462,7 +473,7 @@ void PrintJobRecovery::resume() {
462473 // Restore leveling state before 'G92 Z' to ensure
463474 // the Z stepper count corresponds to the native Z.
464475 if (info.fade || info.flag .leveling ) {
465- sprintf_P (cmd, PSTR (" M420 S%i Z %s" ), int ( info.flag .leveling ) , dtostrf (info.fade , 1 , 1 , str_1));
476+ sprintf_P (cmd, PSTR (" M420S%cZ %s" ), ' 0 ' + ( char ) info.flag .leveling , dtostrf (info.fade , 1 , 1 , str_1));
466477 gcode.process_subcommands_now (cmd);
467478 }
468479 #endif
@@ -472,11 +483,11 @@ void PrintJobRecovery::resume() {
472483 #endif
473484
474485 // Un-retract if there was a retract at outage
475- #if POWER_LOSS_RETRACT_LEN
486+ #if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0
476487 gcode.process_subcommands_now_P (PSTR (" G1 E" STRINGIFY (POWER_LOSS_RETRACT_LEN) " F3000" ));
477488 #endif
478489
479- // Additional purge if configured
490+ // Additional purge on resume if configured
480491 #if POWER_LOSS_PURGE_LEN
481492 sprintf_P (cmd, PSTR (" G1 E%d F3000" ), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN));
482493 gcode.process_subcommands_now (cmd);
0 commit comments