Skip to content

Commit

Permalink
⚡️ Improve Homing / Probing Current (MarlinFirmware#26714)
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
  • Loading branch information
sargonphin and thinkyhead authored Aug 15, 2024
1 parent 23d9020 commit 2aa2e54
Show file tree
Hide file tree
Showing 15 changed files with 691 additions and 228 deletions.
9 changes: 8 additions & 1 deletion Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, ...
Expand Down Expand Up @@ -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

/**
Expand Down
135 changes: 19 additions & 116 deletions Marlin/src/gcode/calibrate/G28.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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));
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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));

Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/gcode/calibrate/G33.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
1 change: 1 addition & 0 deletions Marlin/src/inc/Conditionals_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions Marlin/src/inc/Conditionals_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 24 additions & 2 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)."
Expand Down Expand Up @@ -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
*/
Expand Down
28 changes: 27 additions & 1 deletion Marlin/src/inc/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions Marlin/src/module/delta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Loading

0 comments on commit 2aa2e54

Please sign in to comment.