|
@@ -56,6 +56,13 @@
|
56
|
56
|
float last_z;
|
57
|
57
|
int good_points;
|
58
|
58
|
bool corner_probing_done, wait_for_probe;
|
|
59
|
+
|
|
60
|
+ #if HAS_MARLINUI_U8GLIB
|
|
61
|
+ #include "../dogm/marlinui_DOGM.h"
|
|
62
|
+ #endif
|
|
63
|
+ #define GOOD_POINTS_TO_STR(N) ui8tostr2(N)
|
|
64
|
+ #define LAST_Z_TO_STR(N) ftostr53_63(N) //ftostr42_52(N)
|
|
65
|
+
|
59
|
66
|
#endif
|
60
|
67
|
|
61
|
68
|
static_assert(LEVEL_CORNERS_Z_HOP >= 0, "LEVEL_CORNERS_Z_HOP must be >= 0. Please update your configuration.");
|
|
@@ -66,12 +73,89 @@ extern const char G28_STR[];
|
66
|
73
|
static bool leveling_was_active = false;
|
67
|
74
|
#endif
|
68
|
75
|
|
69
|
|
-static int8_t bed_corner;
|
|
76
|
+#ifndef LEVEL_CORNERS_LEVELING_ORDER
|
|
77
|
+ #define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, LB, RB } // Default
|
|
78
|
+ //#define LEVEL_CORNERS_LEVELING_ORDER { LF, LB, RF } // 3 hard-coded points
|
|
79
|
+ //#define LEVEL_CORNERS_LEVELING_ORDER { LF, RF } // 3-Point tramming - Rear
|
|
80
|
+ //#define LEVEL_CORNERS_LEVELING_ORDER { LF, LB } // 3-Point tramming - Right
|
|
81
|
+ //#define LEVEL_CORNERS_LEVELING_ORDER { RF, RB } // 3-Point tramming - Left
|
|
82
|
+ //#define LEVEL_CORNERS_LEVELING_ORDER { LB, RB } // 3-Point tramming - Front
|
|
83
|
+#endif
|
|
84
|
+
|
|
85
|
+#define LF 1
|
|
86
|
+#define RF 2
|
|
87
|
+#define RB 3
|
|
88
|
+#define LB 4
|
|
89
|
+constexpr int lco[] = LEVEL_CORNERS_LEVELING_ORDER;
|
|
90
|
+constexpr bool level_corners_3_points = COUNT(lco) == 2;
|
|
91
|
+static_assert(level_corners_3_points || COUNT(lco) == 4, "LEVEL_CORNERS_LEVELING_ORDER must have exactly 2 or 4 corners.");
|
|
92
|
+
|
|
93
|
+constexpr int lcodiff = abs(lco[0] - lco[1]);
|
|
94
|
+static_assert(COUNT(lco) == 4 || lcodiff == 1 || lcodiff == 3, "The first two LEVEL_CORNERS_LEVELING_ORDER corners must be on the same edge.");
|
70
|
95
|
|
|
96
|
+constexpr int nr_edge_points = level_corners_3_points ? 3 : 4;
|
|
97
|
+constexpr int available_points = nr_edge_points + ENABLED(LEVEL_CENTER_TOO);
|
|
98
|
+constexpr int center_index = TERN(LEVEL_CENTER_TOO, available_points - 1, -1);
|
71
|
99
|
constexpr float inset_lfrb[4] = LEVEL_CORNERS_INSET_LFRB;
|
72
|
100
|
constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1] },
|
73
|
101
|
rb { (X_MAX_BED) - inset_lfrb[2], (Y_MAX_BED) - inset_lfrb[3] };
|
74
|
102
|
|
|
103
|
+static int8_t bed_corner;
|
|
104
|
+
|
|
105
|
+/**
|
|
106
|
+ * Select next corner coordinates
|
|
107
|
+ */
|
|
108
|
+static inline void _lcd_level_bed_corners_get_next_position() {
|
|
109
|
+
|
|
110
|
+ if (level_corners_3_points) {
|
|
111
|
+ if (bed_corner >= available_points) bed_corner = 0; // Above max position -> move back to first corner
|
|
112
|
+ switch (bed_corner) {
|
|
113
|
+ case 0 ... 1:
|
|
114
|
+ // First two corners set explicitly by the configuration
|
|
115
|
+ current_position = lf; // Left front
|
|
116
|
+ switch (lco[bed_corner]) {
|
|
117
|
+ case RF: current_position.x = rb.x; break; // Right Front
|
|
118
|
+ case RB: current_position = rb; break; // Right Back
|
|
119
|
+ case LB: current_position.y = rb.y; break; // Left Back
|
|
120
|
+ }
|
|
121
|
+ break;
|
|
122
|
+
|
|
123
|
+ case 2:
|
|
124
|
+ // Determine which edge to probe for 3rd point
|
|
125
|
+ current_position.set(lf.x + (rb.x - lf.x) / 2, lf.y + (rb.y - lf.y) / 2);
|
|
126
|
+ if ((lco[0] == LB && lco[1] == RB) || (lco[0] == RB && lco[1] == LB)) current_position.y = lf.y; // Front Center
|
|
127
|
+ if ((lco[0] == LF && lco[1] == LB) || (lco[0] == LB && lco[1] == LF)) current_position.x = rb.x; // Center Right
|
|
128
|
+ if ((lco[0] == RF && lco[1] == RB) || (lco[0] == RB && lco[1] == RF)) current_position.x = lf.x; // Left Center
|
|
129
|
+ if ((lco[0] == LF && lco[1] == RF) || (lco[0] == RF && lco[1] == LF)) current_position.y = rb.y; // Center Back
|
|
130
|
+ #if DISABLED(LEVEL_CENTER_TOO) && ENABLED(LEVEL_CORNERS_USE_PROBE)
|
|
131
|
+ bed_corner++; // Must increment the count to ensure it resets the loop if the 3rd point is out of tolerance
|
|
132
|
+ #endif
|
|
133
|
+ break;
|
|
134
|
+
|
|
135
|
+ #if ENABLED(LEVEL_CENTER_TOO)
|
|
136
|
+ case 3:
|
|
137
|
+ current_position.set(X_CENTER, Y_CENTER);
|
|
138
|
+ break;
|
|
139
|
+ #endif
|
|
140
|
+ }
|
|
141
|
+ }
|
|
142
|
+ else {
|
|
143
|
+ // Four-Corner Bed Tramming with optional center
|
|
144
|
+ if (TERN0(LEVEL_CENTER_TOO, bed_corner == center_index)) {
|
|
145
|
+ current_position.set(X_CENTER, Y_CENTER);
|
|
146
|
+ TERN_(LEVEL_CORNERS_USE_PROBE, good_points--); // Decrement to allow one additional probe point
|
|
147
|
+ }
|
|
148
|
+ else {
|
|
149
|
+ current_position = lf; // Left front
|
|
150
|
+ switch (lco[bed_corner]) {
|
|
151
|
+ case RF: current_position.x = rb.x; break; // Right front
|
|
152
|
+ case RB: current_position = rb; break; // Right rear
|
|
153
|
+ case LB: current_position.y = rb.y; break; // Left rear
|
|
154
|
+ }
|
|
155
|
+ }
|
|
156
|
+ }
|
|
157
|
+}
|
|
158
|
+
|
75
|
159
|
/**
|
76
|
160
|
* Level corners, starting in the front-left corner.
|
77
|
161
|
*/
|
|
@@ -82,8 +166,37 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
|
82
|
166
|
VALIDATE_POINT(lf.x, Y_CENTER, "left"); VALIDATE_POINT(X_CENTER, lf.y, "front");
|
83
|
167
|
VALIDATE_POINT(rb.x, Y_CENTER, "right"); VALIDATE_POINT(X_CENTER, rb.y, "back");
|
84
|
168
|
|
|
169
|
+ #ifndef PAGE_CONTAINS
|
|
170
|
+ #define PAGE_CONTAINS(...) true
|
|
171
|
+ #endif
|
|
172
|
+
|
85
|
173
|
void _lcd_draw_probing() {
|
86
|
|
- if (ui.should_draw()) MenuItem_static::draw((LCD_HEIGHT - 1) / 2, GET_TEXT(MSG_PROBING_MESH));
|
|
174
|
+ if (!ui.should_draw()) return;
|
|
175
|
+
|
|
176
|
+ TERN_(HAS_MARLINUI_U8GLIB, ui.set_font(FONT_MENU)); // Set up the font for extra info
|
|
177
|
+
|
|
178
|
+ MenuItem_static::draw(0, GET_TEXT(MSG_PROBING_MESH), SS_INVERT); // "Probing Mesh" heading
|
|
179
|
+
|
|
180
|
+ uint8_t cy = LCD_HEIGHT - 1, y = LCD_ROW_Y(cy);
|
|
181
|
+
|
|
182
|
+ // Display # of good points found vs total needed
|
|
183
|
+ if (PAGE_CONTAINS(y - (MENU_FONT_HEIGHT), y)) {
|
|
184
|
+ SETCURSOR(0, cy);
|
|
185
|
+ lcd_put_u8str_P(GET_TEXT(MSG_LEVEL_CORNERS_GOOD_POINTS));
|
|
186
|
+ lcd_put_u8str(GOOD_POINTS_TO_STR(good_points));
|
|
187
|
+ lcd_put_wchar('/');
|
|
188
|
+ lcd_put_u8str(GOOD_POINTS_TO_STR(nr_edge_points));
|
|
189
|
+ }
|
|
190
|
+
|
|
191
|
+ --cy;
|
|
192
|
+ y -= MENU_FONT_HEIGHT;
|
|
193
|
+
|
|
194
|
+ // Display the Last Z value
|
|
195
|
+ if (PAGE_CONTAINS(y - (MENU_FONT_HEIGHT), y)) {
|
|
196
|
+ SETCURSOR(0, cy);
|
|
197
|
+ lcd_put_u8str_P(GET_TEXT(MSG_LEVEL_CORNERS_LAST_Z));
|
|
198
|
+ lcd_put_u8str(LAST_Z_TO_STR(last_z));
|
|
199
|
+ }
|
87
|
200
|
}
|
88
|
201
|
|
89
|
202
|
void _lcd_draw_raise() {
|
|
@@ -112,7 +225,7 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
|
112
|
225
|
bool _lcd_level_bed_corners_probe(bool verify=false) {
|
113
|
226
|
if (verify) do_blocking_move_to_z(current_position.z + LEVEL_CORNERS_Z_HOP); // do clearance if needed
|
114
|
227
|
TERN_(BLTOUCH_SLOW_MODE, bltouch.deploy()); // Deploy in LOW SPEED MODE on every probe action
|
115
|
|
- do_blocking_move_to_z(last_z - LEVEL_CORNERS_PROBE_TOLERANCE, manual_feedrate_mm_s.z); // Move down to lower tolerance
|
|
228
|
+ do_blocking_move_to_z(last_z - LEVEL_CORNERS_PROBE_TOLERANCE, MMM_TO_MMS(Z_PROBE_SPEED_SLOW)); // Move down to lower tolerance
|
116
|
229
|
if (TEST(endstops.trigger_state(), TERN(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_MIN, Z_MIN_PROBE))) { // check if probe triggered
|
117
|
230
|
endstops.hit_on_purpose();
|
118
|
231
|
set_current_from_steppers_for_axis(Z_AXIS);
|
|
@@ -149,25 +262,18 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
|
149
|
262
|
}
|
150
|
263
|
|
151
|
264
|
void _lcd_test_corners() {
|
152
|
|
- ui.goto_screen(_lcd_draw_probing);
|
153
|
|
- bed_corner = TERN(LEVEL_CENTER_TOO, 4, 0);
|
|
265
|
+ bed_corner = TERN(LEVEL_CENTER_TOO, center_index, 0);
|
154
|
266
|
last_z = LEVEL_CORNERS_HEIGHT;
|
155
|
267
|
endstops.enable_z_probe(true);
|
156
|
268
|
good_points = 0;
|
157
|
|
-
|
|
269
|
+ ui.goto_screen(_lcd_draw_probing);
|
158
|
270
|
do {
|
|
271
|
+ ui.refresh(LCDVIEW_REDRAW_NOW);
|
|
272
|
+ _lcd_draw_probing(); //update screen with # of good points
|
159
|
273
|
do_blocking_move_to_z(current_position.z + LEVEL_CORNERS_Z_HOP); // clearance
|
160
|
|
- // Select next corner coordinates
|
161
|
|
- xy_pos_t plf = lf - probe.offset_xy, prb = rb - probe.offset_xy;
|
162
|
|
- switch (bed_corner) {
|
163
|
|
- case 0: current_position = plf; break; // copy xy
|
164
|
|
- case 1: current_position.x = prb.x; break;
|
165
|
|
- case 2: current_position.y = prb.y; break;
|
166
|
|
- case 3: current_position.x = plf.x; break;
|
167
|
|
- #if ENABLED(LEVEL_CENTER_TOO)
|
168
|
|
- case 4: current_position.set(X_CENTER - probe.offset_xy.x, Y_CENTER - probe.offset_xy.y); break;
|
169
|
|
- #endif
|
170
|
|
- }
|
|
274
|
+
|
|
275
|
+ _lcd_level_bed_corners_get_next_position(); // Select next corner coordinates
|
|
276
|
+ current_position -= probe.offset_xy; // Account for probe offsets
|
171
|
277
|
do_blocking_move_to_xy(current_position); // Goto corner
|
172
|
278
|
|
173
|
279
|
if (!_lcd_level_bed_corners_probe()) { // Probe down to tolerance
|
|
@@ -185,10 +291,10 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
|
185
|
291
|
return;
|
186
|
292
|
}
|
187
|
293
|
|
188
|
|
- if (bed_corner != 4) good_points++; // ignore center
|
|
294
|
+ if (bed_corner != center_index) good_points++; // ignore center
|
189
|
295
|
if (++bed_corner > 3) bed_corner = 0;
|
190
|
296
|
|
191
|
|
- } while (good_points < 4); // loop until all corners whitin tolerance
|
|
297
|
+ } while (good_points < nr_edge_points); // loop until all points within tolerance
|
192
|
298
|
|
193
|
299
|
ui.goto_screen(_lcd_draw_level_prompt); // prompt for bed leveling
|
194
|
300
|
ui.set_selection(true);
|
|
@@ -198,18 +304,13 @@ constexpr xy_pos_t lf { (X_MIN_BED) + inset_lfrb[0], (Y_MIN_BED) + inset_lfrb[1]
|
198
|
304
|
|
199
|
305
|
static inline void _lcd_goto_next_corner() {
|
200
|
306
|
line_to_z(LEVEL_CORNERS_Z_HOP);
|
201
|
|
- switch (bed_corner) {
|
202
|
|
- case 0: current_position = lf; break; // copy xy
|
203
|
|
- case 1: current_position.x = rb.x; break;
|
204
|
|
- case 2: current_position.y = rb.y; break;
|
205
|
|
- case 3: current_position.x = lf.x; break;
|
206
|
|
- #if ENABLED(LEVEL_CENTER_TOO)
|
207
|
|
- case 4: current_position.set(X_CENTER, Y_CENTER); break;
|
208
|
|
- #endif
|
209
|
|
- }
|
|
307
|
+
|
|
308
|
+ // Select next corner coordinates
|
|
309
|
+ _lcd_level_bed_corners_get_next_position();
|
|
310
|
+
|
210
|
311
|
line_to_current_position(manual_feedrate_mm_s.x);
|
211
|
312
|
line_to_z(LEVEL_CORNERS_HEIGHT);
|
212
|
|
- if (++bed_corner > 3 + ENABLED(LEVEL_CENTER_TOO)) bed_corner = 0;
|
|
313
|
+ if (++bed_corner >= available_points) bed_corner = 0;
|
213
|
314
|
}
|
214
|
315
|
|
215
|
316
|
#endif // !LEVEL_CORNERS_USE_PROBE
|