⚡️ Improve Sensorless homing/probing accuracy for G28, G33, M48 (#24220)
Co-Authored-By: Robby Candra <robbycandra.mail@gmail.com> Co-Authored-By: ellensp <530024+ellensp@users.noreply.github.com>
This commit is contained in:
parent
0253500ccd
commit
fcef8d946c
|
@ -321,6 +321,9 @@ void GcodeSuite::G28() {
|
||||||
stepperK.rms_current(K_CURRENT_HOME);
|
stepperK.rms_current(K_CURRENT_HOME);
|
||||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_K), tmc_save_current_K, K_CURRENT_HOME);
|
if (DEBUGGING(LEVELING)) debug_current(F(STR_K), tmc_save_current_K, K_CURRENT_HOME);
|
||||||
#endif
|
#endif
|
||||||
|
#if SENSORLESS_STALLGUARD_DELAY
|
||||||
|
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
||||||
|
@ -542,6 +545,9 @@ void GcodeSuite::G28() {
|
||||||
#if HAS_CURRENT_HOME(K)
|
#if HAS_CURRENT_HOME(K)
|
||||||
stepperK.rms_current(tmc_save_current_K);
|
stepperK.rms_current(tmc_save_current_K);
|
||||||
#endif
|
#endif
|
||||||
|
#if SENSORLESS_STALLGUARD_DELAY
|
||||||
|
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||||
|
#endif
|
||||||
#endif // HAS_HOMING_CURRENT
|
#endif // HAS_HOMING_CURRENT
|
||||||
|
|
||||||
ui.refresh();
|
ui.refresh();
|
||||||
|
|
|
@ -71,9 +71,9 @@ float lcd_probe_pt(const xy_pos_t &xy);
|
||||||
|
|
||||||
void ac_home() {
|
void ac_home() {
|
||||||
endstops.enable(true);
|
endstops.enable(true);
|
||||||
TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(true));
|
TERN_(SENSORLESS_HOMING, endstops.set_homing_current(true));
|
||||||
home_delta();
|
home_delta();
|
||||||
TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(false));
|
TERN_(SENSORLESS_HOMING, endstops.set_homing_current(false));
|
||||||
endstops.not_homing();
|
endstops.not_homing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,6 +390,8 @@ static float auto_tune_a(const float dcr) {
|
||||||
* X Don't activate stallguard on X.
|
* X Don't activate stallguard on X.
|
||||||
* Y Don't activate stallguard on Y.
|
* Y Don't activate stallguard on Y.
|
||||||
* Z Don't activate stallguard on Z.
|
* Z Don't activate stallguard on Z.
|
||||||
|
*
|
||||||
|
* S Save offset_sensorless_adj
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::G33() {
|
void GcodeSuite::G33() {
|
||||||
|
|
||||||
|
@ -411,7 +413,8 @@ void GcodeSuite::G33() {
|
||||||
dcr -= probe_at_offset ? _MAX(total_offset, PROBING_MARGIN) : total_offset;
|
dcr -= probe_at_offset ? _MAX(total_offset, PROBING_MARGIN) : total_offset;
|
||||||
#endif
|
#endif
|
||||||
NOMORE(dcr, DELTA_PRINTABLE_RADIUS);
|
NOMORE(dcr, DELTA_PRINTABLE_RADIUS);
|
||||||
if (parser.seenval('R')) dcr -= _MAX(parser.value_float(),0);
|
if (parser.seenval('R')) dcr -= _MAX(parser.value_float(), 0.0f);
|
||||||
|
TERN_(HAS_DELTA_SENSORLESS_PROBING, dcr *= sensorless_radius_factor);
|
||||||
|
|
||||||
const float calibration_precision = parser.floatval('C', 0.0f);
|
const float calibration_precision = parser.floatval('C', 0.0f);
|
||||||
if (calibration_precision < 0) {
|
if (calibration_precision < 0) {
|
||||||
|
@ -434,9 +437,8 @@ void GcodeSuite::G33() {
|
||||||
const bool stow_after_each = parser.seen_test('E');
|
const bool stow_after_each = parser.seen_test('E');
|
||||||
|
|
||||||
#if HAS_DELTA_SENSORLESS_PROBING
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
probe.test_sensitivity.x = !parser.seen_test('X');
|
probe.test_sensitivity.set(!parser.seen_test('X'), !parser.seen_test('Y'), !parser.seen_test('Z'));
|
||||||
TERN_(HAS_Y_AXIS, probe.test_sensitivity.y = !parser.seen_test('Y'));
|
const bool do_save_offset_adj = parser.seen_test('S');
|
||||||
TERN_(HAS_Z_AXIS, probe.test_sensitivity.z = !parser.seen_test('Z'));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const bool _0p_calibration = probe_points == 0,
|
const bool _0p_calibration = probe_points == 0,
|
||||||
|
@ -475,6 +477,25 @@ void GcodeSuite::G33() {
|
||||||
|
|
||||||
if (!_0p_calibration) ac_home();
|
if (!_0p_calibration) ac_home();
|
||||||
|
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
if (verbose_level > 0 && do_save_offset_adj) {
|
||||||
|
offset_sensorless_adj.reset();
|
||||||
|
|
||||||
|
auto caltower = [&](Probe::sense_bool_t s){
|
||||||
|
float z_at_pt[NPP + 1];
|
||||||
|
LOOP_CAL_ALL(rad) z_at_pt[rad] = 0.0f;
|
||||||
|
probe.test_sensitivity = s;
|
||||||
|
if (probe_calibration_points(z_at_pt, 1, dcr, false, false, probe_at_offset))
|
||||||
|
probe.set_offset_sensorless_adj(z_at_pt[CEN]);
|
||||||
|
};
|
||||||
|
caltower({ true, false, false }); // A
|
||||||
|
caltower({ false, true, false }); // B
|
||||||
|
caltower({ false, false, true }); // C
|
||||||
|
|
||||||
|
probe.test_sensitivity = { true, true, true }; // reset to all
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
do { // start iterations
|
do { // start iterations
|
||||||
|
|
||||||
float z_at_pt[NPP + 1] = { 0.0f };
|
float z_at_pt[NPP + 1] = { 0.0f };
|
||||||
|
@ -598,8 +619,17 @@ void GcodeSuite::G33() {
|
||||||
|
|
||||||
// print report
|
// print report
|
||||||
|
|
||||||
if (verbose_level == 3 || verbose_level == 0)
|
if (verbose_level == 3 || verbose_level == 0) {
|
||||||
print_calibration_results(z_at_pt, _tower_results, _opposite_results);
|
print_calibration_results(z_at_pt, _tower_results, _opposite_results);
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
if (verbose_level == 0 && probe_points == 1) {
|
||||||
|
if (do_save_offset_adj)
|
||||||
|
probe.set_offset_sensorless_adj(z_at_pt[CEN]);
|
||||||
|
else
|
||||||
|
probe.refresh_largest_sensorless_adj();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose_level != 0) { // !dry run
|
if (verbose_level != 0) { // !dry run
|
||||||
if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations
|
if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations
|
||||||
|
@ -660,6 +690,9 @@ void GcodeSuite::G33() {
|
||||||
ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
|
ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
|
||||||
|
|
||||||
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
|
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
probe.test_sensitivity = { true, true, true };
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DELTA_AUTO_CALIBRATION
|
#endif // DELTA_AUTO_CALIBRATION
|
||||||
|
|
|
@ -193,7 +193,6 @@ void DGUSScreenHandlerMKS::DGUSLCD_SendTMCStepValue(DGUS_VP_Variable &var) {
|
||||||
if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes.
|
if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes.
|
||||||
switch (swap16(*(uint16_t*)val_ptr)) {
|
switch (swap16(*(uint16_t*)val_ptr)) {
|
||||||
case 0: { // Resume
|
case 0: { // Resume
|
||||||
|
|
||||||
auto cs = getCurrentScreen();
|
auto cs = getCurrentScreen();
|
||||||
if (runout_mks.runout_status != RUNOUT_WAITING_STATUS && runout_mks.runout_status != UNRUNOUT_STATUS) {
|
if (runout_mks.runout_status != RUNOUT_WAITING_STATUS && runout_mks.runout_status != UNRUNOUT_STATUS) {
|
||||||
if (cs == MKSLCD_SCREEN_PRINT || cs == MKSLCD_SCREEN_PAUSE)
|
if (cs == MKSLCD_SCREEN_PRINT || cs == MKSLCD_SCREEN_PAUSE)
|
||||||
|
@ -213,7 +212,6 @@ void DGUSScreenHandlerMKS::DGUSLCD_SendTMCStepValue(DGUS_VP_Variable &var) {
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 1: // Pause
|
case 1: // Pause
|
||||||
|
|
||||||
GotoScreen(MKSLCD_SCREEN_PAUSE);
|
GotoScreen(MKSLCD_SCREEN_PAUSE);
|
||||||
if (!ExtUI::isPrintingFromMediaPaused()) {
|
if (!ExtUI::isPrintingFromMediaPaused()) {
|
||||||
nozzle_park_mks.print_pause_start_flag = 1;
|
nozzle_park_mks.print_pause_start_flag = 1;
|
||||||
|
@ -222,6 +220,7 @@ void DGUSScreenHandlerMKS::DGUSLCD_SendTMCStepValue(DGUS_VP_Variable &var) {
|
||||||
//ExtUI::mks_pausePrint();
|
//ExtUI::mks_pausePrint();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // Abort
|
case 2: // Abort
|
||||||
HandleUserConfirmationPopUp(VP_SD_AbortPrintConfirmed, nullptr, PSTR("Abort printing"), filelist.filename(), PSTR("?"), true, true, false, true);
|
HandleUserConfirmationPopUp(VP_SD_AbortPrintConfirmed, nullptr, PSTR("Abort printing"), filelist.filename(), PSTR("?"), true, true, false, true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
#include "../extui/ui_api.h"
|
#include "../extui/ui_api.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_PROBE_XY_OFFSET
|
||||||
|
#include "../../module/probe.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
void _man_probe_pt(const xy_pos_t &xy) {
|
void _man_probe_pt(const xy_pos_t &xy) {
|
||||||
if (!ui.wait_for_move) {
|
if (!ui.wait_for_move) {
|
||||||
ui.wait_for_move = true;
|
ui.wait_for_move = true;
|
||||||
|
@ -88,7 +92,9 @@ void _man_probe_pt(const xy_pos_t &xy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goto_tower_a(const_float_t a) {
|
void _goto_tower_a(const_float_t a) {
|
||||||
constexpr float dcr = DELTA_PRINTABLE_RADIUS;
|
float dcr = DELTA_PRINTABLE_RADIUS - PROBING_MARGIN;
|
||||||
|
TERN_(HAS_PROBE_XY_OFFSET, dcr -= HYPOT(probe.offset_xy.x, probe.offset_xy.y));
|
||||||
|
TERN_(HAS_DELTA_SENSORLESS_PROBING, dcr *= sensorless_radius_factor);
|
||||||
xy_pos_t tower_vec = { cos(RADIANS(a)), sin(RADIANS(a)) };
|
xy_pos_t tower_vec = { cos(RADIANS(a)), sin(RADIANS(a)) };
|
||||||
_man_probe_pt(tower_vec * dcr);
|
_man_probe_pt(tower_vec * dcr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,10 @@ xy_float_t delta_tower[ABC];
|
||||||
abc_float_t delta_diagonal_rod_2_tower;
|
abc_float_t delta_diagonal_rod_2_tower;
|
||||||
float delta_clip_start_height = Z_MAX_POS;
|
float delta_clip_start_height = Z_MAX_POS;
|
||||||
abc_float_t delta_diagonal_rod_trim;
|
abc_float_t delta_diagonal_rod_trim;
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
abc_float_t offset_sensorless_adj{0};
|
||||||
|
float largest_sensorless_adj = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
float delta_safe_distance_from_top();
|
float delta_safe_distance_from_top();
|
||||||
|
|
||||||
|
@ -233,6 +237,9 @@ void home_delta() {
|
||||||
TERN_(I_SENSORLESS, sensorless_t stealth_states_i = start_sensorless_homing_per_axis(I_AXIS));
|
TERN_(I_SENSORLESS, sensorless_t stealth_states_i = start_sensorless_homing_per_axis(I_AXIS));
|
||||||
TERN_(J_SENSORLESS, sensorless_t stealth_states_j = start_sensorless_homing_per_axis(J_AXIS));
|
TERN_(J_SENSORLESS, sensorless_t stealth_states_j = start_sensorless_homing_per_axis(J_AXIS));
|
||||||
TERN_(K_SENSORLESS, sensorless_t stealth_states_k = start_sensorless_homing_per_axis(K_AXIS));
|
TERN_(K_SENSORLESS, sensorless_t stealth_states_k = start_sensorless_homing_per_axis(K_AXIS));
|
||||||
|
#if SENSORLESS_STALLGUARD_DELAY
|
||||||
|
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Move all carriages together linearly until an endstop is hit.
|
// Move all carriages together linearly until an endstop is hit.
|
||||||
|
@ -249,6 +256,9 @@ void home_delta() {
|
||||||
TERN_(I_SENSORLESS, end_sensorless_homing_per_axis(I_AXIS, stealth_states_i));
|
TERN_(I_SENSORLESS, end_sensorless_homing_per_axis(I_AXIS, stealth_states_i));
|
||||||
TERN_(J_SENSORLESS, end_sensorless_homing_per_axis(J_AXIS, stealth_states_j));
|
TERN_(J_SENSORLESS, end_sensorless_homing_per_axis(J_AXIS, stealth_states_j));
|
||||||
TERN_(K_SENSORLESS, end_sensorless_homing_per_axis(K_AXIS, stealth_states_k));
|
TERN_(K_SENSORLESS, end_sensorless_homing_per_axis(K_AXIS, stealth_states_k));
|
||||||
|
#if SENSORLESS_STALLGUARD_DELAY
|
||||||
|
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
endstops.validate_homing_move();
|
endstops.validate_homing_move();
|
||||||
|
|
|
@ -38,6 +38,10 @@ extern xy_float_t delta_tower[ABC];
|
||||||
extern abc_float_t delta_diagonal_rod_2_tower;
|
extern abc_float_t delta_diagonal_rod_2_tower;
|
||||||
extern float delta_clip_start_height;
|
extern float delta_clip_start_height;
|
||||||
extern abc_float_t delta_diagonal_rod_trim;
|
extern abc_float_t delta_diagonal_rod_trim;
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
extern abc_float_t offset_sensorless_adj;
|
||||||
|
extern float largest_sensorless_adj;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recalculate factors used for delta kinematics whenever
|
* Recalculate factors used for delta kinematics whenever
|
||||||
|
@ -45,6 +49,13 @@ extern abc_float_t delta_diagonal_rod_trim;
|
||||||
*/
|
*/
|
||||||
void recalc_delta_settings();
|
void recalc_delta_settings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a safe radius for calibration
|
||||||
|
*/
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
static constexpr float sensorless_radius_factor = 0.7f;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delta Inverse Kinematics
|
* Delta Inverse Kinematics
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include "temperature.h"
|
#include "temperature.h"
|
||||||
#include "../lcd/marlinui.h"
|
#include "../lcd/marlinui.h"
|
||||||
|
|
||||||
|
#define DEBUG_OUT BOTH(USE_SENSORLESS, DEBUG_LEVELING_FEATURE)
|
||||||
|
#include "../core/debug_out.h"
|
||||||
|
|
||||||
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
||||||
#include HAL_PATH(../HAL, endstop_interrupts.h)
|
#include HAL_PATH(../HAL, endstop_interrupts.h)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1355,3 +1358,66 @@ void Endstops::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PINS_DEBUGGING
|
#endif // PINS_DEBUGGING
|
||||||
|
|
||||||
|
#if USE_SENSORLESS
|
||||||
|
/**
|
||||||
|
* Change TMC driver currents to N##_CURRENT_HOME, saving the current configuration of each.
|
||||||
|
*/
|
||||||
|
void Endstops::set_homing_current(const bool onoff) {
|
||||||
|
#define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT)
|
||||||
|
#define HAS_DELTA_X_CURRENT (ENABLED(DELTA) && HAS_CURRENT_HOME(X))
|
||||||
|
#define HAS_DELTA_Y_CURRENT (ENABLED(DELTA) && HAS_CURRENT_HOME(Y))
|
||||||
|
#if HAS_DELTA_X_CURRENT || HAS_DELTA_Y_CURRENT || HAS_CURRENT_HOME(Z)
|
||||||
|
#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
|
||||||
|
auto debug_current_on = [](PGM_P const s, const int16_t a, const int16_t b) {
|
||||||
|
if (DEBUGGING(LEVELING)) { DEBUG_ECHOPGM_P(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); }
|
||||||
|
};
|
||||||
|
if (onoff) {
|
||||||
|
#if HAS_DELTA_X_CURRENT
|
||||||
|
saved_current_x = stepperX.getMilliamps();
|
||||||
|
stepperX.rms_current(X_CURRENT_HOME);
|
||||||
|
debug_current_on(PSTR("X"), saved_current_x, X_CURRENT_HOME);
|
||||||
|
#endif
|
||||||
|
#if HAS_DELTA_Y_CURRENT
|
||||||
|
saved_current_y = stepperY.getMilliamps();
|
||||||
|
stepperY.rms_current(Y_CURRENT_HOME);
|
||||||
|
debug_current_on(PSTR("Y"), saved_current_y, Y_CURRENT_HOME);
|
||||||
|
#endif
|
||||||
|
#if HAS_CURRENT_HOME(Z)
|
||||||
|
saved_current_z = stepperZ.getMilliamps();
|
||||||
|
stepperZ.rms_current(Z_CURRENT_HOME);
|
||||||
|
debug_current_on(PSTR("Z"), saved_current_z, Z_CURRENT_HOME);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if HAS_DELTA_X_CURRENT
|
||||||
|
stepperX.rms_current(saved_current_x);
|
||||||
|
debug_current_on(PSTR("X"), X_CURRENT_HOME, saved_current_x);
|
||||||
|
#endif
|
||||||
|
#if HAS_DELTA_Y_CURRENT
|
||||||
|
stepperY.rms_current(saved_current_y);
|
||||||
|
debug_current_on(PSTR("Y"), Y_CURRENT_HOME, saved_current_y);
|
||||||
|
#endif
|
||||||
|
#if HAS_CURRENT_HOME(Z)
|
||||||
|
stepperZ.rms_current(saved_current_z);
|
||||||
|
debug_current_on(PSTR("Z"), Z_CURRENT_HOME, saved_current_z);
|
||||||
|
#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 // XYZ
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -241,6 +241,11 @@ class Endstops {
|
||||||
static void clear_endstop_state();
|
static void clear_endstop_state();
|
||||||
static bool tmc_spi_homing_check();
|
static bool tmc_spi_homing_check();
|
||||||
#endif
|
#endif
|
||||||
|
public:
|
||||||
|
// Basic functions for Sensorless Homing
|
||||||
|
#if USE_SENSORLESS
|
||||||
|
static void set_homing_current(const bool onoff);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Endstops endstops;
|
extern Endstops endstops;
|
||||||
|
|
|
@ -1541,7 +1541,12 @@ void prepare_line_to_destination() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable stealthChop if used. Enable diag1 pin on driver.
|
// Disable stealthChop if used. Enable diag1 pin on driver.
|
||||||
TERN_(SENSORLESS_HOMING, stealth_states = start_sensorless_homing_per_axis(axis));
|
#if ENABLED(SENSORLESS_HOMING)
|
||||||
|
stealth_states = start_sensorless_homing_per_axis(axis);
|
||||||
|
#if SENSORLESS_STALLGUARD_DELAY
|
||||||
|
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EITHER(MORGAN_SCARA, MP_SCARA)
|
#if EITHER(MORGAN_SCARA, MP_SCARA)
|
||||||
|
@ -1577,7 +1582,12 @@ void prepare_line_to_destination() {
|
||||||
endstops.validate_homing_move();
|
endstops.validate_homing_move();
|
||||||
|
|
||||||
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
||||||
TERN_(SENSORLESS_HOMING, end_sensorless_homing_per_axis(axis, stealth_states));
|
#if ENABLED(SENSORLESS_HOMING)
|
||||||
|
end_sensorless_homing_per_axis(axis, stealth_states);
|
||||||
|
#if SENSORLESS_STALLGUARD_DELAY
|
||||||
|
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1657,10 +1657,7 @@ void Planner::quick_stop() {
|
||||||
// forced to empty, there's no risk the ISR will touch this.
|
// forced to empty, there's no risk the ISR will touch this.
|
||||||
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
|
delay_before_delivering = BLOCK_DELAY_FOR_1ST_MOVE;
|
||||||
|
|
||||||
#if HAS_WIRED_LCD
|
TERN_(HAS_WIRED_LCD, clear_block_buffer_runtime()); // Clear the accumulated runtime
|
||||||
// Clear the accumulated runtime
|
|
||||||
clear_block_buffer_runtime();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Make sure to drop any attempt of queuing moves for 1 second
|
// Make sure to drop any attempt of queuing moves for 1 second
|
||||||
cleaning_buffer_counter = TEMP_TIMER_FREQUENCY;
|
cleaning_buffer_counter = TEMP_TIMER_FREQUENCY;
|
||||||
|
|
|
@ -103,7 +103,7 @@ xyz_pos_t Probe::offset; // Initialized by settings.load()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(SENSORLESS_PROBING)
|
#if ENABLED(SENSORLESS_PROBING)
|
||||||
Probe::sense_bool_t Probe::test_sensitivity;
|
Probe::sense_bool_t Probe::test_sensitivity = { true, true, true };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(Z_PROBE_SLED)
|
#if ENABLED(Z_PROBE_SLED)
|
||||||
|
@ -531,12 +531,12 @@ bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) {
|
||||||
#if ENABLED(SENSORLESS_PROBING)
|
#if ENABLED(SENSORLESS_PROBING)
|
||||||
sensorless_t stealth_states { false };
|
sensorless_t stealth_states { false };
|
||||||
#if HAS_DELTA_SENSORLESS_PROBING
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
if (test_sensitivity.x) stealth_states.x = tmc_enable_stallguard(stepperX); // Delta watches all DIAG pins for a stall
|
if (test_sensitivity.x) stealth_states.x = tmc_enable_stallguard(stepperX); // Delta watches all DIAG pins for a stall
|
||||||
if (test_sensitivity.y) stealth_states.y = tmc_enable_stallguard(stepperY);
|
if (test_sensitivity.y) stealth_states.y = tmc_enable_stallguard(stepperY);
|
||||||
#endif
|
#endif
|
||||||
if (test_sensitivity.z) stealth_states.z = tmc_enable_stallguard(stepperZ); // All machines will check Z-DIAG for stall
|
if (test_sensitivity.z) stealth_states.z = tmc_enable_stallguard(stepperZ); // All machines will check Z-DIAG for stall
|
||||||
|
endstops.set_homing_current(true); // The "homing" current also applies to probing
|
||||||
endstops.enable(true);
|
endstops.enable(true);
|
||||||
set_homing_current(true); // The "homing" current also applies to probing
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TERN_(HAS_QUIET_PROBING, set_probing_paused(true));
|
TERN_(HAS_QUIET_PROBING, set_probing_paused(true));
|
||||||
|
@ -553,6 +553,11 @@ bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) {
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// Offset sensorless probing
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
if (probe_triggered) probe.refresh_largest_sensorless_adj();
|
||||||
|
#endif
|
||||||
|
|
||||||
TERN_(HAS_QUIET_PROBING, set_probing_paused(false));
|
TERN_(HAS_QUIET_PROBING, set_probing_paused(false));
|
||||||
|
|
||||||
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
||||||
|
@ -563,7 +568,7 @@ bool Probe::probe_down_to_z(const_float_t z, const_feedRate_t fr_mm_s) {
|
||||||
if (test_sensitivity.y) tmc_disable_stallguard(stepperY, stealth_states.y);
|
if (test_sensitivity.y) tmc_disable_stallguard(stepperY, stealth_states.y);
|
||||||
#endif
|
#endif
|
||||||
if (test_sensitivity.z) tmc_disable_stallguard(stepperZ, stealth_states.z);
|
if (test_sensitivity.z) tmc_disable_stallguard(stepperZ, stealth_states.z);
|
||||||
set_homing_current(false);
|
endstops.set_homing_current(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(BLTOUCH)
|
#if ENABLED(BLTOUCH)
|
||||||
|
@ -666,8 +671,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
|
||||||
if (try_to_probe(PSTR("FAST"), z_probe_low_point, z_probe_fast_mm_s,
|
if (try_to_probe(PSTR("FAST"), z_probe_low_point, z_probe_fast_mm_s,
|
||||||
sanity_check, Z_CLEARANCE_BETWEEN_PROBES) ) return NAN;
|
sanity_check, Z_CLEARANCE_BETWEEN_PROBES) ) return NAN;
|
||||||
|
|
||||||
const float first_probe_z = current_position.z;
|
const float first_probe_z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
|
||||||
|
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("1st Probe Z:", first_probe_z);
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("1st Probe Z:", first_probe_z);
|
||||||
|
|
||||||
// Raise to give the probe clearance
|
// Raise to give the probe clearance
|
||||||
|
@ -709,7 +713,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
|
||||||
|
|
||||||
TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe());
|
TERN_(MEASURE_BACKLASH_WHEN_PROBING, backlash.measure_with_probe());
|
||||||
|
|
||||||
const float z = current_position.z;
|
const float z = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
|
||||||
|
|
||||||
#if EXTRA_PROBING > 0
|
#if EXTRA_PROBING > 0
|
||||||
// Insert Z measurement into probes[]. Keep it sorted ascending.
|
// Insert Z measurement into probes[]. Keep it sorted ascending.
|
||||||
|
@ -760,7 +764,7 @@ float Probe::run_z_probe(const bool sanity_check/*=true*/) {
|
||||||
|
|
||||||
#elif TOTAL_PROBING == 2
|
#elif TOTAL_PROBING == 2
|
||||||
|
|
||||||
const float z2 = current_position.z;
|
const float z2 = DIFF_TERN(HAS_DELTA_SENSORLESS_PROBING, current_position.z, largest_sensorless_adj);
|
||||||
|
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", first_probe_z - z2);
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("2nd Probe Z:", z2, " Discrepancy:", first_probe_z - z2);
|
||||||
|
|
||||||
|
@ -842,7 +846,7 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
|
||||||
SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED);
|
SERIAL_ERROR_MSG(STR_ERR_PROBING_FAILED);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
DEBUG_ECHOLNPGM("measured_z: ", measured_z);
|
||||||
return measured_z;
|
return measured_z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,58 +899,39 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the current in the TMC drivers to N##_CURRENT_HOME. And we save the current configuration of each TMC driver.
|
* Set the sensorless Z offset
|
||||||
*/
|
*/
|
||||||
void Probe::set_homing_current(const bool onoff) {
|
void Probe::set_offset_sensorless_adj(const_float_t sz) {
|
||||||
#define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT)
|
#if ENABLED(SENSORLESS_PROBING)
|
||||||
#if HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Z)
|
DEBUG_SECTION(pso, "Probe::set_offset_sensorless_adj", true);
|
||||||
#if ENABLED(DELTA)
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
static int16_t saved_current_X, saved_current_Y;
|
if (test_sensitivity.x) offset_sensorless_adj.a = sz;
|
||||||
|
if (test_sensitivity.y) offset_sensorless_adj.b = sz;
|
||||||
#endif
|
#endif
|
||||||
#if HAS_CURRENT_HOME(Z)
|
if (test_sensitivity.z) offset_sensorless_adj.c = sz;
|
||||||
static int16_t saved_current_Z;
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh largest_sensorless_adj based on triggered endstops
|
||||||
|
*/
|
||||||
|
void Probe::refresh_largest_sensorless_adj() {
|
||||||
|
#if ENABLED(SENSORLESS_PROBING)
|
||||||
|
DEBUG_SECTION(rso, "Probe::refresh_largest_sensorless_adj", true);
|
||||||
|
largest_sensorless_adj = -3; // A reference away from any real probe height
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
if (TEST(endstops.state(), X_MAX)) {
|
||||||
|
NOLESS(largest_sensorless_adj, offset_sensorless_adj.a);
|
||||||
|
DEBUG_ECHOLNPGM("Endstop_X: ", largest_sensorless_adj, " TowerX");
|
||||||
|
}
|
||||||
|
if (TEST(endstops.state(), Y_MAX)) {
|
||||||
|
NOLESS(largest_sensorless_adj, offset_sensorless_adj.b);
|
||||||
|
DEBUG_ECHOLNPGM("Endstop_Y: ", largest_sensorless_adj, " TowerY");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if ((ENABLED(DELTA) && (HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(Y))) || HAS_CURRENT_HOME(Z))
|
if (TEST(endstops.state(), Z_MAX)) {
|
||||||
auto debug_current_on = [](PGM_P const s, const int16_t a, const int16_t b) {
|
NOLESS(largest_sensorless_adj, offset_sensorless_adj.c);
|
||||||
if (DEBUGGING(LEVELING)) { DEBUG_ECHOPGM_P(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); }
|
DEBUG_ECHOLNPGM("Endstop_Z: ", largest_sensorless_adj, " TowerZ");
|
||||||
};
|
|
||||||
#endif
|
|
||||||
if (onoff) {
|
|
||||||
#if ENABLED(DELTA)
|
|
||||||
#if HAS_CURRENT_HOME(X)
|
|
||||||
saved_current_X = stepperX.getMilliamps();
|
|
||||||
stepperX.rms_current(X_CURRENT_HOME);
|
|
||||||
debug_current_on(PSTR("X"), saved_current_X, X_CURRENT_HOME);
|
|
||||||
#endif
|
|
||||||
#if HAS_CURRENT_HOME(Y)
|
|
||||||
saved_current_Y = stepperY.getMilliamps();
|
|
||||||
stepperY.rms_current(Y_CURRENT_HOME);
|
|
||||||
debug_current_on(PSTR("Y"), saved_current_Y, Y_CURRENT_HOME);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if HAS_CURRENT_HOME(Z)
|
|
||||||
saved_current_Z = stepperZ.getMilliamps();
|
|
||||||
stepperZ.rms_current(Z_CURRENT_HOME);
|
|
||||||
debug_current_on(PSTR("Z"), saved_current_Z, Z_CURRENT_HOME);
|
|
||||||
#endif
|
|
||||||
TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(true));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if ENABLED(DELTA)
|
|
||||||
#if HAS_CURRENT_HOME(X)
|
|
||||||
stepperX.rms_current(saved_current_X);
|
|
||||||
debug_current_on(PSTR("X"), X_CURRENT_HOME, saved_current_X);
|
|
||||||
#endif
|
|
||||||
#if HAS_CURRENT_HOME(Y)
|
|
||||||
stepperY.rms_current(saved_current_Y);
|
|
||||||
debug_current_on(PSTR("Y"), Y_CURRENT_HOME, saved_current_Y);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if HAS_CURRENT_HOME(Z)
|
|
||||||
stepperZ.rms_current(saved_current_Z);
|
|
||||||
debug_current_on(PSTR("Z"), Z_CURRENT_HOME, saved_current_Z);
|
|
||||||
#endif
|
|
||||||
TERN_(IMPROVE_HOMING_RELIABILITY, planner.enable_stall_prevention(false));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,13 @@ class Probe {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#if ENABLED(SENSORLESS_PROBING)
|
#if ENABLED(SENSORLESS_PROBING)
|
||||||
typedef struct { bool x:1, y:1, z:1; } sense_bool_t;
|
typedef struct {
|
||||||
|
#if HAS_DELTA_SENSORLESS_PROBING
|
||||||
|
bool x:1, y:1, z:1;
|
||||||
|
#else
|
||||||
|
bool z;
|
||||||
|
#endif
|
||||||
|
} sense_bool_t;
|
||||||
static sense_bool_t test_sensitivity;
|
static sense_bool_t test_sensitivity;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -299,7 +305,8 @@ public:
|
||||||
#if USE_SENSORLESS
|
#if USE_SENSORLESS
|
||||||
static void enable_stallguard_diag1();
|
static void enable_stallguard_diag1();
|
||||||
static void disable_stallguard_diag1();
|
static void disable_stallguard_diag1();
|
||||||
static void set_homing_current(const bool onoff);
|
static void set_offset_sensorless_adj(const_float_t sz);
|
||||||
|
static void refresh_largest_sensorless_adj();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue