@@ -408,17 +408,40 @@ void GcodeSuite::G28() {
408408 #endif
409409 #endif
410410
411+ // Z may home first, e.g., when homing away from the bed
411412 TERN_ (HOME_Z_FIRST, if (doZ) homeaxis (Z_AXIS));
412413
414+ // 'R' to specify a specific raise. 'R0' indicates no raise, e.g., for recovery.resume
415+ // When 'R0' is used, there should already be adequate clearance, e.g., from homing Z to max.
413416 const bool seenR = parser.seenval (' R' );
414- const float z_homing_height = seenR ? parser.value_linear_units () : Z_HOMING_HEIGHT;
415417
416- if (z_homing_height && (seenR || NUM_AXIS_GANG (doX, || doY, || TERN0 (Z_SAFE_HOMING, doZ), || doI, || doJ, || doK, || doU, || doV, || doW))) {
417- // Raise Z before homing any other axes and z is not already high enough (never lower z)
418- if (DEBUGGING (LEVELING)) DEBUG_ECHOLNPGM (" Raise Z (before homing) by " , z_homing_height);
419- do_z_clearance (z_homing_height);
420- TERN_ (BLTOUCH, bltouch.init ());
418+ // Use raise given by 'R' or Z_HOMING_HEIGHT (above the probe trigger point)
419+ float z_homing_height = seenR ? parser.value_linear_units () : Z_HOMING_HEIGHT;
420+
421+ // Check for any lateral motion that might require clearance
422+ const bool may_skate = seenR || NUM_AXIS_GANG (doX, || doY, || TERN0 (Z_SAFE_HOMING, doZ), || doI, || doJ, || doK, || doU, || doV, || doW);
423+
424+ if (seenR && z_homing_height == 0 ) {
425+ if (DEBUGGING (LEVELING)) DEBUG_ECHOLNPGM (" R0 = No Z raise" );
421426 }
427+ else {
428+ bool with_probe = ENABLED (HOMING_Z_WITH_PROBE);
429+ // Raise above the current Z (which should be synced in the planner)
430+ // The "height" for Z is a coordinate. But if Z is not trusted/homed make it relative.
431+ if (seenR || !TERN (HOME_AFTER_DEACTIVATE, axis_is_trusted, axis_was_homed)(Z_AXIS)) {
432+ z_homing_height += current_position.z ;
433+ with_probe = false ;
434+ }
435+
436+ if (may_skate) {
437+ // Apply Z clearance before doing any lateral motion
438+ if (DEBUGGING (LEVELING)) DEBUG_ECHOLNPGM (" Raise Z before homing:" );
439+ do_z_clearance (z_homing_height, with_probe);
440+ }
441+ }
442+
443+ // Init BLTouch ahead of any lateral motion, even if not homing with the probe
444+ TERN_ (BLTOUCH, if (may_skate) bltouch.init ());
422445
423446 // Diagonal move first if both are homing
424447 TERN_ (QUICK_HOME, if (doX && doY) quick_home_xy ());
0 commit comments