🚸 Fix / improve LCD_BED_TRAMMING (#25425)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Farva42 2023-03-18 04:14:51 -06:00 committed by Scott Lahteine
parent fbb1c82bc2
commit 5abfc6160f
4 changed files with 105 additions and 79 deletions

View file

@ -38,30 +38,33 @@
* With BLTOUCH_HS_MODE: * With BLTOUCH_HS_MODE:
* H Report the current BLTouch HS mode state and exit * H Report the current BLTouch HS mode state and exit
* S<bool> Set High Speed (HS) Mode and exit without deploy * S<bool> Set High Speed (HS) Mode and exit without deploy
*
* R<bool> Remain in place after deploying (and before activating) the probe
*/ */
void GcodeSuite::M401() { void GcodeSuite::M401() {
#ifdef BLTOUCH_HS_MODE
const bool seenH = parser.seen_test('H'), const bool seenH = parser.seen_test('H'),
seenS = parser.seen('S'); seenS = parser.seen('S');
if (seenH || seenS) { if (seenH || seenS) {
#ifdef BLTOUCH_HS_MODE
if (seenS) bltouch.high_speed_mode = parser.value_bool(); if (seenS) bltouch.high_speed_mode = parser.value_bool();
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPGM("BLTouch HS mode "); SERIAL_ECHOPGM("BLTouch HS mode ");
serialprintln_onoff(bltouch.high_speed_mode); serialprintln_onoff(bltouch.high_speed_mode);
#endif return;
} }
else { #endif
probe.deploy();
probe.deploy(parser.boolval('R'));
TERN_(PROBE_TARE, probe.tare()); TERN_(PROBE_TARE, probe.tare());
report_current_position(); report_current_position();
}
} }
/** /**
* M402: Deactivate and stow the Z probe * M402: Deactivate and stow the Z probe
* R<bool> Remain in place after stowing (and before deactivating) the probe
*/ */
void GcodeSuite::M402() { void GcodeSuite::M402() {
probe.stow(); probe.stow(parser.boolval('R'));
probe.move_z_after_probing(); probe.move_z_after_probing();
report_current_position(); report_current_position();
} }

View file

@ -43,6 +43,10 @@
#define BED_TRAMMING_HEIGHT 0.0 #define BED_TRAMMING_HEIGHT 0.0
#endif #endif
#if BOTH(HAS_STOWABLE_PROBE, BED_TRAMMING_USE_PROBE) && DISABLED(BLTOUCH)
#define NEEDS_PROBE_DEPLOY 1
#endif
#if ENABLED(BED_TRAMMING_USE_PROBE) #if ENABLED(BED_TRAMMING_USE_PROBE)
#include "../../module/probe.h" #include "../../module/probe.h"
#include "../../module/endstops.h" #include "../../module/endstops.h"
@ -97,38 +101,38 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
static int8_t bed_corner; static int8_t bed_corner;
/** /**
* Select next corner coordinates * Move to the next corner coordinates
*/ */
static void _lcd_bed_tramming_get_next_position() { static void _lcd_goto_next_corner() {
xy_pos_t corner_point = lf; // Left front
if (tramming_3_points) { if (tramming_3_points) {
if (bed_corner >= available_points) bed_corner = 0; // Above max position -> move back to first corner if (bed_corner >= available_points) bed_corner = 0; // Above max position -> move back to first corner
switch (bed_corner) { switch (bed_corner) {
case 0 ... 1: case 0 ... 1:
// First two corners set explicitly by the configuration // First two corners set explicitly by the configuration
current_position = lf; // Left front
switch (lco[bed_corner]) { switch (lco[bed_corner]) {
case RF: current_position.x = rb.x; break; // Right Front case RF: corner_point.x = rb.x; break; // Right Front
case RB: current_position = rb; break; // Right Back case RB: corner_point = rb; break; // Right Back
case LB: current_position.y = rb.y; break; // Left Back case LB: corner_point.y = rb.y; break; // Left Back
} }
break; break;
case 2: case 2:
// Determine which edge to probe for 3rd point // Determine which edge to probe for 3rd point
current_position.set(lf.x + (rb.x - lf.x) / 2, lf.y + (rb.y - lf.y) / 2); corner_point.set(lf.x + (rb.x - lf.x) / 2, lf.y + (rb.y - lf.y) / 2);
if ((lco[0] == LB && lco[1] == RB) || (lco[0] == RB && lco[1] == LB)) current_position.y = lf.y; // Front Center if ((lco[0] == LB && lco[1] == RB) || (lco[0] == RB && lco[1] == LB)) corner_point.y = lf.y; // Front Center
if ((lco[0] == LF && lco[1] == LB) || (lco[0] == LB && lco[1] == LF)) current_position.x = rb.x; // Center Right if ((lco[0] == LF && lco[1] == LB) || (lco[0] == LB && lco[1] == LF)) corner_point.x = rb.x; // Center Right
if ((lco[0] == RF && lco[1] == RB) || (lco[0] == RB && lco[1] == RF)) current_position.x = lf.x; // Left Center if ((lco[0] == RF && lco[1] == RB) || (lco[0] == RB && lco[1] == RF)) corner_point.x = lf.x; // Left Center
if ((lco[0] == LF && lco[1] == RF) || (lco[0] == RF && lco[1] == LF)) current_position.y = rb.y; // Center Back if ((lco[0] == LF && lco[1] == RF) || (lco[0] == RF && lco[1] == LF)) corner_point.y = rb.y; // Center Back
#if DISABLED(BED_TRAMMING_INCLUDE_CENTER) && ENABLED(BED_TRAMMING_USE_PROBE) #if ENABLED(BED_TRAMMING_USE_PROBE) && DISABLED(BED_TRAMMING_INCLUDE_CENTER)
bed_corner++; // Must increment the count to ensure it resets the loop if the 3rd point is out of tolerance bed_corner++; // Must increment the count to ensure it resets the loop if the 3rd point is out of tolerance
#endif #endif
break; break;
#if ENABLED(BED_TRAMMING_INCLUDE_CENTER) #if ENABLED(BED_TRAMMING_INCLUDE_CENTER)
case 3: case 3:
current_position.set(X_CENTER, Y_CENTER); corner_point.set(X_CENTER, Y_CENTER);
break; break;
#endif #endif
} }
@ -136,23 +140,29 @@ static void _lcd_bed_tramming_get_next_position() {
else { else {
// Four-Corner Bed Tramming with optional center // Four-Corner Bed Tramming with optional center
if (TERN0(BED_TRAMMING_INCLUDE_CENTER, bed_corner == center_index)) { if (TERN0(BED_TRAMMING_INCLUDE_CENTER, bed_corner == center_index)) {
current_position.set(X_CENTER, Y_CENTER); corner_point.set(X_CENTER, Y_CENTER);
TERN_(BED_TRAMMING_USE_PROBE, good_points--); // Decrement to allow one additional probe point
} }
else { else {
current_position = lf; // Left front
switch (lco[bed_corner]) { switch (lco[bed_corner]) {
case RF: current_position.x = rb.x; break; // Right Front case RF: corner_point.x = rb.x; break; // Right Front
case RB: current_position = rb; break; // Right Back case RB: corner_point = rb; break; // Right Back
case LB: current_position.y = rb.y; break; // Left Back case LB: corner_point.y = rb.y; break; // Left Back
} }
} }
} }
float z = BED_TRAMMING_Z_HOP;
#if BOTH(BED_TRAMMING_USE_PROBE, BLTOUCH)
z += bltouch.z_extra_clearance();
#endif
line_to_z(z);
do_blocking_move_to_xy(DIFF_TERN(BED_TRAMMING_USE_PROBE, corner_point, probe.offset_xy), manual_feedrate_mm_s.x);
#if DISABLED(BED_TRAMMING_USE_PROBE)
line_to_z(BED_TRAMMING_HEIGHT);
if (++bed_corner >= available_points) bed_corner = 0;
#endif
} }
/**
* Level corners, starting in the front-left corner.
*/
#if ENABLED(BED_TRAMMING_USE_PROBE) #if ENABLED(BED_TRAMMING_USE_PROBE)
#define VALIDATE_POINT(X, Y, STR) static_assert(Probe::build_time::can_reach((X), (Y)), \ #define VALIDATE_POINT(X, Y, STR) static_assert(Probe::build_time::can_reach((X), (Y)), \
@ -210,13 +220,21 @@ static void _lcd_bed_tramming_get_next_position() {
MenuItem_confirm::select_screen( MenuItem_confirm::select_screen(
GET_TEXT_F(TERN(HAS_LEVELING, MSG_BUTTON_LEVEL, MSG_BUTTON_DONE)) GET_TEXT_F(TERN(HAS_LEVELING, MSG_BUTTON_LEVEL, MSG_BUTTON_DONE))
, TERN(HAS_LEVELING, GET_TEXT_F(MSG_BUTTON_BACK), nullptr) , TERN(HAS_LEVELING, GET_TEXT_F(MSG_BUTTON_BACK), nullptr)
, []{ queue.inject(TERN(HAS_LEVELING, F("G29N"), FPSTR(G28_STR))); ui.return_to_status(); } , []{
, TERN(HAS_LEVELING, ui.goto_previous_screen_no_defer, []{}) tramming_done = true;
queue.inject(TERN(HAS_LEVELING, F("G29N"), FPSTR(G28_STR)));
ui.goto_previous_screen_no_defer();
}
, []{
tramming_done = true;
TERN_(HAS_LEVELING, ui.goto_previous_screen_no_defer());
TERN_(NEEDS_PROBE_DEPLOY, probe.stow(true));
}
, GET_TEXT_F(MSG_BED_TRAMMING_IN_RANGE) , GET_TEXT_F(MSG_BED_TRAMMING_IN_RANGE)
); );
} }
bool _lcd_bed_tramming_probe(bool verify=false) { bool _lcd_bed_tramming_probe(const bool verify=false) {
if (verify) line_to_z(BED_TRAMMING_Z_HOP); // do clearance if needed if (verify) line_to_z(BED_TRAMMING_Z_HOP); // do clearance if needed
TERN_(BLTOUCH, if (!bltouch.high_speed_mode) bltouch.deploy()); // Deploy in LOW SPEED MODE on every probe action TERN_(BLTOUCH, if (!bltouch.high_speed_mode) bltouch.deploy()); // Deploy in LOW SPEED MODE on every probe action
do_blocking_move_to_z(last_z - BED_TRAMMING_PROBE_TOLERANCE, MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW)); // Move down to lower tolerance do_blocking_move_to_z(last_z - BED_TRAMMING_PROBE_TOLERANCE, MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW)); // Move down to lower tolerance
@ -232,6 +250,11 @@ static void _lcd_bed_tramming_get_next_position() {
last_z = current_position.z; // Above tolerance. Set a new Z for subsequent corners. last_z = current_position.z; // Above tolerance. Set a new Z for subsequent corners.
good_points = 0; // ...and start over good_points = 0; // ...and start over
} }
// Raise the probe after the last point to give clearance for stow
if (TERN0(NEEDS_PROBE_DEPLOY, good_points == nr_edge_points - 1))
line_to_z(BED_TRAMMING_Z_HOP);
return true; // probe triggered return true; // probe triggered
} }
line_to_z(last_z); // go back to tolerance middle point before raise line_to_z(last_z); // go back to tolerance middle point before raise
@ -267,11 +290,7 @@ static void _lcd_bed_tramming_get_next_position() {
ui.refresh(LCDVIEW_REDRAW_NOW); ui.refresh(LCDVIEW_REDRAW_NOW);
_lcd_draw_probing(); // update screen with # of good points _lcd_draw_probing(); // update screen with # of good points
line_to_z(current_position.z + BED_TRAMMING_Z_HOP + TERN0(BLTOUCH, bltouch.z_extra_clearance())); // clearance _lcd_goto_next_corner(); // Goto corner
_lcd_bed_tramming_get_next_position(); // Select next corner coordinates
current_position -= probe.offset_xy; // Account for probe offsets
do_blocking_move_to_xy(current_position); // Goto corner
TERN_(BLTOUCH, if (bltouch.high_speed_mode) bltouch.deploy()); // Deploy in HIGH SPEED MODE TERN_(BLTOUCH, if (bltouch.high_speed_mode) bltouch.deploy()); // Deploy in HIGH SPEED MODE
if (!_lcd_bed_tramming_probe()) { // Probe down to tolerance if (!_lcd_bed_tramming_probe()) { // Probe down to tolerance
@ -306,31 +325,26 @@ static void _lcd_bed_tramming_get_next_position() {
ui.set_selection(true); ui.set_selection(true);
} }
#else // !BED_TRAMMING_USE_PROBE #endif // BED_TRAMMING_USE_PROBE
static void _lcd_goto_next_corner() {
line_to_z(BED_TRAMMING_Z_HOP);
// Select next corner coordinates
_lcd_bed_tramming_get_next_position();
line_to_current_position(manual_feedrate_mm_s.x);
line_to_z(BED_TRAMMING_HEIGHT);
if (++bed_corner >= available_points) bed_corner = 0;
}
#endif // !BED_TRAMMING_USE_PROBE
void _lcd_bed_tramming_homing() { void _lcd_bed_tramming_homing() {
_lcd_draw_homing(); if (!all_axes_homed() && TERN1(NEEDS_PROBE_DEPLOY, probe.deploy())) return;
if (!all_axes_homed()) return;
#if HAS_LEVELING // Disable leveling so the planner won't mess with us
menu_leveling_was_active = planner.leveling_active;
set_bed_leveling_enabled(false);
#endif
#if ENABLED(BED_TRAMMING_USE_PROBE) #if ENABLED(BED_TRAMMING_USE_PROBE)
_lcd_test_corners(); if (!tramming_done) _lcd_test_corners(); // May set tramming_done
if (tramming_done) ui.goto_previous_screen_no_defer(); if (tramming_done) {
ui.goto_previous_screen_no_defer();
TERN_(NEEDS_PROBE_DEPLOY, probe.stow(true));
}
tramming_done = true;
TERN_(HAS_LEVELING, set_bed_leveling_enabled(menu_leveling_was_active)); TERN_(HAS_LEVELING, set_bed_leveling_enabled(menu_leveling_was_active));
endstops.enable_z_probe(false); TERN_(BLTOUCH, endstops.enable_z_probe(false));
#else // !BED_TRAMMING_USE_PROBE #else // !BED_TRAMMING_USE_PROBE
@ -354,20 +368,28 @@ void _lcd_bed_tramming_homing() {
#endif // !BED_TRAMMING_USE_PROBE #endif // !BED_TRAMMING_USE_PROBE
} }
void _lcd_bed_tramming() { #if NEEDS_PROBE_DEPLOY
ui.defer_status_screen();
if (!all_axes_trusted()) { void deploy_probe() {
set_all_unhomed(); if (!tramming_done) probe.deploy(true);
queue.inject_P(G28_STR); ui.goto_screen([]{
if (ui.should_draw()) MenuItem_static::draw((LCD_HEIGHT - 1) / 2, GET_TEXT_F(MSG_MANUAL_DEPLOY));
if (!probe.deploy() && !tramming_done) _lcd_bed_tramming_homing();
});
} }
// Disable leveling so the planner won't mess with us #endif // NEEDS_PROBE_DEPLOY
#if HAS_LEVELING
menu_leveling_was_active = planner.leveling_active;
set_bed_leveling_enabled(false);
#endif
ui.goto_screen(_lcd_bed_tramming_homing); void _lcd_bed_tramming() {
TERN_(BED_TRAMMING_USE_PROBE, tramming_done = false);
ui.defer_status_screen();
set_all_unhomed();
queue.inject(TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR)));
ui.goto_screen([]{
_lcd_draw_homing();
if (!all_axes_homed()) return;
TERN(NEEDS_PROBE_DEPLOY, deploy_probe(), ui.goto_screen(_lcd_bed_tramming_homing));
});
} }
#endif // HAS_MARLINUI_MENU && LCD_BED_TRAMMING #endif // HAS_MARLINUI_MENU && LCD_BED_TRAMMING

View file

@ -500,11 +500,11 @@ void Probe::probe_error_stop() {
* *
* Return TRUE if the probe could not be deployed/stowed * Return TRUE if the probe could not be deployed/stowed
*/ */
bool Probe::set_deployed(const bool deploy) { bool Probe::set_deployed(const bool deploy, const bool no_return/*=false*/) {
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
DEBUG_POS("Probe::set_deployed", current_position); DEBUG_POS("Probe::set_deployed", current_position);
DEBUG_ECHOLNPGM("deploy: ", deploy); DEBUG_ECHOLNPGM("deploy=", deploy, " no_return=", no_return);
} }
if (endstops.z_probe_enabled == deploy) return false; if (endstops.z_probe_enabled == deploy) return false;
@ -557,7 +557,8 @@ bool Probe::set_deployed(const bool deploy) {
// If preheating is required before any probing... // If preheating is required before any probing...
TERN_(PREHEAT_BEFORE_PROBING, if (deploy) preheat_for_probing(PROBING_NOZZLE_TEMP, PROBING_BED_TEMP)); TERN_(PREHEAT_BEFORE_PROBING, if (deploy) preheat_for_probing(PROBING_NOZZLE_TEMP, PROBING_BED_TEMP));
do_blocking_move_to(old_xy); if (!no_return) do_blocking_move_to(old_xy); // Return to the original location unless handled externally
endstops.enable_z_probe(deploy); endstops.enable_z_probe(deploy);
return false; return false;
} }

View file

@ -90,7 +90,7 @@ public:
static void probe_error_stop(); static void probe_error_stop();
static bool set_deployed(const bool deploy); static bool set_deployed(const bool deploy, const bool no_return=false);
#if IS_KINEMATIC #if IS_KINEMATIC
@ -182,7 +182,7 @@ public:
static constexpr xyz_pos_t offset = xyz_pos_t(NUM_AXIS_ARRAY_1(0)); // See #16767 static constexpr xyz_pos_t offset = xyz_pos_t(NUM_AXIS_ARRAY_1(0)); // See #16767
static bool set_deployed(const bool) { return false; } static bool set_deployed(const bool, const bool=false) { return false; }
static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(rx, ry); } static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(rx, ry); }
@ -216,8 +216,8 @@ public:
static constexpr xy_pos_t offset_xy = xy_pos_t({ 0, 0 }); // See #16767 static constexpr xy_pos_t offset_xy = xy_pos_t({ 0, 0 }); // See #16767
#endif #endif
static bool deploy() { return set_deployed(true); } static bool deploy(const bool no_return=false) { return set_deployed(true, no_return); }
static bool stow() { return set_deployed(false); } static bool stow(const bool no_return=false) { return set_deployed(false, no_return); }
#if HAS_BED_PROBE || HAS_LEVELING #if HAS_BED_PROBE || HAS_LEVELING
#if IS_KINEMATIC #if IS_KINEMATIC