From 6b91b7b411da3e7dfd535670d8a096a7144a0ff2 Mon Sep 17 00:00:00 2001
From: Edward Patel <edward.patel@memention.com>
Date: Wed, 1 Apr 2015 21:18:51 +0200
Subject: [PATCH] Mesh bed leveling: Added G29 S3 + finer steps in manual
 probing.

* Use "G29 S3 Xn Yn Zn.nn" to modify bad probed point manually
* Changed manual Z steps from 0.05 to 0.025 and made brought it to Configuration.h
---
 Marlin/Configuration.h |  4 ++++
 Marlin/Marlin_main.cpp | 54 +++++++++++++++++++++++++++++++++++-------
 Marlin/ultralcd.cpp    |  4 ++--
 3 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index a984923ea2..5a6d483bf9 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -387,6 +387,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
+#if defined(MANUAL_BED_LEVELING)
+  #define MBL_Z_STEP 0.025
+#endif  // MANUAL_BED_LEVELING
+
 #if defined(MESH_BED_LEVELING)
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6b41be6179..a327f209d8 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2038,10 +2038,18 @@ inline void gcode_G28() {
    *
    * Parameters With MESH_BED_LEVELING:
    *
-   *  S0 Produce a mesh report
-   *  S1 Start probing mesh points
-   *  S2 Probe the next mesh point
+   *  S0              Produce a mesh report
+   *  S1              Start probing mesh points
+   *  S2              Probe the next mesh point
+   *  S3 Xn Yn Zn.nn  Manually modify a single point
    *
+   * The S0 report the points as below
+   *
+   *  +----> X-axis
+   *  |
+   *  |
+   *  v Y-axis
+   *  
    */
   inline void gcode_G29() {
 
@@ -2052,13 +2060,13 @@ inline void gcode_G28() {
     int state = 0;
     if (code_seen('S') || code_seen('s')) {
       state = code_value_long();
-      if (state < 0 || state > 2) {
-        SERIAL_PROTOCOLPGM("S out of range (0-2).\n");
+      if (state < 0 || state > 3) {
+        SERIAL_PROTOCOLPGM("S out of range (0-3).\n");
         return;
       }
     }
 
-    if (state == 0) { // Dump mesh_bed_leveling
+    if (state == 0) { // Produce a mesh report
       if (mbl.active) {
         SERIAL_PROTOCOLPGM("Num X,Y: ");
         SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
@@ -2078,14 +2086,14 @@ inline void gcode_G28() {
         SERIAL_PROTOCOLPGM("Mesh bed leveling not active.\n");
       }
 
-    } else if (state == 1) { // Begin probing mesh points
+    } else if (state == 1) { // Start probing mesh points
 
       mbl.reset();
       probe_point = 0;
       enquecommands_P(PSTR("G28"));
       enquecommands_P(PSTR("G29 S2"));
 
-    } else if (state == 2) { // Goto next point
+    } else if (state == 2) { // Probe the next mesh point
 
       if (probe_point < 0) {
         SERIAL_PROTOCOLPGM("Start mesh probing with \"G29 S1\" first.\n");
@@ -2119,6 +2127,36 @@ inline void gcode_G28() {
       plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
       st_synchronize();
       probe_point++;
+    } else if (state == 3) { // Manually modify a single point
+      int ix, iy;
+      float z;
+      if (code_seen('X') || code_seen('x')) {
+        ix = code_value_long()-1;
+        if (ix < 0 || ix >= MESH_NUM_X_POINTS) {
+          SERIAL_PROTOCOLPGM("X out of range (1-" STRINGIFY(MESH_NUM_X_POINTS) ").\n");
+          return;
+        }
+      } else {
+          SERIAL_PROTOCOLPGM("X not entered.\n");
+          return;
+      }
+      if (code_seen('Y') || code_seen('y')) {
+        iy = code_value_long()-1;
+        if (iy < 0 || iy >= MESH_NUM_Y_POINTS) {
+          SERIAL_PROTOCOLPGM("Y out of range (1-" STRINGIFY(MESH_NUM_Y_POINTS) ").\n");
+          return;
+        }
+      } else {
+          SERIAL_PROTOCOLPGM("Y not entered.\n");
+          return;
+      }
+      if (code_seen('Z') || code_seen('z')) {
+        z = code_value();
+      } else {
+          SERIAL_PROTOCOLPGM("Z not entered.\n");
+          return;
+      }
+      mbl.z_values[iy][ix] = z;
     }
   }
 
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index d2a2e6faaf..e6da28e0f1 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1795,14 +1795,14 @@ static void _lcd_level_bed()
 {
   if (encoderPosition != 0) {
     refresh_cmd_timeout();
-    current_position[Z_AXIS] += float((int)encoderPosition) * 0.05;
+    current_position[Z_AXIS] += float((int)encoderPosition) * MBL_Z_STEP;
     if (min_software_endstops && current_position[Z_AXIS] < Z_MIN_POS) current_position[Z_AXIS] = Z_MIN_POS;
     if (max_software_endstops && current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
     encoderPosition = 0;
     plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[Z_AXIS]/60, active_extruder);
     lcdDrawUpdate = 1;
   }
-  if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("Z"), ftostr32(current_position[Z_AXIS]));
+  if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR("Z"), ftostr43(current_position[Z_AXIS]));
   static bool debounce_click = false;
   if (LCD_CLICKED) {
     if (!debounce_click) {
-- 
GitLab