Skip to content

Commit bfbf780

Browse files
Farva42thinkyhead
andcommitted
🚸 Fix / improve LCD_BED_TRAMMING (MarlinFirmware#25425)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
1 parent a6812c5 commit bfbf780

File tree

4 files changed

+105
-79
lines changed

4 files changed

+105
-79
lines changed

Marlin/src/gcode/probe/M401_M402.cpp

+15-12
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,33 @@
3838
* With BLTOUCH_HS_MODE:
3939
* H Report the current BLTouch HS mode state and exit
4040
* S<bool> Set High Speed (HS) Mode and exit without deploy
41+
*
42+
* R<bool> Remain in place after deploying (and before activating) the probe
4143
*/
4244
void GcodeSuite::M401() {
43-
const bool seenH = parser.seen_test('H'),
44-
seenS = parser.seen('S');
45-
if (seenH || seenS) {
46-
#ifdef BLTOUCH_HS_MODE
45+
#ifdef BLTOUCH_HS_MODE
46+
const bool seenH = parser.seen_test('H'),
47+
seenS = parser.seen('S');
48+
if (seenH || seenS) {
4749
if (seenS) bltouch.high_speed_mode = parser.value_bool();
4850
SERIAL_ECHO_START();
4951
SERIAL_ECHOPGM("BLTouch HS mode ");
5052
serialprintln_onoff(bltouch.high_speed_mode);
51-
#endif
52-
}
53-
else {
54-
probe.deploy();
55-
TERN_(PROBE_TARE, probe.tare());
56-
report_current_position();
57-
}
53+
return;
54+
}
55+
#endif
56+
57+
probe.deploy(parser.boolval('R'));
58+
TERN_(PROBE_TARE, probe.tare());
59+
report_current_position();
5860
}
5961

6062
/**
6163
* M402: Deactivate and stow the Z probe
64+
* R<bool> Remain in place after stowing (and before deactivating) the probe
6265
*/
6366
void GcodeSuite::M402() {
64-
probe.stow();
67+
probe.stow(parser.boolval('R'));
6568
probe.move_z_after_probing();
6669
report_current_position();
6770
}

Marlin/src/lcd/menu/menu_bed_tramming.cpp

+82-60
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
#define BED_TRAMMING_HEIGHT 0.0
4444
#endif
4545

46+
#if BOTH(HAS_STOWABLE_PROBE, BED_TRAMMING_USE_PROBE) && DISABLED(BLTOUCH)
47+
#define NEEDS_PROBE_DEPLOY 1
48+
#endif
49+
4650
#if ENABLED(BED_TRAMMING_USE_PROBE)
4751
#include "../../module/probe.h"
4852
#include "../../module/endstops.h"
@@ -97,62 +101,68 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
97101
static int8_t bed_corner;
98102

99103
/**
100-
* Select next corner coordinates
104+
* Move to the next corner coordinates
101105
*/
102-
static void _lcd_bed_tramming_get_next_position() {
106+
static void _lcd_goto_next_corner() {
107+
xy_pos_t corner_point = lf; // Left front
103108

104109
if (tramming_3_points) {
105110
if (bed_corner >= available_points) bed_corner = 0; // Above max position -> move back to first corner
106111
switch (bed_corner) {
107112
case 0 ... 1:
108113
// First two corners set explicitly by the configuration
109-
current_position = lf; // Left front
110114
switch (lco[bed_corner]) {
111-
case RF: current_position.x = rb.x; break; // Right Front
112-
case RB: current_position = rb; break; // Right Back
113-
case LB: current_position.y = rb.y; break; // Left Back
115+
case RF: corner_point.x = rb.x; break; // Right Front
116+
case RB: corner_point = rb; break; // Right Back
117+
case LB: corner_point.y = rb.y; break; // Left Back
114118
}
115119
break;
116120

117121
case 2:
118122
// Determine which edge to probe for 3rd point
119-
current_position.set(lf.x + (rb.x - lf.x) / 2, lf.y + (rb.y - lf.y) / 2);
120-
if ((lco[0] == LB && lco[1] == RB) || (lco[0] == RB && lco[1] == LB)) current_position.y = lf.y; // Front Center
121-
if ((lco[0] == LF && lco[1] == LB) || (lco[0] == LB && lco[1] == LF)) current_position.x = rb.x; // Center Right
122-
if ((lco[0] == RF && lco[1] == RB) || (lco[0] == RB && lco[1] == RF)) current_position.x = lf.x; // Left Center
123-
if ((lco[0] == LF && lco[1] == RF) || (lco[0] == RF && lco[1] == LF)) current_position.y = rb.y; // Center Back
124-
#if DISABLED(BED_TRAMMING_INCLUDE_CENTER) && ENABLED(BED_TRAMMING_USE_PROBE)
123+
corner_point.set(lf.x + (rb.x - lf.x) / 2, lf.y + (rb.y - lf.y) / 2);
124+
if ((lco[0] == LB && lco[1] == RB) || (lco[0] == RB && lco[1] == LB)) corner_point.y = lf.y; // Front Center
125+
if ((lco[0] == LF && lco[1] == LB) || (lco[0] == LB && lco[1] == LF)) corner_point.x = rb.x; // Center Right
126+
if ((lco[0] == RF && lco[1] == RB) || (lco[0] == RB && lco[1] == RF)) corner_point.x = lf.x; // Left Center
127+
if ((lco[0] == LF && lco[1] == RF) || (lco[0] == RF && lco[1] == LF)) corner_point.y = rb.y; // Center Back
128+
#if ENABLED(BED_TRAMMING_USE_PROBE) && DISABLED(BED_TRAMMING_INCLUDE_CENTER)
125129
bed_corner++; // Must increment the count to ensure it resets the loop if the 3rd point is out of tolerance
126130
#endif
127131
break;
128132

129133
#if ENABLED(BED_TRAMMING_INCLUDE_CENTER)
130134
case 3:
131-
current_position.set(X_CENTER, Y_CENTER);
135+
corner_point.set(X_CENTER, Y_CENTER);
132136
break;
133137
#endif
134138
}
135139
}
136140
else {
137141
// Four-Corner Bed Tramming with optional center
138142
if (TERN0(BED_TRAMMING_INCLUDE_CENTER, bed_corner == center_index)) {
139-
current_position.set(X_CENTER, Y_CENTER);
140-
TERN_(BED_TRAMMING_USE_PROBE, good_points--); // Decrement to allow one additional probe point
143+
corner_point.set(X_CENTER, Y_CENTER);
141144
}
142145
else {
143-
current_position = lf; // Left front
144146
switch (lco[bed_corner]) {
145-
case RF: current_position.x = rb.x; break; // Right Front
146-
case RB: current_position = rb; break; // Right Back
147-
case LB: current_position.y = rb.y; break; // Left Back
147+
case RF: corner_point.x = rb.x; break; // Right Front
148+
case RB: corner_point = rb; break; // Right Back
149+
case LB: corner_point.y = rb.y; break; // Left Back
148150
}
149151
}
150152
}
153+
154+
float z = BED_TRAMMING_Z_HOP;
155+
#if BOTH(BED_TRAMMING_USE_PROBE, BLTOUCH)
156+
z += bltouch.z_extra_clearance();
157+
#endif
158+
line_to_z(z);
159+
do_blocking_move_to_xy(DIFF_TERN(BED_TRAMMING_USE_PROBE, corner_point, probe.offset_xy), manual_feedrate_mm_s.x);
160+
#if DISABLED(BED_TRAMMING_USE_PROBE)
161+
line_to_z(BED_TRAMMING_HEIGHT);
162+
if (++bed_corner >= available_points) bed_corner = 0;
163+
#endif
151164
}
152165

153-
/**
154-
* Level corners, starting in the front-left corner.
155-
*/
156166
#if ENABLED(BED_TRAMMING_USE_PROBE)
157167

158168
#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() {
210220
MenuItem_confirm::select_screen(
211221
GET_TEXT_F(TERN(HAS_LEVELING, MSG_BUTTON_LEVEL, MSG_BUTTON_DONE))
212222
, TERN(HAS_LEVELING, GET_TEXT_F(MSG_BUTTON_BACK), nullptr)
213-
, []{ queue.inject(TERN(HAS_LEVELING, F("G29N"), FPSTR(G28_STR))); ui.return_to_status(); }
214-
, TERN(HAS_LEVELING, ui.goto_previous_screen_no_defer, []{})
223+
, []{
224+
tramming_done = true;
225+
queue.inject(TERN(HAS_LEVELING, F("G29N"), FPSTR(G28_STR)));
226+
ui.goto_previous_screen_no_defer();
227+
}
228+
, []{
229+
tramming_done = true;
230+
TERN_(HAS_LEVELING, ui.goto_previous_screen_no_defer());
231+
TERN_(NEEDS_PROBE_DEPLOY, probe.stow(true));
232+
}
215233
, GET_TEXT_F(MSG_BED_TRAMMING_IN_RANGE)
216234
);
217235
}
218236

219-
bool _lcd_bed_tramming_probe(bool verify=false) {
237+
bool _lcd_bed_tramming_probe(const bool verify=false) {
220238
if (verify) line_to_z(BED_TRAMMING_Z_HOP); // do clearance if needed
221239
TERN_(BLTOUCH, if (!bltouch.high_speed_mode) bltouch.deploy()); // Deploy in LOW SPEED MODE on every probe action
222240
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() {
232250
last_z = current_position.z; // Above tolerance. Set a new Z for subsequent corners.
233251
good_points = 0; // ...and start over
234252
}
253+
254+
// Raise the probe after the last point to give clearance for stow
255+
if (TERN0(NEEDS_PROBE_DEPLOY, good_points == nr_edge_points - 1))
256+
line_to_z(BED_TRAMMING_Z_HOP);
257+
235258
return true; // probe triggered
236259
}
237260
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() {
267290
ui.refresh(LCDVIEW_REDRAW_NOW);
268291
_lcd_draw_probing(); // update screen with # of good points
269292

270-
line_to_z(current_position.z + BED_TRAMMING_Z_HOP + TERN0(BLTOUCH, bltouch.z_extra_clearance())); // clearance
271-
272-
_lcd_bed_tramming_get_next_position(); // Select next corner coordinates
273-
current_position -= probe.offset_xy; // Account for probe offsets
274-
do_blocking_move_to_xy(current_position); // Goto corner
293+
_lcd_goto_next_corner(); // Goto corner
275294

276295
TERN_(BLTOUCH, if (bltouch.high_speed_mode) bltouch.deploy()); // Deploy in HIGH SPEED MODE
277296
if (!_lcd_bed_tramming_probe()) { // Probe down to tolerance
@@ -306,31 +325,26 @@ static void _lcd_bed_tramming_get_next_position() {
306325
ui.set_selection(true);
307326
}
308327

309-
#else // !BED_TRAMMING_USE_PROBE
310-
311-
static void _lcd_goto_next_corner() {
312-
line_to_z(BED_TRAMMING_Z_HOP);
313-
314-
// Select next corner coordinates
315-
_lcd_bed_tramming_get_next_position();
316-
317-
line_to_current_position(manual_feedrate_mm_s.x);
318-
line_to_z(BED_TRAMMING_HEIGHT);
319-
if (++bed_corner >= available_points) bed_corner = 0;
320-
}
321-
322-
#endif // !BED_TRAMMING_USE_PROBE
328+
#endif // BED_TRAMMING_USE_PROBE
323329

324330
void _lcd_bed_tramming_homing() {
325-
_lcd_draw_homing();
326-
if (!all_axes_homed()) return;
331+
if (!all_axes_homed() && TERN1(NEEDS_PROBE_DEPLOY, probe.deploy())) return;
332+
333+
#if HAS_LEVELING // Disable leveling so the planner won't mess with us
334+
menu_leveling_was_active = planner.leveling_active;
335+
set_bed_leveling_enabled(false);
336+
#endif
327337

328338
#if ENABLED(BED_TRAMMING_USE_PROBE)
329339

330-
_lcd_test_corners();
331-
if (tramming_done) ui.goto_previous_screen_no_defer();
340+
if (!tramming_done) _lcd_test_corners(); // May set tramming_done
341+
if (tramming_done) {
342+
ui.goto_previous_screen_no_defer();
343+
TERN_(NEEDS_PROBE_DEPLOY, probe.stow(true));
344+
}
345+
tramming_done = true;
332346
TERN_(HAS_LEVELING, set_bed_leveling_enabled(menu_leveling_was_active));
333-
endstops.enable_z_probe(false);
347+
TERN_(BLTOUCH, endstops.enable_z_probe(false));
334348

335349
#else // !BED_TRAMMING_USE_PROBE
336350

@@ -354,20 +368,28 @@ void _lcd_bed_tramming_homing() {
354368
#endif // !BED_TRAMMING_USE_PROBE
355369
}
356370

357-
void _lcd_bed_tramming() {
358-
ui.defer_status_screen();
359-
if (!all_axes_trusted()) {
360-
set_all_unhomed();
361-
queue.inject_P(G28_STR);
371+
#if NEEDS_PROBE_DEPLOY
372+
373+
void deploy_probe() {
374+
if (!tramming_done) probe.deploy(true);
375+
ui.goto_screen([]{
376+
if (ui.should_draw()) MenuItem_static::draw((LCD_HEIGHT - 1) / 2, GET_TEXT_F(MSG_MANUAL_DEPLOY));
377+
if (!probe.deploy() && !tramming_done) _lcd_bed_tramming_homing();
378+
});
362379
}
363380

364-
// Disable leveling so the planner won't mess with us
365-
#if HAS_LEVELING
366-
menu_leveling_was_active = planner.leveling_active;
367-
set_bed_leveling_enabled(false);
368-
#endif
381+
#endif // NEEDS_PROBE_DEPLOY
369382

370-
ui.goto_screen(_lcd_bed_tramming_homing);
383+
void _lcd_bed_tramming() {
384+
TERN_(BED_TRAMMING_USE_PROBE, tramming_done = false);
385+
ui.defer_status_screen();
386+
set_all_unhomed();
387+
queue.inject(TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR)));
388+
ui.goto_screen([]{
389+
_lcd_draw_homing();
390+
if (!all_axes_homed()) return;
391+
TERN(NEEDS_PROBE_DEPLOY, deploy_probe(), ui.goto_screen(_lcd_bed_tramming_homing));
392+
});
371393
}
372394

373395
#endif // HAS_MARLINUI_MENU && LCD_BED_TRAMMING

Marlin/src/module/probe.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,11 @@ void Probe::probe_error_stop() {
500500
*
501501
* Return TRUE if the probe could not be deployed/stowed
502502
*/
503-
bool Probe::set_deployed(const bool deploy) {
503+
bool Probe::set_deployed(const bool deploy, const bool no_return/*=false*/) {
504504

505505
if (DEBUGGING(LEVELING)) {
506506
DEBUG_POS("Probe::set_deployed", current_position);
507-
DEBUG_ECHOLNPGM("deploy: ", deploy);
507+
DEBUG_ECHOLNPGM("deploy=", deploy, " no_return=", no_return);
508508
}
509509

510510
if (endstops.z_probe_enabled == deploy) return false;
@@ -557,7 +557,8 @@ bool Probe::set_deployed(const bool deploy) {
557557
// If preheating is required before any probing...
558558
TERN_(PREHEAT_BEFORE_PROBING, if (deploy) preheat_for_probing(PROBING_NOZZLE_TEMP, PROBING_BED_TEMP));
559559

560-
do_blocking_move_to(old_xy);
560+
if (!no_return) do_blocking_move_to(old_xy); // Return to the original location unless handled externally
561+
561562
endstops.enable_z_probe(deploy);
562563
return false;
563564
}

Marlin/src/module/probe.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class Probe {
9090

9191
static void probe_error_stop();
9292

93-
static bool set_deployed(const bool deploy);
93+
static bool set_deployed(const bool deploy, const bool no_return=false);
9494

9595
#if IS_KINEMATIC
9696

@@ -182,7 +182,7 @@ class Probe {
182182

183183
static constexpr xyz_pos_t offset = xyz_pos_t(NUM_AXIS_ARRAY_1(0)); // See #16767
184184

185-
static bool set_deployed(const bool) { return false; }
185+
static bool set_deployed(const bool, const bool=false) { return false; }
186186

187187
static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(rx, ry); }
188188

@@ -216,8 +216,8 @@ class Probe {
216216
static constexpr xy_pos_t offset_xy = xy_pos_t({ 0, 0 }); // See #16767
217217
#endif
218218

219-
static bool deploy() { return set_deployed(true); }
220-
static bool stow() { return set_deployed(false); }
219+
static bool deploy(const bool no_return=false) { return set_deployed(true, no_return); }
220+
static bool stow(const bool no_return=false) { return set_deployed(false, no_return); }
221221

222222
#if HAS_BED_PROBE || HAS_LEVELING
223223
#if IS_KINEMATIC

0 commit comments

Comments
 (0)