Skip to content

Commit 2aa2e54

Browse files
⚡️ Improve Homing / Probing Current (#26714)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
1 parent 23d9020 commit 2aa2e54

File tree

15 files changed

+691
-228
lines changed

15 files changed

+691
-228
lines changed

Marlin/Configuration_adv.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2969,7 +2969,7 @@
29692969

29702970
#if AXIS_IS_TMC_CONFIG(X)
29712971
#define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
2972-
#define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing
2972+
#define X_CURRENT_HOME X_CURRENT // (mA) RMS current for homing. (Typically lower than *_CURRENT.)
29732973
#define X_MICROSTEPS 16 // 0..256
29742974
#define X_RSENSE 0.11
29752975
#define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
@@ -3179,6 +3179,13 @@
31793179
//#define E7_HOLD_MULTIPLIER 0.5
31803180
#endif
31813181

3182+
/**
3183+
* Use the homing current for all probing. (e.g., Current may be reduced to the
3184+
* point where a collision makes the motor skip instead of damaging the bed,
3185+
* though this is unlikely to save delicate probes from being damaged.
3186+
*/
3187+
//#define PROBING_USE_CURRENT_HOME
3188+
31823189
// @section tmc/spi
31833190

31843191
/**

Marlin/src/gcode/calibrate/G28.cpp

Lines changed: 19 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
#include "../../module/planner.h"
2929
#include "../../module/stepper.h" // for various
3030

31+
#if HAS_HOMING_CURRENT
32+
#include "../../module/motion.h" // for set/restore_homing_current
33+
#endif
34+
3135
#if HAS_MULTI_HOTEND
3236
#include "../../module/tool_change.h"
3337
#endif
@@ -77,6 +81,14 @@
7781
const float minfr = _MIN(homing_feedrate(X_AXIS), homing_feedrate(Y_AXIS)),
7882
fr_mm_s = HYPOT(minfr, minfr);
7983

84+
// Set homing current to X and Y axis if defined
85+
#if HAS_CURRENT_HOME(X)
86+
set_homing_current(X_AXIS);
87+
#endif
88+
#if HAS_CURRENT_HOME(Y) && NONE(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
89+
set_homing_current(Y_AXIS);
90+
#endif
91+
8092
#if ENABLED(SENSORLESS_HOMING)
8193
sensorless_t stealth_states {
8294
NUM_AXIS_LIST(
@@ -95,6 +107,13 @@
95107

96108
current_position.set(0.0, 0.0);
97109

110+
#if HAS_CURRENT_HOME(X)
111+
restore_homing_current(X_AXIS);
112+
#endif
113+
#if HAS_CURRENT_HOME(Y) && NONE(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
114+
restore_homing_current(Y_AXIS);
115+
#endif
116+
98117
#if ENABLED(SENSORLESS_HOMING) && DISABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
99118
TERN_(X_SENSORLESS, tmc_disable_stallguard(stepperX, stealth_states.x));
100119
TERN_(X2_SENSORLESS, tmc_disable_stallguard(stepperX2, stealth_states.x2));
@@ -254,73 +273,6 @@ void GcodeSuite::G28() {
254273
// Reset to the XY plane
255274
TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
256275

257-
#define _OR_HAS_CURR_HOME(N) HAS_CURRENT_HOME(N) ||
258-
#if MAIN_AXIS_MAP(_OR_HAS_CURR_HOME) MAP(_OR_HAS_CURR_HOME, X2, Y2, Z2, Z3, Z4) 0
259-
#define HAS_HOMING_CURRENT 1
260-
#endif
261-
262-
#if HAS_HOMING_CURRENT
263-
264-
#if ENABLED(DEBUG_LEVELING_FEATURE)
265-
auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) {
266-
if (DEBUGGING(LEVELING)) { DEBUG_ECHOLN(s, F(" current: "), a, F(" -> "), b); }
267-
};
268-
#else
269-
#define debug_current(...)
270-
#endif
271-
272-
#define _SAVE_SET_CURRENT(A) \
273-
const int16_t saved_current_##A = stepper##A.getMilliamps(); \
274-
stepper##A.rms_current(A##_CURRENT_HOME); \
275-
debug_current(F(STR_##A), saved_current_##A, A##_CURRENT_HOME)
276-
277-
#if HAS_CURRENT_HOME(X)
278-
_SAVE_SET_CURRENT(X);
279-
#endif
280-
#if HAS_CURRENT_HOME(X2)
281-
_SAVE_SET_CURRENT(X2);
282-
#endif
283-
#if HAS_CURRENT_HOME(Y)
284-
_SAVE_SET_CURRENT(Y);
285-
#endif
286-
#if HAS_CURRENT_HOME(Y2)
287-
_SAVE_SET_CURRENT(Y2);
288-
#endif
289-
#if HAS_CURRENT_HOME(Z)
290-
_SAVE_SET_CURRENT(Z);
291-
#endif
292-
#if HAS_CURRENT_HOME(Z2)
293-
_SAVE_SET_CURRENT(Z2);
294-
#endif
295-
#if HAS_CURRENT_HOME(Z3)
296-
_SAVE_SET_CURRENT(Z3);
297-
#endif
298-
#if HAS_CURRENT_HOME(Z4)
299-
_SAVE_SET_CURRENT(Z4);
300-
#endif
301-
#if HAS_CURRENT_HOME(I)
302-
_SAVE_SET_CURRENT(I);
303-
#endif
304-
#if HAS_CURRENT_HOME(J)
305-
_SAVE_SET_CURRENT(J);
306-
#endif
307-
#if HAS_CURRENT_HOME(K)
308-
_SAVE_SET_CURRENT(K);
309-
#endif
310-
#if HAS_CURRENT_HOME(U)
311-
_SAVE_SET_CURRENT(U);
312-
#endif
313-
#if HAS_CURRENT_HOME(V)
314-
_SAVE_SET_CURRENT(V);
315-
#endif
316-
#if HAS_CURRENT_HOME(W)
317-
_SAVE_SET_CURRENT(W);
318-
#endif
319-
#if SENSORLESS_STALLGUARD_DELAY
320-
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
321-
#endif
322-
#endif // HAS_HOMING_CURRENT
323-
324276
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
325277
motion_state_t saved_motion_state = begin_slow_homing();
326278
#endif
@@ -572,55 +524,6 @@ void GcodeSuite::G28() {
572524
// Clear endstop state for polled stallGuard endstops
573525
TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state());
574526

575-
#if HAS_HOMING_CURRENT
576-
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore driver current...");
577-
#if HAS_CURRENT_HOME(X)
578-
stepperX.rms_current(saved_current_X);
579-
#endif
580-
#if HAS_CURRENT_HOME(X2)
581-
stepperX2.rms_current(saved_current_X2);
582-
#endif
583-
#if HAS_CURRENT_HOME(Y)
584-
stepperY.rms_current(saved_current_Y);
585-
#endif
586-
#if HAS_CURRENT_HOME(Y2)
587-
stepperY2.rms_current(saved_current_Y2);
588-
#endif
589-
#if HAS_CURRENT_HOME(Z)
590-
stepperZ.rms_current(saved_current_Z);
591-
#endif
592-
#if HAS_CURRENT_HOME(Z2)
593-
stepperZ2.rms_current(saved_current_Z2);
594-
#endif
595-
#if HAS_CURRENT_HOME(Z3)
596-
stepperZ3.rms_current(saved_current_Z3);
597-
#endif
598-
#if HAS_CURRENT_HOME(Z4)
599-
stepperZ4.rms_current(saved_current_Z4);
600-
#endif
601-
#if HAS_CURRENT_HOME(I)
602-
stepperI.rms_current(saved_current_I);
603-
#endif
604-
#if HAS_CURRENT_HOME(J)
605-
stepperJ.rms_current(saved_current_J);
606-
#endif
607-
#if HAS_CURRENT_HOME(K)
608-
stepperK.rms_current(saved_current_K);
609-
#endif
610-
#if HAS_CURRENT_HOME(U)
611-
stepperU.rms_current(saved_current_U);
612-
#endif
613-
#if HAS_CURRENT_HOME(V)
614-
stepperV.rms_current(saved_current_V);
615-
#endif
616-
#if HAS_CURRENT_HOME(W)
617-
stepperW.rms_current(saved_current_W);
618-
#endif
619-
#if SENSORLESS_STALLGUARD_DELAY
620-
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
621-
#endif
622-
#endif // HAS_HOMING_CURRENT
623-
624527
// Move to a height where we can use the full xy-area
625528
TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height));
626529

Marlin/src/gcode/calibrate/G33.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ float lcd_probe_pt(const xy_pos_t &xy);
6363

6464
void ac_home() {
6565
endstops.enable(true);
66-
TERN_(SENSORLESS_HOMING, endstops.set_z_sensorless_current(true));
66+
TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(true));
6767
home_delta();
68-
TERN_(SENSORLESS_HOMING, endstops.set_z_sensorless_current(false));
68+
TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(false));
6969
endstops.not_homing();
7070
}
7171

Marlin/src/inc/Conditionals_adv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797

9898
#if !HAS_BED_PROBE
9999
#undef BABYSTEP_ZPROBE_OFFSET
100+
#undef PROBING_USE_CURRENT_HOME
100101
#endif
101102
#if !HAS_STOWABLE_PROBE
102103
#undef PROBE_DEPLOY_STOW_MENU

Marlin/src/inc/Conditionals_type.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,13 @@
3030
#ifdef GITHUB_ACTIONS
3131
// Extras for CI testing
3232
#endif
33+
34+
// If an axis's Homing Current differs from standard current...
35+
#define HAS_CURRENT_HOME(N) (N##_CURRENT_HOME > 0 && N##_CURRENT_HOME != N##_CURRENT)
36+
37+
// Does any axis have homing current?
38+
#define _OR_HAS_CURR_HOME(N) HAS_CURRENT_HOME(N) ||
39+
#if MAIN_AXIS_MAP(_OR_HAS_CURR_HOME) MAP(_OR_HAS_CURR_HOME, X2, Y2, Z2, Z3, Z4) 0
40+
#define HAS_HOMING_CURRENT 1
41+
#endif
42+
#undef _OR_HAS_CURR_HOME

Marlin/src/inc/SanityCheck.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
237237

238238
// Serial DMA is only available for some STM32 MCUs and HC32
239239
#if ENABLED(SERIAL_DMA)
240-
#if defined(ARDUINO_ARCH_HC32)
240+
#ifdef ARDUINO_ARCH_HC32
241241
// checks for HC32 are located in HAL/HC32/inc/SanityCheck.h
242-
#elif !HAL_STM32 || NONE(STM32F0xx, STM32F1xx, STM32F2xx, STM32F4xx, STM32F7xx)
242+
#elif DISABLED(HAL_STM32) || NONE(STM32F0xx, STM32F1xx, STM32F2xx, STM32F4xx, STM32F7xx)
243243
#error "SERIAL_DMA is only available for some STM32 MCUs and requires HAL/STM32."
244244
#elif !defined(HAL_UART_MODULE_ENABLED) || defined(HAL_UART_MODULE_ONLY)
245245
#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
17261726
#endif
17271727
#endif
17281728

1729+
/**
1730+
* Assert that the homing current must not be greater than the base current.
1731+
* Current may be reduced "to prevent damage" but in fact it's typically reduced to prevent spurious
1732+
* DIAG triggering from fast high torque moves with large jerk values which are more prone to cause binding.
1733+
*/
1734+
#define _BAD_HOME_CURRENT(N) (N##_CURRENT_HOME > N##_CURRENT) ||
1735+
#if MAIN_AXIS_MAP(_BAD_HOME_CURRENT) MAP(_BAD_HOME_CURRENT, X2, Y2, Z2, Z3, Z4) 0
1736+
#ifndef ALLOW_HIGHER_CURRENT_HOME
1737+
#error "*_CURRENT_HOME should be <= *_CURRENT. Define ALLOW_HIGHER_CURRENT_HOME in your configuration to continue anyway."
1738+
#else
1739+
#define HIGHER_CURRENT_HOME_WARNING 1
1740+
#endif
1741+
#endif
1742+
#undef _BAD_HOME_CURRENT
1743+
1744+
#if ENABLED(PROBING_USE_CURRENT_HOME)
1745+
#if (defined(Z_CURRENT_HOME) && !HAS_CURRENT_HOME(Z)) || (defined(Z2_CURRENT_HOME) && !HAS_CURRENT_HOME(Z2)) \
1746+
|| (defined(Z3_CURRENT_HOME) && !HAS_CURRENT_HOME(Z3)) || (defined(Z4_CURRENT_HOME) && !HAS_CURRENT_HOME(Z4))
1747+
#error "PROBING_USE_CURRENT_HOME requires a Z_CURRENT_HOME value that differs from Z_CURRENT."
1748+
#endif
1749+
#endif
1750+
17291751
/**
17301752
* Make sure Z_SAFE_HOMING point is reachable
17311753
*/

Marlin/src/inc/Warnings.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,33 @@
715715
#endif
716716

717717
#if ENABLED(QUICK_HOME) && (X_SPI_SENSORLESS || Y_SPI_SENSORLESS)
718-
#warning "SPI_ENDSTOPS may be unreliable with QUICK_HOME. Adjust back-offs for better results."
718+
#warning "SPI_ENDSTOPS may be unreliable with QUICK_HOME. Adjust SENSORLESS_BACKOFF_MM for better results."
719+
#endif
720+
721+
#if HIGHER_CURRENT_HOME_WARNING
722+
#warning "High homing currents can lead to damage if a sensor fails or is set up incorrectly."
723+
#endif
724+
725+
#if USE_SENSORLESS
726+
#if defined(X_CURRENT_HOME) && !HAS_CURRENT_HOME(X)
727+
#warning "It's recommended to set X_CURRENT_HOME lower than X_CURRENT with SENSORLESS_HOMING."
728+
#elif defined(X2_CURRENT_HOME) && !HAS_CURRENT_HOME(X2)
729+
#warning "It's recommended to set X2_CURRENT_HOME lower than X2_CURRENT with SENSORLESS_HOMING."
730+
#endif
731+
#if defined(Y_CURRENT_HOME) && !HAS_CURRENT_HOME(Y)
732+
#warning "It's recommended to set Y_CURRENT_HOME lower than Y_CURRENT with SENSORLESS_HOMING."
733+
#elif defined(Y2_CURRENT_HOME) && !HAS_CURRENT_HOME(Y2)
734+
#warning "It's recommended to set Y2_CURRENT_HOME lower than Y2_CURRENT with SENSORLESS_HOMING."
735+
#endif
736+
#if defined(Z_CURRENT_HOME) && !HAS_CURRENT_HOME(Z)
737+
#warning "It's recommended to set Z_CURRENT_HOME lower than Z_CURRENT with SENSORLESS_HOMING."
738+
#elif defined(Z2_CURRENT_HOME) && !HAS_CURRENT_HOME(Z2)
739+
#warning "It's recommended to set Z2_CURRENT_HOME lower than Z2_CURRENT with SENSORLESS_HOMING."
740+
#elif defined(Z3_CURRENT_HOME) && !HAS_CURRENT_HOME(Z3)
741+
#warning "It's recommended to set Z3_CURRENT_HOME lower than Z3_CURRENT with SENSORLESS_HOMING."
742+
#elif defined(Z4_CURRENT_HOME) && !HAS_CURRENT_HOME(Z4)
743+
#warning "It's recommended to set Z4_CURRENT_HOME lower than Z4_CURRENT with SENSORLESS_HOMING."
744+
#endif
719745
#endif
720746

721747
#if CANNOT_EMBED_CONFIGURATION

Marlin/src/module/delta.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,18 @@ void home_delta() {
241241
#endif
242242
#endif
243243

244+
// Set homing current for all motors
245+
TERN_(HAS_HOMING_CURRENT, set_homing_current(Z_AXIS));
246+
244247
// Move all carriages together linearly until an endstop is hit.
245248
current_position.z = DIFF_TERN(HAS_BED_PROBE, delta_height + 10, probe.offset.z);
246249
line_to_current_position(homing_feedrate(Z_AXIS));
247250
planner.synchronize();
248251
TERN_(HAS_DELTA_SENSORLESS_PROBING, endstops.report_states());
249252

253+
// Restore the homing current for all motors
254+
TERN_(HAS_HOMING_CURRENT, restore_homing_current(Z_AXIS));
255+
250256
// Re-enable stealthChop if used. Disable diag1 pin on driver.
251257
#if ENABLED(SENSORLESS_HOMING) && DISABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
252258
TERN_(X_SENSORLESS, end_sensorless_homing_per_axis(X_AXIS, stealth_states_x));

0 commit comments

Comments
 (0)