🚸 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:
* H Report the current BLTouch HS mode state and exit
* 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() {
#ifdef BLTOUCH_HS_MODE
const bool seenH = parser.seen_test('H'),
seenS = parser.seen('S');
if (seenH || seenS) {
#ifdef BLTOUCH_HS_MODE
if (seenS) bltouch.high_speed_mode = parser.value_bool();
SERIAL_ECHO_START();
SERIAL_ECHOPGM("BLTouch HS mode ");
serialprintln_onoff(bltouch.high_speed_mode);
#endif
return;
}
else {
probe.deploy();
#endif
probe.deploy(parser.boolval('R'));
TERN_(PROBE_TARE, probe.tare());
report_current_position();
}
}
/**
* M402: Deactivate and stow the Z probe
* R<bool> Remain in place after stowing (and before deactivating) the probe
*/
void GcodeSuite::M402() {
probe.stow();
probe.stow(parser.boolval('R'));
probe.move_z_after_probing();
report_current_position();
}

View file

@ -43,6 +43,10 @@
#define BED_TRAMMING_HEIGHT 0.0
#endif
#if BOTH(HAS_STOWABLE_PROBE, BED_TRAMMING_USE_PROBE) && DISABLED(BLTOUCH)
#define NEEDS_PROBE_DEPLOY 1
#endif
#if ENABLED(BED_TRAMMING_USE_PROBE)
#include "../../module/probe.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;
/**
* 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 (bed_corner >= available_points) bed_corner = 0; // Above max position -> move back to first corner
switch (bed_corner) {
case 0 ... 1:
// First two corners set explicitly by the configuration
current_position = lf; // Left front
switch (lco[bed_corner]) {
case RF: current_position.x = rb.x; break; // Right Front
case RB: current_position = rb; break; // Right Back
case LB: current_position.y = rb.y; break; // Left Back
case RF: corner_point.x = rb.x; break; // Right Front
case RB: corner_point = rb; break; // Right Back
case LB: corner_point.y = rb.y; break; // Left Back
}
break;
case 2:
// 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);
if ((lco[0] == LB && lco[1] == RB) || (lco[0] == RB && lco[1] == LB)) current_position.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] == RF && lco[1] == RB) || (lco[0] == RB && lco[1] == RF)) current_position.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 DISABLED(BED_TRAMMING_INCLUDE_CENTER) && ENABLED(BED_TRAMMING_USE_PROBE)
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)) corner_point.y = lf.y; // Front Center
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)) corner_point.x = lf.x; // Left Center
if ((lco[0] == LF && lco[1] == RF) || (lco[0] == RF && lco[1] == LF)) corner_point.y = rb.y; // Center Back
#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
#endif
break;
#if ENABLED(BED_TRAMMING_INCLUDE_CENTER)
case 3:
current_position.set(X_CENTER, Y_CENTER);
corner_point.set(X_CENTER, Y_CENTER);
break;
#endif
}
@ -136,23 +140,29 @@ static void _lcd_bed_tramming_get_next_position() {
else {
// Four-Corner Bed Tramming with optional center
if (TERN0(BED_TRAMMING_INCLUDE_CENTER, bed_corner == center_index)) {
current_position.set(X_CENTER, Y_CENTER);
TERN_(BED_TRAMMING_USE_PROBE, good_points--); // Decrement to allow one additional probe point
corner_point.set(X_CENTER, Y_CENTER);
}
else {
current_position = lf; // Left front
switch (lco[bed_corner]) {
case RF: current_position.x = rb.x; break; // Right Front
case RB: current_position = rb; break; // Right Back
case LB: current_position.y = rb.y; break; // Left Back
case RF: corner_point.x = rb.x; break; // Right Front
case RB: corner_point = rb; break; // Right 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)
#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(
GET_TEXT_F(TERN(HAS_LEVELING, MSG_BUTTON_LEVEL, MSG_BUTTON_DONE))
, 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)
);
}
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
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
@ -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.
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
}
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);
_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_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
_lcd_goto_next_corner(); // Goto corner
TERN_(BLTOUCH, if (bltouch.high_speed_mode) bltouch.deploy()); // Deploy in HIGH SPEED MODE
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);
}
#else // !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
#endif // BED_TRAMMING_USE_PROBE
void _lcd_bed_tramming_homing() {
_lcd_draw_homing();
if (!all_axes_homed()) return;
if (!all_axes_homed() && TERN1(NEEDS_PROBE_DEPLOY, probe.deploy())) 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)
_lcd_test_corners();
if (tramming_done) ui.goto_previous_screen_no_defer();
if (!tramming_done) _lcd_test_corners(); // May set tramming_done
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));
endstops.enable_z_probe(false);
TERN_(BLTOUCH, endstops.enable_z_probe(false));
#else // !BED_TRAMMING_USE_PROBE
@ -354,20 +368,28 @@ void _lcd_bed_tramming_homing() {
#endif // !BED_TRAMMING_USE_PROBE
}
void _lcd_bed_tramming() {
ui.defer_status_screen();
if (!all_axes_trusted()) {
set_all_unhomed();
queue.inject_P(G28_STR);
#if NEEDS_PROBE_DEPLOY
void deploy_probe() {
if (!tramming_done) probe.deploy(true);
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
#if HAS_LEVELING
menu_leveling_was_active = planner.leveling_active;
set_bed_leveling_enabled(false);
#endif
#endif // NEEDS_PROBE_DEPLOY
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

View file

@ -500,11 +500,11 @@ void Probe::probe_error_stop() {
*
* 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)) {
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;
@ -557,7 +557,8 @@ bool Probe::set_deployed(const bool deploy) {
// If preheating is required before any probing...
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);
return false;
}

View file

@ -90,7 +90,7 @@ public:
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
@ -182,7 +182,7 @@ public:
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); }
@ -216,8 +216,8 @@ public:
static constexpr xy_pos_t offset_xy = xy_pos_t({ 0, 0 }); // See #16767
#endif
static bool deploy() { return set_deployed(true); }
static bool stow() { return set_deployed(false); }
static bool deploy(const bool no_return=false) { return set_deployed(true, no_return); }
static bool stow(const bool no_return=false) { return set_deployed(false, no_return); }
#if HAS_BED_PROBE || HAS_LEVELING
#if IS_KINEMATIC