diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 7947ba65c5b7..629a9b691c69 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -1415,6 +1415,15 @@ // Force the use of the probe for Z-axis homing //#define USE_PROBE_FOR_Z_HOMING +/** + * For machines with Z endstop(s) and a reliable Z probe this option will + * cause Z to home first using Z endstop and then re-home with the probe + * to establish a more ideal Z0 position for probing the bed. This can be + * useful when Z must home to MAX but you want to establish a better Z0 + * based on bed height. Requires a probe and calibrated probe Z offset. + */ +//#define REHOME_Z_WITH_PROBE + /** * Z_MIN_PROBE_PIN * diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 01a4d3bc02e2..fd9200bacf26 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -62,7 +62,7 @@ uint32_t PrintJobRecovery::cmd_sdpos, // = 0 #include "../module/printcounter.h" #include "../module/temperature.h" -#if HOMING_Z_WITH_PROBE +#if Z_CAN_HOME_WITH_PROBE #include "../module/probe.h" #endif @@ -470,7 +470,7 @@ void PrintJobRecovery::resume() { #if HOMING_Z_DOWN // Move to a safe XY position and home Z while avoiding the print. - const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy); + const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(Z_CAN_HOME_WITH_PROBE, - probe.offset_xy); PROCESS_SUBCOMMANDS_NOW(TS(F("G1F1000X"), p_float_t(p.x, 3), 'Y', p_float_t(p.y, 3), F("\nG28HZ"))); #endif diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index 92f05b1fba24..84467e316e44 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -147,7 +147,7 @@ constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; destination.set(safe_homing_xy, current_position.z); - TERN_(HOMING_Z_WITH_PROBE, destination -= probe.offset_xy); + TERN_(Z_CAN_HOME_WITH_PROBE, destination -= probe.offset_xy); if (position_is_reachable(destination)) { @@ -384,7 +384,7 @@ void GcodeSuite::G28() { if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("R0 = No Z raise"); } else { - bool with_probe = ENABLED(HOMING_Z_WITH_PROBE); + bool with_probe = ENABLED(Z_CAN_HOME_WITH_PROBE); // Raise above the current Z (which should be synced in the planner) // The "height" for Z is a coordinate. But if Z is not trusted/homed make it relative. if (seenR || !(z_min_trusted || axis_should_home(Z_AXIS))) { @@ -473,7 +473,9 @@ void GcodeSuite::G28() { stepper.set_separate_multi_axis(false); #endif - #if ENABLED(Z_SAFE_HOMING) + // Use Safe Homing for Z unless re-homing with probe. + // Assume that it only applies to the probe-homing step. + #if ENABLED(Z_SAFE_HOMING) && DISABLED(REHOME_Z_WITH_PROBE) // H means hold the current X/Y position when probing. // Otherwise move to the define safe X/Y position before homing Z. if (!parser.seen_test('H')) diff --git a/Marlin/src/inc/Conditionals-3-etc.h b/Marlin/src/inc/Conditionals-3-etc.h index 3fa80726f123..d2fb694972e6 100644 --- a/Marlin/src/inc/Conditionals-3-etc.h +++ b/Marlin/src/inc/Conditionals-3-etc.h @@ -432,7 +432,14 @@ #define NEED_Z_MIN_PROBE_PIN 1 #endif #if Z_HOME_TO_MIN && (!NEED_Z_MIN_PROBE_PIN || ENABLED(USE_PROBE_FOR_Z_HOMING)) - #define HOMING_Z_WITH_PROBE 1 + #define HOMING_Z_WITH_PROBE 1 // Always home Z with probe + #endif + #if ANY(HOMING_Z_WITH_PROBE, REHOME_Z_WITH_PROBE) + #define Z_CAN_HOME_WITH_PROBE 1 // Can home Z with probe or endstop + #endif + #ifdef REHOME_Z_WITH_PROBE + #undef REHOME_Z_WITH_PROBE + #define REHOME_Z_WITH_PROBE 1 // ensure a value of 1 so we can use with #elif and TERN #endif #if DISABLED(NOZZLE_AS_PROBE) #define HAS_PROBE_XY_OFFSET 1 diff --git a/Marlin/src/inc/Conditionals-4-adv.h b/Marlin/src/inc/Conditionals-4-adv.h index d72f2e458258..1d16e959a17e 100644 --- a/Marlin/src/inc/Conditionals-4-adv.h +++ b/Marlin/src/inc/Conditionals-4-adv.h @@ -160,6 +160,7 @@ #undef ENABLE_LEVELING_FADE_HEIGHT #undef HOME_Z_FIRST #undef HOMING_Z_WITH_PROBE + #undef REHOME_Z_WITH_PROBE #undef INPUT_SHAPING_Z #undef NUM_Z_STEPPERS #undef SAFE_BED_LEVELING_START_Z diff --git a/Marlin/src/inc/Conditionals-5-post.h b/Marlin/src/inc/Conditionals-5-post.h index 67c0135d1960..bdaa01661d83 100644 --- a/Marlin/src/inc/Conditionals-5-post.h +++ b/Marlin/src/inc/Conditionals-5-post.h @@ -1467,7 +1467,7 @@ #endif // Disable Z axis sensorless homing if a probe is used to home the Z axis - #if HOMING_Z_WITH_PROBE + #if Z_CAN_HOME_WITH_PROBE #undef Z_STALL_SENSITIVITY #undef Z2_STALL_SENSITIVITY #undef Z3_STALL_SENSITIVITY diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index d8dc9a38439f..966fbec6e827 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2557,6 +2557,8 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i #error "Z_HOME_DIR must be -1 when homing Z with the probe." #elif ALL(USE_PROBE_FOR_Z_HOMING, HOME_Z_FIRST) #error "HOME_Z_FIRST can't be used when homing Z with a probe." +#elif ALL(HOMING_Z_WITH_PROBE, REHOME_Z_WITH_PROBE) + #error "HOMING_Z_WITH_PROBE and REHOME_Z_WITH_PROBE are mutually-exclusive." #endif #if Z_HOME_TO_MAX && defined(Z_AFTER_HOMING) && DISABLED(ALLOW_Z_AFTER_HOMING) diff --git a/Marlin/src/inc/Warnings.cpp b/Marlin/src/inc/Warnings.cpp index 38711e4fcadd..0950bf03b654 100644 --- a/Marlin/src/inc/Warnings.cpp +++ b/Marlin/src/inc/Warnings.cpp @@ -716,6 +716,10 @@ #error "Z_SAFE_HOMING is recommended when homing with a probe. (Enable Z_SAFE_HOMING or define NO_Z_SAFE_HOMING_WARNING to suppress this warning.)" #endif +#if REHOME_Z_WITH_PROBE && IS_CARTESIAN && NONE(Z_SAFE_HOMING, NO_Z_SAFE_HOMING_WARNING) + #error "Z_SAFE_HOMING is recommended when re-homing with a probe. (Enable Z_SAFE_HOMING or define NO_Z_SAFE_HOMING_WARNING to suppress this warning.)" +#endif + #if HAS_TRINAMIC_CONFIG && NONE(EDGE_STEPPING, NO_EDGE_STEPPING_WARNING) #error "EDGE_STEPPING is strongly recommended with Trinamic stepper drivers. (Enable EDGE_STEPPING or define NO_EDGE_STEPPING_WARNING to suppress this warning.)" #endif diff --git a/Marlin/src/lcd/extui/mks_ui/draw_z_offset_wizard.cpp b/Marlin/src/lcd/extui/mks_ui/draw_z_offset_wizard.cpp index 2ad9816e0147..e665e630ed66 100644 --- a/Marlin/src/lcd/extui/mks_ui/draw_z_offset_wizard.cpp +++ b/Marlin/src/lcd/extui/mks_ui/draw_z_offset_wizard.cpp @@ -109,7 +109,7 @@ static void event_handler(lv_obj_t *obj, lv_event_t event) { SET_SOFT_ENDSTOP_LOOSE(false); TERN_(HAS_LEVELING, set_bed_leveling_enabled(mks_leveling_was_active)); // On cancel the Z position needs correction - #if HOMING_Z_WITH_PROBE && defined(PROBE_OFFSET_WIZARD_START_Z) + #if Z_CAN_HOME_WITH_PROBE && defined(PROBE_OFFSET_WIZARD_START_Z) set_axis_never_homed(Z_AXIS); queue.inject_P(PSTR("G28Z")); #else diff --git a/Marlin/src/lcd/menu/menu_probe_offset.cpp b/Marlin/src/lcd/menu/menu_probe_offset.cpp index e959c687edea..81eb64863b23 100644 --- a/Marlin/src/lcd/menu/menu_probe_offset.cpp +++ b/Marlin/src/lcd/menu/menu_probe_offset.cpp @@ -82,7 +82,7 @@ void probe_offset_wizard_menu() { ACTION_ITEM(MSG_BUTTON_CANCEL, []{ set_offset_and_go_back(z_offset_backup); // On cancel the Z position needs correction - #if HOMING_Z_WITH_PROBE && defined(PROBE_OFFSET_WIZARD_START_Z) + #if Z_CAN_HOME_WITH_PROBE && defined(PROBE_OFFSET_WIZARD_START_Z) set_axis_never_homed(Z_AXIS); queue.inject(F("G28Z")); #else @@ -104,7 +104,7 @@ void probe_offset_wizard_menu() { * 3. Go to the probe_offset_wizard_menu() screen for Z position adjustment to acquire Z0. */ void prepare_for_probe_offset_wizard() { - #if defined(PROBE_OFFSET_WIZARD_XY_POS) || !HOMING_Z_WITH_PROBE + #if defined(PROBE_OFFSET_WIZARD_XY_POS) || !Z_CAN_HOME_WITH_PROBE if (ui.should_draw()) MenuItem_static::draw(1, GET_TEXT_F(MSG_PROBE_WIZARD_PROBING)); if (ui.wait_for_move) return; diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 1282e605eba7..224665e0a415 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -85,6 +85,12 @@ bool relative_mode; // = false bool z_min_trusted; // = false #endif +#if HOMING_Z_WITH_PROBE + constexpr bool z_homing_use_probe = true; +#elif REHOME_Z_WITH_PROBE + bool z_homing_use_probe; // = false +#endif + /** * Cartesian Current Position * Used to track the native machine position as moves are queued. @@ -1065,7 +1071,7 @@ void do_blocking_move_to(const xyze_pos_t &raw, const feedRate_t fr_mm_s/*=0.0f* #ifdef Z_POST_CLEARANCE do_z_clearance( Z_POST_CLEARANCE, - ALL(HOMING_Z_WITH_PROBE, HAS_STOWABLE_PROBE) && TERN0(HAS_BED_PROBE, endstops.z_probe_enabled), + ALL(Z_CAN_HOME_WITH_PROBE, HAS_STOWABLE_PROBE) && TERN0(HAS_BED_PROBE, endstops.z_probe_enabled), true ); #elif ENABLED(USE_PROBE_FOR_Z_HOMING) @@ -1970,8 +1976,8 @@ void prepare_line_to_destination() { * Homing bump feedrate (mm/s) */ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) { - #if HOMING_Z_WITH_PROBE - if (axis == Z_AXIS) return z_probe_slow_mm_s; + #if Z_CAN_HOME_WITH_PROBE + if (axis == Z_AXIS && z_homing_use_probe) return z_probe_slow_mm_s; #endif static const uint8_t homing_bump_divisor[] PROGMEM = HOMING_BUMP_DIVISOR; uint8_t hbd = pgm_read_byte(&homing_bump_divisor[axis]); @@ -2202,7 +2208,7 @@ void prepare_line_to_destination() { if (is_home_dir) { - if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS)) { + if (TERN0(Z_CAN_HOME_WITH_PROBE, axis == Z_AXIS && z_homing_use_probe)) { #if ALL(HAS_HEATED_BED, WAIT_FOR_BED_HEATER) // Wait for bed to heat back up between probing points thermalManager.wait_for_bed_heating(); @@ -2251,8 +2257,8 @@ void prepare_line_to_destination() { if (is_home_dir) { - #if HOMING_Z_WITH_PROBE && HAS_QUIET_PROBING - if (axis == Z_AXIS && final_approach) probe.set_probing_paused(false); + #if Z_CAN_HOME_WITH_PROBE && HAS_QUIET_PROBING + if (axis == Z_AXIS && z_homing_use_probe && final_approach) probe.set_probing_paused(false); #endif endstops.validate_homing_move(); @@ -2427,7 +2433,7 @@ void prepare_line_to_destination() { // Only Z homing (with probe) is permitted if (axis != Z_AXIS) { BUZZ(100, 880); return; } #else - #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_STATE) || TERN0(HOMING_Z_WITH_PROBE, _AXIS(A) == Z_AXIS))) + #define _CAN_HOME(A) (axis == _AXIS(A) && (ANY(A##_SPI_SENSORLESS, HAS_##A##_STATE) || TERN0(Z_CAN_HOME_WITH_PROBE, _AXIS(A) == Z_AXIS))) #define _ANDCANT(N) && !_CAN_HOME(N) if (true MAIN_AXIS_MAP(_ANDCANT)) return; #endif @@ -2441,26 +2447,29 @@ void prepare_line_to_destination() { // Homing Z with a probe? Raise Z (maybe) and deploy the Z probe. // Return early if probe deployment fails. // - #if HOMING_Z_WITH_PROBE - if (axis == Z_AXIS && probe.deploy()) { probe.stow(); return; } + const bool now_probe_homing = TERN0(Z_CAN_HOME_WITH_PROBE, axis == Z_AXIS && z_homing_use_probe); + #if Z_CAN_HOME_WITH_PROBE + if (now_probe_homing && probe.deploy()) { probe.stow(); return; } #endif // Set flags for X, Y, Z motor locking #if HAS_EXTRA_ENDSTOPS - switch (axis) { - TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) - TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) - TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) - stepper.set_separate_multi_axis(true); - default: break; + if (TERN1(REHOME_Z_WITH_PROBE, !z_homing_use_probe)) { + switch (axis) { + TERN_(X_DUAL_ENDSTOPS, case X_AXIS:) + TERN_(Y_DUAL_ENDSTOPS, case Y_AXIS:) + TERN_(Z_MULTI_ENDSTOPS, case Z_AXIS:) + stepper.set_separate_multi_axis(true); + default: break; + } } #endif // // Deploy BLTouch or tare the probe just before probing // - #if HOMING_Z_WITH_PROBE - if (axis == Z_AXIS) { + #if Z_CAN_HOME_WITH_PROBE + if (now_probe_homing) { #if ENABLED(BLTOUCH) // BLTouch was deployed above, but get the alarm state. @@ -2506,10 +2515,16 @@ void prepare_line_to_destination() { // Determine if a homing bump will be done and the bumps distance // When homing Z with probe respect probe clearance - const bool use_probe_bump = TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && home_bump_mm(axis)); + const bool use_probe_bump = now_probe_homing && home_bump_mm(axis); const float bump = axis_home_dir * ( - use_probe_bump ? _MAX(TERN0(HOMING_Z_WITH_PROBE, Z_CLEARANCE_BETWEEN_PROBES), home_bump_mm(axis)) : home_bump_mm(axis) + #ifdef Z_CLEARANCE_BETWEEN_PROBES + // TERN only works if a define is 1 or undefined, it does not work on values other than 1 + use_probe_bump ? Z_CLEARANCE_BETWEEN_PROBES : home_bump_mm(axis) //cannot use TERN on Z_CLEARANCE_BETWEEN_PROBES + #else + home_bump_mm(axis) + #endif ); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("use_probe_bump: ", use_probe_bump, " "); // // Fast move towards endstop until triggered @@ -2520,13 +2535,13 @@ void prepare_line_to_destination() { // If a second homing move is configured... if (bump) { - #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) - if (axis == Z_AXIS && !bltouch.high_speed_mode) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) + #if ALL(Z_CAN_HOME_WITH_PROBE, BLTOUCH) + if (now_probe_homing && !bltouch.high_speed_mode) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) #endif // Move away from the endstop by the axis HOMING_BUMP_MM if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away: ", -bump, "mm"); - do_homing_move(axis, -bump, TERN0(HOMING_Z_WITH_PROBE, (axis == Z_AXIS ? z_probe_fast_mm_s : 0)), false); + do_homing_move(axis, -bump, TERN0(Z_CAN_HOME_WITH_PROBE, (now_probe_homing ? z_probe_fast_mm_s : 0)), false); #if ENABLED(DETECT_BROKEN_ENDSTOP) @@ -2552,8 +2567,8 @@ void prepare_line_to_destination() { #endif // DETECT_BROKEN_ENDSTOP - #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) - if (axis == Z_AXIS && !bltouch.high_speed_mode && bltouch.deploy()) { + #if ALL(Z_CAN_HOME_WITH_PROBE, BLTOUCH) + if (now_probe_homing && !bltouch.high_speed_mode && bltouch.deploy()) { bltouch.stow(); return; // Intermediate DEPLOY (in LOW SPEED MODE) } @@ -2565,11 +2580,14 @@ void prepare_line_to_destination() { do_homing_move(axis, rebump, get_homing_bump_feedrate(axis), true); } - #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) - if (axis == Z_AXIS) bltouch.stow(); // The final STOW + #if ALL(Z_CAN_HOME_WITH_PROBE, BLTOUCH) + if (now_probe_homing) bltouch.stow(); // The final STOW #endif #if HAS_EXTRA_ENDSTOPS + + if (TERN1(REHOME_Z_WITH_PROBE, !z_homing_use_probe)) { + const bool pos_dir = axis_home_dir > 0; #if ENABLED(X_DUAL_ENDSTOPS) if (axis == X_AXIS) { @@ -2694,6 +2712,8 @@ void prepare_line_to_destination() { stepper.set_separate_multi_axis(false); } + } // !z_homing_use_probe + #endif // HAS_EXTRA_ENDSTOPS #ifdef TMC_HOME_PHASE @@ -2732,18 +2752,18 @@ void prepare_line_to_destination() { #endif - #if ALL(BD_SENSOR, HOMING_Z_WITH_PROBE) - if (axis == Z_AXIS) bdl.config_state = BDS_IDLE; + #if ALL(BD_SENSOR, Z_CAN_HOME_WITH_PROBE) + if (now_probe_homing) bdl.config_state = BDS_IDLE; #endif // Put away the Z probe. Return early if it fails. - if (TERN0(HOMING_Z_WITH_PROBE, axis == Z_AXIS && probe.stow())) return; + if (TERN0(Z_CAN_HOME_WITH_PROBE, now_probe_homing && probe.stow())) return; #if DISABLED(DELTA) && defined(HOMING_BACKOFF_POST_MM) const xyz_float_t endstop_backoff = HOMING_BACKOFF_POST_MM; if (endstop_backoff[axis]) { current_position[axis] -= ABS(endstop_backoff[axis]) * axis_home_dir; - line_to_current_position(TERN_(HOMING_Z_WITH_PROBE, (axis == Z_AXIS) ? z_probe_fast_mm_s :) homing_feedrate(axis)); + line_to_current_position(TERN_(Z_CAN_HOME_WITH_PROBE, (axis == Z_AXIS) ? z_probe_fast_mm_s :) homing_feedrate(axis)); #if ENABLED(SENSORLESS_HOMING) planner.synchronize(); @@ -2761,13 +2781,36 @@ void prepare_line_to_destination() { if (axis == Z_AXIS) fwretract.current_hop = 0.0; #endif - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< homeaxis(", C(AXIS_CHAR(axis)), ")"); + // Home again, this time with the probe + #if ENABLED(REHOME_Z_WITH_PROBE) + if (axis == Z_AXIS && !z_homing_use_probe) { + // This was Z endstop homing. Set up for Z Probe Homing. + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("ReHoming Z with Probe now..."); + current_position.z = 0; + sync_plan_position(); + destination.z = current_position.z; + z_homing_use_probe = true; // Home again, but use the probe + #if ENABLED(Z_SAFE_HOMING) + // instead of dragging the nozzle across the bed to Z_SAFE_HOMING XY position, move Z now to prevent nozzle dragging + current_position.z = Z_CLEARANCE_DEPLOY_PROBE; + sync_plan_position(); + do_homing_move(axis,Z_CLEARANCE_DEPLOY_PROBE,z_probe_fast_mm_s,false); + //home_z_safely(); // not declared in this scope, also does not move Z first, which we need + destination = current_position; + destination.x = Z_SAFE_HOMING_X_POINT - probe.offset_xy.x; + destination.y = Z_SAFE_HOMING_Y_POINT - probe.offset_xy.y; + do_blocking_move_to_xy(destination); + #endif + homeaxis(Z_AXIS); + } + z_homing_use_probe = false; + #endif // REHOME_Z_WITH_PROBE - // // Restore axis motor(s) current after homing - // TERN_(HAS_HOMING_CURRENT, restore_homing_current(axis)); + if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< homeaxis(", C(AXIS_CHAR(axis)), ")"); + } // homeaxis() #endif // HAS_ENDSTOPS @@ -2816,14 +2859,19 @@ void set_axis_is_at_home(const AxisEnum axis) { */ #if HAS_BED_PROBE && Z_HOME_TO_MIN if (axis == Z_AXIS) { - #if HOMING_Z_WITH_PROBE - #if ENABLED(BD_SENSOR) - safe_delay(100); - current_position.z = bdl.read(); - #else - current_position.z -= probe.offset.z; - #endif - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z homed with PROBE" TERN_(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, " (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)") " ***\n> (M851 Z", probe.offset.z, ")"); + #if Z_CAN_HOME_WITH_PROBE + if (z_homing_use_probe) { + #if ENABLED(BD_SENSOR) + safe_delay(100); + current_position.z = bdl.read(); + #else + current_position.z -= probe.offset.z; + #endif + if (DEBUGGING(LEVELING)) + DEBUG_ECHOLNPGM("*** Z homed with PROBE" TERN_(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, " (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)") " ***\n> (M851 Z", probe.offset.z, ")"); + } + else if (DEBUGGING(LEVELING)) + DEBUG_ECHOLNPGM("*** Z homed to ENDSTOP, next is Z probe homing ***"); #else if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("*** Z homed to ENDSTOP ***"); #endif