|
@@ -346,6 +346,9 @@ int fanSpeed = 0;
|
346
|
346
|
float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
|
347
|
347
|
float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
|
348
|
348
|
float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
|
|
349
|
+ #ifdef ENABLE_AUTO_BED_LEVELING
|
|
350
|
+ float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS];
|
|
351
|
+ #endif
|
349
|
352
|
#endif
|
350
|
353
|
|
351
|
354
|
#ifdef SCARA
|
|
@@ -1058,6 +1061,8 @@ static void axis_is_at_home(int axis) {
|
1058
|
1061
|
|
1059
|
1062
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
1060
|
1063
|
#ifdef AUTO_BED_LEVELING_GRID
|
|
1064
|
+
|
|
1065
|
+#ifndef DELTA
|
1061
|
1066
|
static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
|
1062
|
1067
|
{
|
1063
|
1068
|
vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
|
|
@@ -1080,6 +1085,7 @@ static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
|
1080
|
1085
|
|
1081
|
1086
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
1082
|
1087
|
}
|
|
1088
|
+#endif
|
1083
|
1089
|
|
1084
|
1090
|
#else // not AUTO_BED_LEVELING_GRID
|
1085
|
1091
|
|
|
@@ -1113,6 +1119,27 @@ static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float
|
1113
|
1119
|
#endif // AUTO_BED_LEVELING_GRID
|
1114
|
1120
|
|
1115
|
1121
|
static void run_z_probe() {
|
|
1122
|
+ #ifdef DELTA
|
|
1123
|
+
|
|
1124
|
+ float start_z = current_position[Z_AXIS];
|
|
1125
|
+ long start_steps = st_get_position(Z_AXIS);
|
|
1126
|
+
|
|
1127
|
+ // move down slowly until you find the bed
|
|
1128
|
+ feedrate = homing_feedrate[Z_AXIS] / 4;
|
|
1129
|
+ destination[Z_AXIS] = -10;
|
|
1130
|
+ prepare_move_raw();
|
|
1131
|
+ st_synchronize();
|
|
1132
|
+ endstops_hit_on_purpose();
|
|
1133
|
+
|
|
1134
|
+ // we have to let the planner know where we are right now as it is not where we said to go.
|
|
1135
|
+ long stop_steps = st_get_position(Z_AXIS);
|
|
1136
|
+ float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
|
|
1137
|
+ current_position[Z_AXIS] = mm;
|
|
1138
|
+ calculate_delta(current_position);
|
|
1139
|
+ plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
|
|
1140
|
+
|
|
1141
|
+ #else
|
|
1142
|
+
|
1116
|
1143
|
plan_bed_level_matrix.set_to_identity();
|
1117
|
1144
|
feedrate = homing_feedrate[Z_AXIS];
|
1118
|
1145
|
|
|
@@ -1139,11 +1166,25 @@ static void run_z_probe() {
|
1139
|
1166
|
current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
|
1140
|
1167
|
// make sure the planner knows where we are as it may be a bit different than we last said to move to
|
1141
|
1168
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
|
1169
|
+
|
|
1170
|
+ #endif
|
1142
|
1171
|
}
|
1143
|
1172
|
|
1144
|
1173
|
static void do_blocking_move_to(float x, float y, float z) {
|
1145
|
1174
|
float oldFeedRate = feedrate;
|
1146
|
1175
|
|
|
1176
|
+#ifdef DELTA
|
|
1177
|
+
|
|
1178
|
+ feedrate = XY_TRAVEL_SPEED;
|
|
1179
|
+
|
|
1180
|
+ destination[X_AXIS] = x;
|
|
1181
|
+ destination[Y_AXIS] = y;
|
|
1182
|
+ destination[Z_AXIS] = z;
|
|
1183
|
+ prepare_move_raw();
|
|
1184
|
+ st_synchronize();
|
|
1185
|
+
|
|
1186
|
+#else
|
|
1187
|
+
|
1147
|
1188
|
feedrate = homing_feedrate[Z_AXIS];
|
1148
|
1189
|
|
1149
|
1190
|
current_position[Z_AXIS] = z;
|
|
@@ -1157,6 +1198,8 @@ static void do_blocking_move_to(float x, float y, float z) {
|
1157
|
1198
|
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
|
1158
|
1199
|
st_synchronize();
|
1159
|
1200
|
|
|
1201
|
+#endif
|
|
1202
|
+
|
1160
|
1203
|
feedrate = oldFeedRate;
|
1161
|
1204
|
}
|
1162
|
1205
|
|
|
@@ -1196,7 +1239,40 @@ static void engage_z_probe() {
|
1196
|
1239
|
servos[servo_endstops[Z_AXIS]].detach();
|
1197
|
1240
|
#endif
|
1198
|
1241
|
}
|
|
1242
|
+ #elif defined(Z_PROBE_ALLEN_KEY)
|
|
1243
|
+ feedrate = homing_feedrate[X_AXIS];
|
|
1244
|
+
|
|
1245
|
+ // Move to the start position to initiate deployment
|
|
1246
|
+ destination[X_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_X;
|
|
1247
|
+ destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_Y;
|
|
1248
|
+ destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_Z;
|
|
1249
|
+ prepare_move_raw();
|
|
1250
|
+
|
|
1251
|
+ // Home X to touch the belt
|
|
1252
|
+ feedrate = homing_feedrate[X_AXIS]/10;
|
|
1253
|
+ destination[X_AXIS] = 0;
|
|
1254
|
+ prepare_move_raw();
|
|
1255
|
+
|
|
1256
|
+ // Home Y for safety
|
|
1257
|
+ feedrate = homing_feedrate[X_AXIS]/2;
|
|
1258
|
+ destination[Y_AXIS] = 0;
|
|
1259
|
+ prepare_move_raw();
|
|
1260
|
+
|
|
1261
|
+ st_synchronize();
|
|
1262
|
+
|
|
1263
|
+ bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
|
1264
|
+ if (z_min_endstop)
|
|
1265
|
+ {
|
|
1266
|
+ if (!Stopped)
|
|
1267
|
+ {
|
|
1268
|
+ SERIAL_ERROR_START;
|
|
1269
|
+ SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
|
|
1270
|
+ LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
|
1271
|
+ }
|
|
1272
|
+ Stop();
|
|
1273
|
+ }
|
1199
|
1274
|
#endif
|
|
1275
|
+
|
1200
|
1276
|
}
|
1201
|
1277
|
|
1202
|
1278
|
static void retract_z_probe() {
|
|
@@ -1212,7 +1288,49 @@ static void retract_z_probe() {
|
1212
|
1288
|
servos[servo_endstops[Z_AXIS]].detach();
|
1213
|
1289
|
#endif
|
1214
|
1290
|
}
|
|
1291
|
+ #elif defined(Z_PROBE_ALLEN_KEY)
|
|
1292
|
+ // Move up for safety
|
|
1293
|
+ feedrate = homing_feedrate[X_AXIS];
|
|
1294
|
+ destination[Z_AXIS] = current_position[Z_AXIS] + 20;
|
|
1295
|
+ prepare_move_raw();
|
|
1296
|
+
|
|
1297
|
+ // Move to the start position to initiate retraction
|
|
1298
|
+ destination[X_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_X;
|
|
1299
|
+ destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Y;
|
|
1300
|
+ destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Z;
|
|
1301
|
+ prepare_move_raw();
|
|
1302
|
+
|
|
1303
|
+ // Move the nozzle down to push the probe into retracted position
|
|
1304
|
+ feedrate = homing_feedrate[Z_AXIS]/10;
|
|
1305
|
+ destination[Z_AXIS] = current_position[Z_AXIS] - Z_PROBE_ALLEN_KEY_RETRACT_DEPTH;
|
|
1306
|
+ prepare_move_raw();
|
|
1307
|
+
|
|
1308
|
+ // Move up for safety
|
|
1309
|
+ feedrate = homing_feedrate[Z_AXIS]/2;
|
|
1310
|
+ destination[Z_AXIS] = current_position[Z_AXIS] + Z_PROBE_ALLEN_KEY_RETRACT_DEPTH * 2;
|
|
1311
|
+ prepare_move_raw();
|
|
1312
|
+
|
|
1313
|
+ // Home XY for safety
|
|
1314
|
+ feedrate = homing_feedrate[X_AXIS]/2;
|
|
1315
|
+ destination[X_AXIS] = 0;
|
|
1316
|
+ destination[Y_AXIS] = 0;
|
|
1317
|
+ prepare_move_raw();
|
|
1318
|
+
|
|
1319
|
+ st_synchronize();
|
|
1320
|
+
|
|
1321
|
+ bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
|
1322
|
+ if (!z_min_endstop)
|
|
1323
|
+ {
|
|
1324
|
+ if (!Stopped)
|
|
1325
|
+ {
|
|
1326
|
+ SERIAL_ERROR_START;
|
|
1327
|
+ SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
|
|
1328
|
+ LCD_ALERTMESSAGEPGM("Err: ZPROBE");
|
|
1329
|
+ }
|
|
1330
|
+ Stop();
|
|
1331
|
+ }
|
1215
|
1332
|
#endif
|
|
1333
|
+
|
1216
|
1334
|
}
|
1217
|
1335
|
|
1218
|
1336
|
enum ProbeAction { ProbeStay, ProbeEngage, ProbeRetract, ProbeEngageRetract };
|
|
@@ -1223,14 +1341,14 @@ static float probe_pt(float x, float y, float z_before, ProbeAction retract_acti
|
1223
|
1341
|
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
|
1224
|
1342
|
do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
|
1225
|
1343
|
|
1226
|
|
- #ifndef Z_PROBE_SLED
|
|
1344
|
+ #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
|
1227
|
1345
|
if (retract_action & ProbeEngage) engage_z_probe();
|
1228
|
1346
|
#endif
|
1229
|
1347
|
|
1230
|
1348
|
run_z_probe();
|
1231
|
1349
|
float measured_z = current_position[Z_AXIS];
|
1232
|
1350
|
|
1233
|
|
- #ifndef Z_PROBE_SLED
|
|
1351
|
+ #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
|
1234
|
1352
|
if (retract_action & ProbeRetract) retract_z_probe();
|
1235
|
1353
|
#endif
|
1236
|
1354
|
|
|
@@ -1247,6 +1365,62 @@ static float probe_pt(float x, float y, float z_before, ProbeAction retract_acti
|
1247
|
1365
|
return measured_z;
|
1248
|
1366
|
}
|
1249
|
1367
|
|
|
1368
|
+#ifdef DELTA
|
|
1369
|
+static void extrapolate_one_point(int x, int y, int xdir, int ydir) {
|
|
1370
|
+ if (bed_level[x][y] != 0.0) {
|
|
1371
|
+ return; // Don't overwrite good values.
|
|
1372
|
+ }
|
|
1373
|
+ float a = 2*bed_level[x+xdir][y] - bed_level[x+xdir*2][y]; // Left to right.
|
|
1374
|
+ float b = 2*bed_level[x][y+ydir] - bed_level[x][y+ydir*2]; // Front to back.
|
|
1375
|
+ float c = 2*bed_level[x+xdir][y+ydir] - bed_level[x+xdir*2][y+ydir*2]; // Diagonal.
|
|
1376
|
+ float median = c; // Median is robust (ignores outliers).
|
|
1377
|
+ if (a < b) {
|
|
1378
|
+ if (b < c) median = b;
|
|
1379
|
+ if (c < a) median = a;
|
|
1380
|
+ } else { // b <= a
|
|
1381
|
+ if (c < b) median = b;
|
|
1382
|
+ if (a < c) median = a;
|
|
1383
|
+ }
|
|
1384
|
+ bed_level[x][y] = median;
|
|
1385
|
+}
|
|
1386
|
+
|
|
1387
|
+// Fill in the unprobed points (corners of circular print surface)
|
|
1388
|
+// using linear extrapolation, away from the center.
|
|
1389
|
+static void extrapolate_unprobed_bed_level() {
|
|
1390
|
+ int half = (AUTO_BED_LEVELING_GRID_POINTS-1)/2;
|
|
1391
|
+ for (int y = 0; y <= half; y++) {
|
|
1392
|
+ for (int x = 0; x <= half; x++) {
|
|
1393
|
+ if (x + y < 3) continue;
|
|
1394
|
+ extrapolate_one_point(half-x, half-y, x>1?+1:0, y>1?+1:0);
|
|
1395
|
+ extrapolate_one_point(half+x, half-y, x>1?-1:0, y>1?+1:0);
|
|
1396
|
+ extrapolate_one_point(half-x, half+y, x>1?+1:0, y>1?-1:0);
|
|
1397
|
+ extrapolate_one_point(half+x, half+y, x>1?-1:0, y>1?-1:0);
|
|
1398
|
+ }
|
|
1399
|
+ }
|
|
1400
|
+}
|
|
1401
|
+
|
|
1402
|
+// Print calibration results for plotting or manual frame adjustment.
|
|
1403
|
+static void print_bed_level() {
|
|
1404
|
+ for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
|
|
1405
|
+ for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
|
|
1406
|
+ SERIAL_PROTOCOL_F(bed_level[x][y], 2);
|
|
1407
|
+ SERIAL_PROTOCOLPGM(" ");
|
|
1408
|
+ }
|
|
1409
|
+ SERIAL_ECHOLN("");
|
|
1410
|
+ }
|
|
1411
|
+}
|
|
1412
|
+
|
|
1413
|
+// Reset calibration results to zero.
|
|
1414
|
+void reset_bed_level() {
|
|
1415
|
+ for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
|
|
1416
|
+ for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
|
|
1417
|
+ bed_level[x][y] = 0.0;
|
|
1418
|
+ }
|
|
1419
|
+ }
|
|
1420
|
+}
|
|
1421
|
+
|
|
1422
|
+#endif // DELTA
|
|
1423
|
+
|
1250
|
1424
|
#endif // ENABLE_AUTO_BED_LEVELING
|
1251
|
1425
|
|
1252
|
1426
|
static void homeaxis(int axis) {
|
|
@@ -1523,7 +1697,11 @@ inline void gcode_G4() {
|
1523
|
1697
|
*/
|
1524
|
1698
|
inline void gcode_G28() {
|
1525
|
1699
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
1526
|
|
- plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data)
|
|
1700
|
+ #ifdef DELTA
|
|
1701
|
+ reset_bed_level();
|
|
1702
|
+ #else
|
|
1703
|
+ plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data)
|
|
1704
|
+ #endif
|
1527
|
1705
|
#endif
|
1528
|
1706
|
|
1529
|
1707
|
saved_feedrate = feedrate;
|
|
@@ -1804,6 +1982,7 @@ inline void gcode_G28() {
|
1804
|
1982
|
* Parameters With AUTO_BED_LEVELING_GRID:
|
1805
|
1983
|
*
|
1806
|
1984
|
* P Set the size of the grid that will be probed (P x P points).
|
|
1985
|
+ * Not supported by non-linear delta printer bed leveling.
|
1807
|
1986
|
* Example: "G29 P4"
|
1808
|
1987
|
*
|
1809
|
1988
|
* V Set the verbose level (0-4). Example: "G29 V3"
|
|
@@ -1811,6 +1990,7 @@ inline void gcode_G28() {
|
1811
|
1990
|
* T Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report.
|
1812
|
1991
|
* This is useful for manual bed leveling and finding flaws in the bed (to
|
1813
|
1992
|
* assist with part placement).
|
|
1993
|
+ * Not supported by non-linear delta printer bed leveling.
|
1814
|
1994
|
*
|
1815
|
1995
|
* F Set the Front limit of the probing grid
|
1816
|
1996
|
* B Set the Back limit of the probing grid
|
|
@@ -1856,16 +2036,21 @@ inline void gcode_G28() {
|
1856
|
2036
|
|
1857
|
2037
|
#ifdef AUTO_BED_LEVELING_GRID
|
1858
|
2038
|
|
|
2039
|
+ #ifndef DELTA
|
1859
|
2040
|
bool topo_flag = verbose_level > 2 || code_seen('T') || code_seen('t');
|
|
2041
|
+ #endif
|
1860
|
2042
|
|
1861
|
2043
|
if (verbose_level > 0)
|
1862
|
2044
|
SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n");
|
1863
|
2045
|
|
1864
|
|
- int auto_bed_leveling_grid_points = code_seen('P') ? code_value_long() : AUTO_BED_LEVELING_GRID_POINTS;
|
1865
|
|
- if (auto_bed_leveling_grid_points < 2 || auto_bed_leveling_grid_points > AUTO_BED_LEVELING_GRID_POINTS) {
|
1866
|
|
- SERIAL_PROTOCOLPGM("?Number of probed (P)oints is implausible (2 minimum).\n");
|
1867
|
|
- return;
|
1868
|
|
- }
|
|
2046
|
+ int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS;
|
|
2047
|
+ #ifndef DELTA
|
|
2048
|
+ if (code_seen('P')) auto_bed_leveling_grid_points = code_value_long();
|
|
2049
|
+ if (auto_bed_leveling_grid_points < 2 || auto_bed_leveling_grid_points > AUTO_BED_LEVELING_GRID_POINTS) {
|
|
2050
|
+ SERIAL_PROTOCOLPGM("?Number of probed (P)oints is implausible (2 minimum).\n");
|
|
2051
|
+ return;
|
|
2052
|
+ }
|
|
2053
|
+ #endif
|
1869
|
2054
|
|
1870
|
2055
|
int left_probe_bed_position = code_seen('L') ? code_value_long() : LEFT_PROBE_BED_POSITION,
|
1871
|
2056
|
right_probe_bed_position = code_seen('R') ? code_value_long() : RIGHT_PROBE_BED_POSITION,
|
|
@@ -1905,20 +2090,27 @@ inline void gcode_G28() {
|
1905
|
2090
|
|
1906
|
2091
|
#ifdef Z_PROBE_SLED
|
1907
|
2092
|
dock_sled(false); // engage (un-dock) the probe
|
|
2093
|
+ #elif not defined(SERVO_ENDSTOPS)
|
|
2094
|
+ engage_z_probe();
|
1908
|
2095
|
#endif
|
1909
|
2096
|
|
1910
|
2097
|
st_synchronize();
|
1911
|
2098
|
|
|
2099
|
+ #ifdef DELTA
|
|
2100
|
+ reset_bed_level();
|
|
2101
|
+ #else
|
1912
|
2102
|
// make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
|
1913
|
2103
|
//vector_3 corrected_position = plan_get_position_mm();
|
1914
|
2104
|
//corrected_position.debug("position before G29");
|
1915
|
2105
|
plan_bed_level_matrix.set_to_identity();
|
1916
|
2106
|
vector_3 uncorrected_position = plan_get_position();
|
1917
|
|
- //uncorrected_position.debug("position durring G29");
|
|
2107
|
+ //uncorrected_position.debug("position during G29");
|
1918
|
2108
|
current_position[X_AXIS] = uncorrected_position.x;
|
1919
|
2109
|
current_position[Y_AXIS] = uncorrected_position.y;
|
1920
|
2110
|
current_position[Z_AXIS] = uncorrected_position.z;
|
1921
|
2111
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
|
2112
|
+ #endif
|
|
2113
|
+
|
1922
|
2114
|
setup_for_endstop_move();
|
1923
|
2115
|
|
1924
|
2116
|
feedrate = homing_feedrate[Z_AXIS];
|
|
@@ -1926,9 +2118,10 @@ inline void gcode_G28() {
|
1926
|
2118
|
#ifdef AUTO_BED_LEVELING_GRID
|
1927
|
2119
|
|
1928
|
2120
|
// probe at the points of a lattice grid
|
1929
|
|
- int xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (auto_bed_leveling_grid_points - 1);
|
1930
|
|
- int yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (auto_bed_leveling_grid_points - 1);
|
|
2121
|
+ const int xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (auto_bed_leveling_grid_points-1);
|
|
2122
|
+ const int yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (auto_bed_leveling_grid_points-1);
|
1931
|
2123
|
|
|
2124
|
+ #ifndef DELTA
|
1932
|
2125
|
// solve the plane equation ax + by + d = z
|
1933
|
2126
|
// A is the matrix with rows [x y 1] for all the probed points
|
1934
|
2127
|
// B is the vector of the Z positions
|
|
@@ -1941,26 +2134,60 @@ inline void gcode_G28() {
|
1941
|
2134
|
eqnBVector[abl2], // "B" vector of Z points
|
1942
|
2135
|
mean = 0.0;
|
1943
|
2136
|
|
|
2137
|
+ #else
|
|
2138
|
+ delta_grid_spacing[0] = xGridSpacing;
|
|
2139
|
+ delta_grid_spacing[1] = yGridSpacing;
|
|
2140
|
+
|
|
2141
|
+ float z_offset = Z_PROBE_OFFSET_FROM_EXTRUDER;
|
|
2142
|
+ if (code_seen(axis_codes[Z_AXIS])) {
|
|
2143
|
+ z_offset += code_value();
|
|
2144
|
+ }
|
|
2145
|
+ #endif
|
|
2146
|
+
|
1944
|
2147
|
int probePointCounter = 0;
|
1945
|
2148
|
bool zig = true;
|
1946
|
2149
|
|
1947
|
|
- for (int yProbe = front_probe_bed_position; yProbe <= back_probe_bed_position; yProbe += yGridSpacing) {
|
1948
|
|
- int xProbe, xInc;
|
|
2150
|
+ for (int yCount=0; yCount < auto_bed_leveling_grid_points; yCount++)
|
|
2151
|
+ {
|
|
2152
|
+ double yProbe = front_probe_bed_position + yGridSpacing * yCount;
|
|
2153
|
+ int xStart, xStop, xInc;
|
1949
|
2154
|
|
1950
|
2155
|
if (zig)
|
1951
|
|
- xProbe = left_probe_bed_position, xInc = xGridSpacing;
|
|
2156
|
+ {
|
|
2157
|
+ xStart = 0;
|
|
2158
|
+ xStop = auto_bed_leveling_grid_points;
|
|
2159
|
+ xInc = 1;
|
|
2160
|
+ zig = false;
|
|
2161
|
+ }
|
1952
|
2162
|
else
|
1953
|
|
- xProbe = right_probe_bed_position, xInc = -xGridSpacing;
|
|
2163
|
+ {
|
|
2164
|
+ xStart = auto_bed_leveling_grid_points - 1;
|
|
2165
|
+ xStop = -1;
|
|
2166
|
+ xInc = -1;
|
|
2167
|
+ zig = true;
|
|
2168
|
+ }
|
1954
|
2169
|
|
|
2170
|
+ #ifndef DELTA
|
1955
|
2171
|
// If topo_flag is set then don't zig-zag. Just scan in one direction.
|
1956
|
2172
|
// This gets the probe points in more readable order.
|
1957
|
2173
|
if (!topo_flag) zig = !zig;
|
|
2174
|
+ #endif
|
|
2175
|
+
|
|
2176
|
+ for (int xCount=xStart; xCount != xStop; xCount += xInc)
|
|
2177
|
+ {
|
|
2178
|
+ double xProbe = left_probe_bed_position + xGridSpacing * xCount;
|
1958
|
2179
|
|
1959
|
|
- for (int xCount = 0; xCount < auto_bed_leveling_grid_points; xCount++) {
|
1960
|
2180
|
// raise extruder
|
1961
|
2181
|
float measured_z,
|
1962
|
2182
|
z_before = probePointCounter == 0 ? Z_RAISE_BEFORE_PROBING : current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS;
|
1963
|
2183
|
|
|
2184
|
+ #ifdef DELTA
|
|
2185
|
+ // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.
|
|
2186
|
+ float distance_from_center = sqrt(xProbe*xProbe + yProbe*yProbe);
|
|
2187
|
+ if (distance_from_center > DELTA_PROBABLE_RADIUS)
|
|
2188
|
+ continue;
|
|
2189
|
+ #endif //DELTA
|
|
2190
|
+
|
1964
|
2191
|
// Enhanced G29 - Do not retract servo between probes
|
1965
|
2192
|
ProbeAction act;
|
1966
|
2193
|
if (enhanced_g29) {
|
|
@@ -1976,22 +2203,24 @@ inline void gcode_G28() {
|
1976
|
2203
|
|
1977
|
2204
|
measured_z = probe_pt(xProbe, yProbe, z_before, act, verbose_level);
|
1978
|
2205
|
|
|
2206
|
+ #ifndef DELTA
|
1979
|
2207
|
mean += measured_z;
|
1980
|
2208
|
|
1981
|
2209
|
eqnBVector[probePointCounter] = measured_z;
|
1982
|
2210
|
eqnAMatrix[probePointCounter + 0 * abl2] = xProbe;
|
1983
|
2211
|
eqnAMatrix[probePointCounter + 1 * abl2] = yProbe;
|
1984
|
2212
|
eqnAMatrix[probePointCounter + 2 * abl2] = 1;
|
|
2213
|
+ #else
|
|
2214
|
+ bed_level[xCount][yCount] = measured_z + z_offset;
|
|
2215
|
+ #endif
|
1985
|
2216
|
|
1986
|
2217
|
probePointCounter++;
|
1987
|
|
- xProbe += xInc;
|
1988
|
|
-
|
1989
|
2218
|
} //xProbe
|
1990
|
|
-
|
1991
|
2219
|
} //yProbe
|
1992
|
2220
|
|
1993
|
2221
|
clean_up_after_endstop_move();
|
1994
|
2222
|
|
|
2223
|
+ #ifndef DELTA
|
1995
|
2224
|
// solve lsq problem
|
1996
|
2225
|
double *plane_equation_coefficients = qr_solve(abl2, 3, eqnAMatrix, eqnBVector);
|
1997
|
2226
|
|
|
@@ -2053,6 +2282,10 @@ inline void gcode_G28() {
|
2053
|
2282
|
|
2054
|
2283
|
set_bed_level_equation_lsq(plane_equation_coefficients);
|
2055
|
2284
|
free(plane_equation_coefficients);
|
|
2285
|
+ #else
|
|
2286
|
+ extrapolate_unprobed_bed_level();
|
|
2287
|
+ print_bed_level();
|
|
2288
|
+ #endif
|
2056
|
2289
|
|
2057
|
2290
|
#else // !AUTO_BED_LEVELING_GRID
|
2058
|
2291
|
|
|
@@ -2075,11 +2308,13 @@ inline void gcode_G28() {
|
2075
|
2308
|
|
2076
|
2309
|
#endif // !AUTO_BED_LEVELING_GRID
|
2077
|
2310
|
|
|
2311
|
+ do_blocking_move_to(MANUAL_X_HOME_POS, MANUAL_Y_HOME_POS, Z_RAISE_AFTER_PROBING);
|
2078
|
2312
|
st_synchronize();
|
2079
|
2313
|
|
2080
|
2314
|
if (verbose_level > 0)
|
2081
|
2315
|
plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
|
2082
|
2316
|
|
|
2317
|
+ #ifndef DELTA
|
2083
|
2318
|
// Correct the Z height difference from z-probe position and hotend tip position.
|
2084
|
2319
|
// The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
|
2085
|
2320
|
// When the bed is uneven, this height must be corrected.
|
|
@@ -2091,10 +2326,13 @@ inline void gcode_G28() {
|
2091
|
2326
|
apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); //Apply the correction sending the probe offset
|
2092
|
2327
|
current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS]; //The difference is added to current position and sent to planner.
|
2093
|
2328
|
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
|
|
2329
|
+ #endif
|
2094
|
2330
|
|
2095
|
|
- #ifdef Z_PROBE_SLED
|
2096
|
|
- dock_sled(true, -SLED_DOCKING_OFFSET); // dock the probe, correcting for over-travel
|
2097
|
|
- #endif
|
|
2331
|
+ #ifdef Z_PROBE_SLED
|
|
2332
|
+ dock_sled(true, -SLED_DOCKING_OFFSET); // dock the probe, correcting for over-travel
|
|
2333
|
+ #elif not defined(SERVO_ENDSTOPS)
|
|
2334
|
+ retract_z_probe();
|
|
2335
|
+ #endif
|
2098
|
2336
|
}
|
2099
|
2337
|
|
2100
|
2338
|
#ifndef Z_PROBE_SLED
|
|
@@ -4920,7 +5158,64 @@ void calculate_delta(float cartesian[3])
|
4920
|
5158
|
SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]);
|
4921
|
5159
|
*/
|
4922
|
5160
|
}
|
4923
|
|
-#endif
|
|
5161
|
+
|
|
5162
|
+#ifdef ENABLE_AUTO_BED_LEVELING
|
|
5163
|
+// Adjust print surface height by linear interpolation over the bed_level array.
|
|
5164
|
+int delta_grid_spacing[2] = { 0, 0 };
|
|
5165
|
+void adjust_delta(float cartesian[3])
|
|
5166
|
+{
|
|
5167
|
+ if (delta_grid_spacing[0] == 0 || delta_grid_spacing[1] == 0)
|
|
5168
|
+ return; // G29 not done
|
|
5169
|
+
|
|
5170
|
+ int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2;
|
|
5171
|
+ float grid_x = max(0.001-half, min(half-0.001, cartesian[X_AXIS] / delta_grid_spacing[0]));
|
|
5172
|
+ float grid_y = max(0.001-half, min(half-0.001, cartesian[Y_AXIS] / delta_grid_spacing[1]));
|
|
5173
|
+ int floor_x = floor(grid_x);
|
|
5174
|
+ int floor_y = floor(grid_y);
|
|
5175
|
+ float ratio_x = grid_x - floor_x;
|
|
5176
|
+ float ratio_y = grid_y - floor_y;
|
|
5177
|
+ float z1 = bed_level[floor_x+half][floor_y+half];
|
|
5178
|
+ float z2 = bed_level[floor_x+half][floor_y+half+1];
|
|
5179
|
+ float z3 = bed_level[floor_x+half+1][floor_y+half];
|
|
5180
|
+ float z4 = bed_level[floor_x+half+1][floor_y+half+1];
|
|
5181
|
+ float left = (1-ratio_y)*z1 + ratio_y*z2;
|
|
5182
|
+ float right = (1-ratio_y)*z3 + ratio_y*z4;
|
|
5183
|
+ float offset = (1-ratio_x)*left + ratio_x*right;
|
|
5184
|
+
|
|
5185
|
+ delta[X_AXIS] += offset;
|
|
5186
|
+ delta[Y_AXIS] += offset;
|
|
5187
|
+ delta[Z_AXIS] += offset;
|
|
5188
|
+
|
|
5189
|
+ /*
|
|
5190
|
+ SERIAL_ECHOPGM("grid_x="); SERIAL_ECHO(grid_x);
|
|
5191
|
+ SERIAL_ECHOPGM(" grid_y="); SERIAL_ECHO(grid_y);
|
|
5192
|
+ SERIAL_ECHOPGM(" floor_x="); SERIAL_ECHO(floor_x);
|
|
5193
|
+ SERIAL_ECHOPGM(" floor_y="); SERIAL_ECHO(floor_y);
|
|
5194
|
+ SERIAL_ECHOPGM(" ratio_x="); SERIAL_ECHO(ratio_x);
|
|
5195
|
+ SERIAL_ECHOPGM(" ratio_y="); SERIAL_ECHO(ratio_y);
|
|
5196
|
+ SERIAL_ECHOPGM(" z1="); SERIAL_ECHO(z1);
|
|
5197
|
+ SERIAL_ECHOPGM(" z2="); SERIAL_ECHO(z2);
|
|
5198
|
+ SERIAL_ECHOPGM(" z3="); SERIAL_ECHO(z3);
|
|
5199
|
+ SERIAL_ECHOPGM(" z4="); SERIAL_ECHO(z4);
|
|
5200
|
+ SERIAL_ECHOPGM(" left="); SERIAL_ECHO(left);
|
|
5201
|
+ SERIAL_ECHOPGM(" right="); SERIAL_ECHO(right);
|
|
5202
|
+ SERIAL_ECHOPGM(" offset="); SERIAL_ECHOLN(offset);
|
|
5203
|
+ */
|
|
5204
|
+}
|
|
5205
|
+#endif //ENABLE_AUTO_BED_LEVELING
|
|
5206
|
+
|
|
5207
|
+void prepare_move_raw()
|
|
5208
|
+{
|
|
5209
|
+ previous_millis_cmd = millis();
|
|
5210
|
+ calculate_delta(destination);
|
|
5211
|
+ plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
|
|
5212
|
+ destination[E_AXIS], feedrate*feedmultiply/60/100.0,
|
|
5213
|
+ active_extruder);
|
|
5214
|
+ for(int8_t i=0; i < NUM_AXIS; i++) {
|
|
5215
|
+ current_position[i] = destination[i];
|
|
5216
|
+ }
|
|
5217
|
+}
|
|
5218
|
+#endif //DELTA
|
4924
|
5219
|
|
4925
|
5220
|
void prepare_move()
|
4926
|
5221
|
{
|