Browse Source

⚡️ Improve Homing / Probing Current (#26714)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
sargonphin 6 months ago
parent
commit
2aa2e5487a

+ 8 - 1
Marlin/Configuration_adv.h

@@ -2969,7 +2969,7 @@
 
   #if AXIS_IS_TMC_CONFIG(X)
     #define X_CURRENT       800        // (mA) RMS current. Multiply by 1.414 for peak current.
-    #define X_CURRENT_HOME  X_CURRENT  // (mA) RMS current for sensorless homing
+    #define X_CURRENT_HOME  X_CURRENT  // (mA) RMS current for homing. (Typically lower than *_CURRENT.)
     #define X_MICROSTEPS     16        // 0..256
     #define X_RSENSE          0.11
     #define X_CHAIN_POS      -1        // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
@@ -3179,6 +3179,13 @@
     //#define E7_HOLD_MULTIPLIER 0.5
   #endif
 
+  /**
+   * Use the homing current for all probing. (e.g., Current may be reduced to the
+   * point where a collision makes the motor skip instead of damaging the bed,
+   * though this is unlikely to save delicate probes from being damaged.
+   */
+  //#define PROBING_USE_CURRENT_HOME
+
   // @section tmc/spi
 
   /**

+ 19 - 116
Marlin/src/gcode/calibrate/G28.cpp

@@ -28,6 +28,10 @@
 #include "../../module/planner.h"
 #include "../../module/stepper.h" // for various
 
+#if HAS_HOMING_CURRENT
+  #include "../../module/motion.h" // for set/restore_homing_current
+#endif
+
 #if HAS_MULTI_HOTEND
   #include "../../module/tool_change.h"
 #endif
@@ -77,6 +81,14 @@
     const float minfr = _MIN(homing_feedrate(X_AXIS), homing_feedrate(Y_AXIS)),
                 fr_mm_s = HYPOT(minfr, minfr);
 
+    // Set homing current to X and Y axis if defined
+    #if HAS_CURRENT_HOME(X)
+      set_homing_current(X_AXIS);
+    #endif
+    #if HAS_CURRENT_HOME(Y) && NONE(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
+      set_homing_current(Y_AXIS);
+    #endif
+
     #if ENABLED(SENSORLESS_HOMING)
       sensorless_t stealth_states {
         NUM_AXIS_LIST(
@@ -95,6 +107,13 @@
 
     current_position.set(0.0, 0.0);
 
+    #if HAS_CURRENT_HOME(X)
+      restore_homing_current(X_AXIS);
+    #endif
+    #if HAS_CURRENT_HOME(Y) && NONE(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
+      restore_homing_current(Y_AXIS);
+    #endif
+
     #if ENABLED(SENSORLESS_HOMING) && DISABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
       TERN_(X_SENSORLESS, tmc_disable_stallguard(stepperX, stealth_states.x));
       TERN_(X2_SENSORLESS, tmc_disable_stallguard(stepperX2, stealth_states.x2));
@@ -254,73 +273,6 @@ void GcodeSuite::G28() {
     // Reset to the XY plane
     TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
 
-    #define _OR_HAS_CURR_HOME(N) HAS_CURRENT_HOME(N) ||
-    #if MAIN_AXIS_MAP(_OR_HAS_CURR_HOME) MAP(_OR_HAS_CURR_HOME, X2, Y2, Z2, Z3, Z4) 0
-      #define HAS_HOMING_CURRENT 1
-    #endif
-
-    #if HAS_HOMING_CURRENT
-
-      #if ENABLED(DEBUG_LEVELING_FEATURE)
-        auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) {
-          if (DEBUGGING(LEVELING)) { DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); }
-        };
-      #else
-        #define debug_current(...)
-      #endif
-
-      #define _SAVE_SET_CURRENT(A) \
-        const int16_t saved_current_##A = stepper##A.getMilliamps(); \
-        stepper##A.rms_current(A##_CURRENT_HOME); \
-        debug_current(F(STR_##A), saved_current_##A, A##_CURRENT_HOME)
-
-      #if HAS_CURRENT_HOME(X)
-        _SAVE_SET_CURRENT(X);
-      #endif
-      #if HAS_CURRENT_HOME(X2)
-        _SAVE_SET_CURRENT(X2);
-      #endif
-      #if HAS_CURRENT_HOME(Y)
-        _SAVE_SET_CURRENT(Y);
-      #endif
-      #if HAS_CURRENT_HOME(Y2)
-        _SAVE_SET_CURRENT(Y2);
-      #endif
-      #if HAS_CURRENT_HOME(Z)
-        _SAVE_SET_CURRENT(Z);
-      #endif
-      #if HAS_CURRENT_HOME(Z2)
-        _SAVE_SET_CURRENT(Z2);
-      #endif
-      #if HAS_CURRENT_HOME(Z3)
-        _SAVE_SET_CURRENT(Z3);
-      #endif
-      #if HAS_CURRENT_HOME(Z4)
-        _SAVE_SET_CURRENT(Z4);
-      #endif
-      #if HAS_CURRENT_HOME(I)
-        _SAVE_SET_CURRENT(I);
-      #endif
-      #if HAS_CURRENT_HOME(J)
-        _SAVE_SET_CURRENT(J);
-      #endif
-      #if HAS_CURRENT_HOME(K)
-        _SAVE_SET_CURRENT(K);
-      #endif
-      #if HAS_CURRENT_HOME(U)
-        _SAVE_SET_CURRENT(U);
-      #endif
-      #if HAS_CURRENT_HOME(V)
-        _SAVE_SET_CURRENT(V);
-      #endif
-      #if HAS_CURRENT_HOME(W)
-        _SAVE_SET_CURRENT(W);
-      #endif
-      #if SENSORLESS_STALLGUARD_DELAY
-        safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
-      #endif
-    #endif // HAS_HOMING_CURRENT
-
     #if ENABLED(IMPROVE_HOMING_RELIABILITY)
       motion_state_t saved_motion_state = begin_slow_homing();
     #endif
@@ -572,55 +524,6 @@ void GcodeSuite::G28() {
     // Clear endstop state for polled stallGuard endstops
     TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state());
 
-    #if HAS_HOMING_CURRENT
-      if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore driver current...");
-      #if HAS_CURRENT_HOME(X)
-        stepperX.rms_current(saved_current_X);
-      #endif
-      #if HAS_CURRENT_HOME(X2)
-        stepperX2.rms_current(saved_current_X2);
-      #endif
-      #if HAS_CURRENT_HOME(Y)
-        stepperY.rms_current(saved_current_Y);
-      #endif
-      #if HAS_CURRENT_HOME(Y2)
-        stepperY2.rms_current(saved_current_Y2);
-      #endif
-      #if HAS_CURRENT_HOME(Z)
-        stepperZ.rms_current(saved_current_Z);
-      #endif
-      #if HAS_CURRENT_HOME(Z2)
-        stepperZ2.rms_current(saved_current_Z2);
-      #endif
-      #if HAS_CURRENT_HOME(Z3)
-        stepperZ3.rms_current(saved_current_Z3);
-      #endif
-      #if HAS_CURRENT_HOME(Z4)
-        stepperZ4.rms_current(saved_current_Z4);
-      #endif
-      #if HAS_CURRENT_HOME(I)
-        stepperI.rms_current(saved_current_I);
-      #endif
-      #if HAS_CURRENT_HOME(J)
-        stepperJ.rms_current(saved_current_J);
-      #endif
-      #if HAS_CURRENT_HOME(K)
-        stepperK.rms_current(saved_current_K);
-      #endif
-      #if HAS_CURRENT_HOME(U)
-        stepperU.rms_current(saved_current_U);
-      #endif
-      #if HAS_CURRENT_HOME(V)
-        stepperV.rms_current(saved_current_V);
-      #endif
-      #if HAS_CURRENT_HOME(W)
-        stepperW.rms_current(saved_current_W);
-      #endif
-      #if SENSORLESS_STALLGUARD_DELAY
-        safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
-      #endif
-    #endif // HAS_HOMING_CURRENT
-
     // Move to a height where we can use the full xy-area
     TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height));
 

+ 2 - 2
Marlin/src/gcode/calibrate/G33.cpp

@@ -63,9 +63,9 @@ float lcd_probe_pt(const xy_pos_t &xy);
 
 void ac_home() {
   endstops.enable(true);
-  TERN_(SENSORLESS_HOMING, endstops.set_z_sensorless_current(true));
+  TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(true));
   home_delta();
-  TERN_(SENSORLESS_HOMING, endstops.set_z_sensorless_current(false));
+  TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(false));
   endstops.not_homing();
 }
 

+ 1 - 0
Marlin/src/inc/Conditionals_adv.h

@@ -97,6 +97,7 @@
 
 #if !HAS_BED_PROBE
   #undef BABYSTEP_ZPROBE_OFFSET
+  #undef PROBING_USE_CURRENT_HOME
 #endif
 #if !HAS_STOWABLE_PROBE
   #undef PROBE_DEPLOY_STOW_MENU

+ 10 - 0
Marlin/src/inc/Conditionals_type.h

@@ -30,3 +30,13 @@
 #ifdef GITHUB_ACTIONS
   // Extras for CI testing
 #endif
+
+// If an axis's Homing Current differs from standard current...
+#define HAS_CURRENT_HOME(N) (N##_CURRENT_HOME > 0 && N##_CURRENT_HOME != N##_CURRENT)
+
+// Does any axis have homing current?
+#define _OR_HAS_CURR_HOME(N) HAS_CURRENT_HOME(N) ||
+#if MAIN_AXIS_MAP(_OR_HAS_CURR_HOME) MAP(_OR_HAS_CURR_HOME, X2, Y2, Z2, Z3, Z4) 0
+  #define HAS_HOMING_CURRENT 1
+#endif
+#undef _OR_HAS_CURR_HOME

+ 24 - 2
Marlin/src/inc/SanityCheck.h

@@ -237,9 +237,9 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
 
 // Serial DMA is only available for some STM32 MCUs and HC32
 #if ENABLED(SERIAL_DMA)
-  #if defined(ARDUINO_ARCH_HC32)
+  #ifdef ARDUINO_ARCH_HC32
     // checks for HC32 are located in HAL/HC32/inc/SanityCheck.h
-  #elif !HAL_STM32 || NONE(STM32F0xx, STM32F1xx, STM32F2xx, STM32F4xx, STM32F7xx)
+  #elif DISABLED(HAL_STM32) || NONE(STM32F0xx, STM32F1xx, STM32F2xx, STM32F4xx, STM32F7xx)
     #error "SERIAL_DMA is only available for some STM32 MCUs and requires HAL/STM32."
   #elif !defined(HAL_UART_MODULE_ENABLED) || defined(HAL_UART_MODULE_ONLY)
     #error "SERIAL_DMA requires STM32 platform HAL UART (without HAL_UART_MODULE_ONLY)."
@@ -1726,6 +1726,28 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
   #endif
 #endif
 
+/**
+ * Assert that the homing current must not be greater than the base current.
+ * Current may be reduced "to prevent damage" but in fact it's typically reduced to prevent spurious
+ * DIAG triggering from fast high torque moves with large jerk values which are more prone to cause binding.
+ */
+#define _BAD_HOME_CURRENT(N) (N##_CURRENT_HOME > N##_CURRENT) ||
+#if MAIN_AXIS_MAP(_BAD_HOME_CURRENT) MAP(_BAD_HOME_CURRENT, X2, Y2, Z2, Z3, Z4) 0
+  #ifndef ALLOW_HIGHER_CURRENT_HOME
+    #error "*_CURRENT_HOME should be <= *_CURRENT. Define ALLOW_HIGHER_CURRENT_HOME in your configuration to continue anyway."
+  #else
+    #define HIGHER_CURRENT_HOME_WARNING 1
+  #endif
+#endif
+#undef _BAD_HOME_CURRENT
+
+#if ENABLED(PROBING_USE_CURRENT_HOME)
+  #if  (defined(Z_CURRENT_HOME)  && !HAS_CURRENT_HOME(Z))  || (defined(Z2_CURRENT_HOME) && !HAS_CURRENT_HOME(Z2)) \
+    || (defined(Z3_CURRENT_HOME) && !HAS_CURRENT_HOME(Z3)) || (defined(Z4_CURRENT_HOME) && !HAS_CURRENT_HOME(Z4))
+    #error "PROBING_USE_CURRENT_HOME requires a Z_CURRENT_HOME value that differs from Z_CURRENT."
+  #endif
+#endif
+
 /**
  * Make sure Z_SAFE_HOMING point is reachable
  */

+ 27 - 1
Marlin/src/inc/Warnings.cpp

@@ -715,7 +715,33 @@
 #endif
 
 #if ENABLED(QUICK_HOME) && (X_SPI_SENSORLESS || Y_SPI_SENSORLESS)
-  #warning "SPI_ENDSTOPS may be unreliable with QUICK_HOME. Adjust back-offs for better results."
+  #warning "SPI_ENDSTOPS may be unreliable with QUICK_HOME. Adjust SENSORLESS_BACKOFF_MM for better results."
+#endif
+
+#if HIGHER_CURRENT_HOME_WARNING
+  #warning "High homing currents can lead to damage if a sensor fails or is set up incorrectly."
+#endif
+
+#if USE_SENSORLESS
+  #if defined(X_CURRENT_HOME) && !HAS_CURRENT_HOME(X)
+    #warning "It's recommended to set X_CURRENT_HOME lower than X_CURRENT with SENSORLESS_HOMING."
+  #elif defined(X2_CURRENT_HOME) && !HAS_CURRENT_HOME(X2)
+    #warning "It's recommended to set X2_CURRENT_HOME lower than X2_CURRENT with SENSORLESS_HOMING."
+  #endif
+  #if defined(Y_CURRENT_HOME) && !HAS_CURRENT_HOME(Y)
+    #warning "It's recommended to set Y_CURRENT_HOME lower than Y_CURRENT with SENSORLESS_HOMING."
+  #elif defined(Y2_CURRENT_HOME) && !HAS_CURRENT_HOME(Y2)
+    #warning "It's recommended to set Y2_CURRENT_HOME lower than Y2_CURRENT with SENSORLESS_HOMING."
+  #endif
+  #if defined(Z_CURRENT_HOME) && !HAS_CURRENT_HOME(Z)
+    #warning "It's recommended to set Z_CURRENT_HOME lower than Z_CURRENT with SENSORLESS_HOMING."
+  #elif defined(Z2_CURRENT_HOME) && !HAS_CURRENT_HOME(Z2)
+    #warning "It's recommended to set Z2_CURRENT_HOME lower than Z2_CURRENT with SENSORLESS_HOMING."
+  #elif defined(Z3_CURRENT_HOME) && !HAS_CURRENT_HOME(Z3)
+    #warning "It's recommended to set Z3_CURRENT_HOME lower than Z3_CURRENT with SENSORLESS_HOMING."
+  #elif defined(Z4_CURRENT_HOME) && !HAS_CURRENT_HOME(Z4)
+    #warning "It's recommended to set Z4_CURRENT_HOME lower than Z4_CURRENT with SENSORLESS_HOMING."
+  #endif
 #endif
 
 #if CANNOT_EMBED_CONFIGURATION

+ 6 - 0
Marlin/src/module/delta.cpp

@@ -241,12 +241,18 @@ void home_delta() {
     #endif
   #endif
 
+  // Set homing current for all motors
+  TERN_(HAS_HOMING_CURRENT, set_homing_current(Z_AXIS));
+
   // Move all carriages together linearly until an endstop is hit.
   current_position.z = DIFF_TERN(HAS_BED_PROBE, delta_height + 10, probe.offset.z);
   line_to_current_position(homing_feedrate(Z_AXIS));
   planner.synchronize();
   TERN_(HAS_DELTA_SENSORLESS_PROBING, endstops.report_states());
 
+  // Restore the homing current for all motors
+  TERN_(HAS_HOMING_CURRENT, restore_homing_current(Z_AXIS));
+
   // Re-enable stealthChop if used. Disable diag1 pin on driver.
   #if ENABLED(SENSORLESS_HOMING) && DISABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
     TERN_(X_SENSORLESS, end_sensorless_homing_per_axis(X_AXIS, stealth_states_x));

+ 0 - 91
Marlin/src/module/endstops.cpp

@@ -1370,94 +1370,3 @@ void Endstops::update() {
   }
 
 #endif // PINS_DEBUGGING
-
-#if USE_SENSORLESS
-  /**
-   * Change TMC driver currents to N##_CURRENT_HOME, saving the current configuration of each.
-   */
-  void Endstops::set_z_sensorless_current(const bool onoff) {
-    #if ENABLED(DELTA) && HAS_CURRENT_HOME(X)
-      #define HAS_DELTA_X_CURRENT 1
-    #endif
-    #if ENABLED(DELTA) && HAS_CURRENT_HOME(Y)
-      #define HAS_DELTA_Y_CURRENT 1
-    #endif
-    #if HAS_DELTA_X_CURRENT || HAS_DELTA_Y_CURRENT || HAS_CURRENT_HOME(Z) || HAS_CURRENT_HOME(Z2) || HAS_CURRENT_HOME(Z3) || HAS_CURRENT_HOME(Z4)
-      #if HAS_DELTA_X_CURRENT
-        static int16_t saved_current_X;
-      #endif
-      #if HAS_DELTA_Y_CURRENT
-        static int16_t saved_current_Y;
-      #endif
-      #if HAS_CURRENT_HOME(Z)
-        static int16_t saved_current_Z;
-      #endif
-      #if HAS_CURRENT_HOME(Z2)
-        static int16_t saved_current_Z2;
-      #endif
-      #if HAS_CURRENT_HOME(Z3)
-        static int16_t saved_current_Z3;
-      #endif
-      #if HAS_CURRENT_HOME(Z4)
-        static int16_t saved_current_Z4;
-      #endif
-
-      #if ENABLED(DEBUG_LEVELING_FEATURE)
-        auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) {
-          if (DEBUGGING(LEVELING)) { DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); }
-        };
-      #else
-        #define debug_current(...)
-      #endif
-
-      #define _SAVE_SET_CURRENT(A) \
-        saved_current_##A = stepper##A.getMilliamps(); \
-        stepper##A.rms_current(A##_CURRENT_HOME); \
-        debug_current(F(STR_##A), saved_current_##A, A##_CURRENT_HOME)
-
-      #define _RESTORE_CURRENT(A) \
-        stepper##A.rms_current(saved_current_##A); \
-        debug_current(F(STR_##A), saved_current_##A, A##_CURRENT_HOME)
-
-      if (onoff) {
-        TERN_(HAS_DELTA_X_CURRENT, _SAVE_SET_CURRENT(X));
-        TERN_(HAS_DELTA_Y_CURRENT, _SAVE_SET_CURRENT(Y));
-        #if HAS_CURRENT_HOME(Z)
-          _SAVE_SET_CURRENT(Z);
-        #endif
-        #if HAS_CURRENT_HOME(Z2)
-          _SAVE_SET_CURRENT(Z2);
-        #endif
-        #if HAS_CURRENT_HOME(Z3)
-          _SAVE_SET_CURRENT(Z3);
-        #endif
-        #if HAS_CURRENT_HOME(Z4)
-          _SAVE_SET_CURRENT(Z4);
-        #endif
-      }
-      else {
-        TERN_(HAS_DELTA_X_CURRENT, _RESTORE_CURRENT(X));
-        TERN_(HAS_DELTA_Y_CURRENT, _RESTORE_CURRENT(Y));
-        #if HAS_CURRENT_HOME(Z)
-          _RESTORE_CURRENT(Z);
-        #endif
-        #if HAS_CURRENT_HOME(Z2)
-          _RESTORE_CURRENT(Z2);
-        #endif
-        #if HAS_CURRENT_HOME(Z3)
-          _RESTORE_CURRENT(Z3);
-        #endif
-        #if HAS_CURRENT_HOME(Z4)
-          _RESTORE_CURRENT(Z4);
-        #endif
-      }
-
-      TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(onoff));
-
-      #if SENSORLESS_STALLGUARD_DELAY
-        safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
-      #endif
-
-    #endif
-  }
-#endif // USE_SENSORLESS

+ 0 - 7
Marlin/src/module/endstops.h

@@ -37,8 +37,6 @@
 #define _ESN_ITEM(K,A,M) ES_ITEM(K,ES_ENUM(A,M))
 #define ES_MINMAX(A) ES_ITEM(HAS_##A##_MIN_STATE, ES_ENUM(A,MIN)) ES_ITEM(HAS_##A##_MAX_STATE, ES_ENUM(A,MAX))
 
-#define HAS_CURRENT_HOME(N) ((N##_CURRENT_HOME > 0) && (N##_CURRENT_HOME != N##_CURRENT))
-
 /**
  * Basic Endstop Flag Bits:
  * - Each axis with an endstop gets a flag for its homing direction.
@@ -288,11 +286,6 @@ class Endstops {
       static void clear_endstop_state();
       static bool tmc_spi_homing_check();
     #endif
-  public:
-    // Basic functions for Sensorless Homing
-    #if USE_SENSORLESS
-      static void set_z_sensorless_current(const bool onoff);
-    #endif
 };
 
 extern Endstops endstops;

Some files were not shown because too many files changed in this diff