From 533d752707cded76fbf48e3fc949dfd620b0c9b4 Mon Sep 17 00:00:00 2001
From: erril007 <141030793+erril007@users.noreply.github.com>
Date: Sat, 21 Jun 2025 03:50:13 +0200
Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20EVENT=5FGCODE=5F(BEFORE|AFTER)=5FG3?=
 =?UTF-8?q?4=20(#27930)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Marlin/Configuration_adv.h              | 17 +++++++++++-
 Marlin/src/gcode/calibrate/G34_M422.cpp | 36 ++++++++++++++++---------
 buildroot/tests/LPC1769                 |  3 ++-
 3 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index fd238dcc08..1cd89a9714 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1081,11 +1081,26 @@
   #define G34_MAX_GRADE              5    // (%) Maximum incline that G34 will handle
   #define Z_STEPPER_ALIGN_ITERATIONS 5    // Number of iterations to apply during alignment
   #define Z_STEPPER_ALIGN_ACC        0.02 // Stop iterating early if the accuracy is better than this
+
   #define RESTORE_LEVELING_AFTER_G34      // Restore leveling after G34 is done?
+
   // After G34, re-home Z (G28 Z) or just calculate it from the last probe heights?
   // Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed.
   #define HOME_AFTER_G34
-#endif
+
+  /**
+   * Commands to execute at the start of G34 probing,
+   * after switching to the PROBING_TOOL.
+   */
+  //#define EVENT_GCODE_BEFORE_G34 "M300 P440 S200"
+
+  /**
+   * Commands to execute at the end of G34 probing.
+   * Useful to retract or move the Z probe out of the way.
+   */
+  //#define EVENT_GCODE_AFTER_G34 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10"
+
+#endif // Z_STEPPER_AUTO_ALIGN
 
 /**
  * Assisted Tramming
diff --git a/Marlin/src/gcode/calibrate/G34_M422.cpp b/Marlin/src/gcode/calibrate/G34_M422.cpp
index 9d8fd7b84b..fc22b354eb 100644
--- a/Marlin/src/gcode/calibrate/G34_M422.cpp
+++ b/Marlin/src/gcode/calibrate/G34_M422.cpp
@@ -143,6 +143,11 @@ void GcodeSuite::G34() {
 
       probe.use_probing_tool();
 
+      #ifdef EVENT_GCODE_BEFORE_G34
+        if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Before G34 G-code: ", F(EVENT_GCODE_BEFORE_G34));
+        gcode.process_subcommands_now(F(EVENT_GCODE_BEFORE_G34));
+      #endif
+
       TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
 
       // Compute a worst-case clearance height to probe from. After the first
@@ -214,19 +219,20 @@ void GcodeSuite::G34() {
           // Probing sanity check is disabled, as it would trigger even in normal cases because
           // current_position.z has been manually altered in the "dirty trick" above.
 
-          if (DEBUGGING(LEVELING))
-            DEBUG_ECHOLNPGM(
-              "Z_PROBE_LOW_POINT: ", p_float_t(Z_PROBE_LOW_POINT, 2),
-              "z_probe: ", p_float_t(z_probe, 2),
-              "Probe Tgt: ", p_float_t((Z_PROBE_LOW_POINT) - z_probe * 0.5f, 2)
-            );
+          const float minz = (Z_PROBE_LOW_POINT) - (z_probe * 0.5f);
+
+          if (DEBUGGING(LEVELING)) {
+            DEBUG_ECHOPGM("Z_PROBE_LOW_POINT: " STRINGIFY(Z_PROBE_LOW_POINT));
+            DEBUG_ECHOLNPGM(" z_probe: ", p_float_t(z_probe, 3),
+                            " Probe Tgt: ", p_float_t(minz, 3));
+          }
 
           const float z_probed_height = probe.probe_at_point(
             DIFF_TERN(HAS_HOME_OFFSET, ppos, xy_pos_t(home_offset)),   // xy
             raise_after,                                               // raise_after
             (DEBUGGING(LEVELING) || DEBUGGING(INFO)) ? 3 : 0,          // verbose_level
             true, false,                                               // probe_relative, sanity_check
-            (Z_PROBE_LOW_POINT) - (z_probe * 0.5f),                    // z_min_point
+            minz,                                                      // z_min_point
             Z_TWEEN_SAFE_CLEARANCE                                     // z_clearance
           );
 
@@ -303,7 +309,7 @@ void GcodeSuite::G34() {
 
         SERIAL_EOL();
 
-        SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("1:2="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
+        SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("2-1="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
         #if TRIPLE_Z
           msg.append(F(" 3-2="), p_float_t(ABS(z_measured[2] - z_measured[1]), 3))
              .append(F(" 3-1="), p_float_t(ABS(z_measured[2] - z_measured[0]), 3));
@@ -414,7 +420,7 @@ void GcodeSuite::G34() {
         SERIAL_ECHOLNPGM("G34 aborted.");
       else {
         SERIAL_ECHOLNPGM("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations);
-        SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 2));
+        SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 3));
       }
 
       // Stow the probe because the last call to probe.probe_at_point(...)
@@ -430,9 +436,9 @@ void GcodeSuite::G34() {
         // Ideally, this would be equal to the 'z_probe * 0.5f' which was added earlier.
         if (DEBUGGING(LEVELING))
           DEBUG_ECHOLNPGM(
-            "z_measured_min: ", p_float_t(z_measured_min, 2),
-            "Z_TWEEN_SAFE_CLEARANCE: ", p_float_t(Z_TWEEN_SAFE_CLEARANCE, 2),
-            "zoffs: ", p_float_t(zoffs, 2)
+            "z_measured_min: ", p_float_t(z_measured_min, 3),
+            "Z_TWEEN_SAFE_CLEARANCE: ", p_float_t(Z_TWEEN_SAFE_CLEARANCE, 3),
+            "zoffs: ", p_float_t(zoffs, 3)
           );
 
         if (!err_break)
@@ -440,6 +446,12 @@ void GcodeSuite::G34() {
         sync_plan_position();
       #endif
 
+      #ifdef EVENT_GCODE_AFTER_G34
+        if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("After G34 G-code: ", F(EVENT_GCODE_AFTER_G34));
+        planner.synchronize();
+        process_subcommands_now(F(EVENT_GCODE_AFTER_G34));
+      #endif
+
       probe.use_probing_tool(false);
 
       #if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34)
diff --git a/buildroot/tests/LPC1769 b/buildroot/tests/LPC1769
index 5356d3e186..ae470d5619 100755
--- a/buildroot/tests/LPC1769
+++ b/buildroot/tests/LPC1769
@@ -83,7 +83,8 @@ opt_set MOTHERBOARD BOARD_BTT_SKR_V1_4_TURBO SERIAL_PORT -1 \
         Z_MIN_ENDSTOP_HIT_STATE HIGH
 opt_enable PIDTEMPBED \
         FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE \
-        BLTOUCH BLTOUCH_FORCE_SW_MODE USE_PROBE_FOR_Z_HOMING Z_SAFE_HOMING QUICK_HOME Z_STEPPER_AUTO_ALIGN \
+        BLTOUCH BLTOUCH_FORCE_SW_MODE USE_PROBE_FOR_Z_HOMING Z_SAFE_HOMING QUICK_HOME \
+        Z_STEPPER_AUTO_ALIGN EVENT_GCODE_BEFORE_G34 EVENT_GCODE_AFTER_G34 \
         AUTO_BED_LEVELING_BILINEAR EXTRAPOLATE_BEYOND_GRID RESTORE_LEVELING_AFTER_G28 LCD_BED_LEVELING MESH_EDIT_MENU \
         EEPROM_SETTINGS EEPROM_AUTO_INIT \
         SDSUPPORT CR10_STOCKDISPLAY SPEAKER LCD_INFO_MENU STATUS_MESSAGE_SCROLLING \