Browse Source

Ported over Johann Rocholl's improvements for delta printers:

- Nonlinear auto bed leveling code (includes G29, G30, Z_RAISE_AFTER_PROBING). Cleaned it up to be a delta-specific AUTO_BED_LEVELING_GRID code path.
- Allen key z-probe deployment and retraction code. Cleaned it up and added safety checks.
maverikou 10 years ago
parent
commit
7c24b97958

+ 6
- 0
Marlin/Marlin.h View File

189
 void get_coordinates();
189
 void get_coordinates();
190
 #ifdef DELTA
190
 #ifdef DELTA
191
 void calculate_delta(float cartesian[3]);
191
 void calculate_delta(float cartesian[3]);
192
+  #ifdef ENABLE_AUTO_BED_LEVELING
193
+  extern int delta_grid_spacing[2];
194
+  void adjust_delta(float cartesian[3]);
195
+  #endif
192
 extern float delta[3];
196
 extern float delta[3];
197
+void prepare_move_raw();
193
 #endif
198
 #endif
194
 #ifdef SCARA
199
 #ifdef SCARA
195
 void calculate_delta(float cartesian[3]);
200
 void calculate_delta(float cartesian[3]);
196
 void calculate_SCARA_forward_Transform(float f_scara[3]);
201
 void calculate_SCARA_forward_Transform(float f_scara[3]);
197
 #endif
202
 #endif
203
+void reset_bed_level();
198
 void prepare_move();
204
 void prepare_move();
199
 void kill();
205
 void kill();
200
 void Stop();
206
 void Stop();

+ 318
- 23
Marlin/Marlin_main.cpp View File

346
   float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
346
   float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
347
   float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
347
   float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
348
   float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
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
 #endif
352
 #endif
350
 
353
 
351
 #ifdef SCARA
354
 #ifdef SCARA
1058
 
1061
 
1059
 #ifdef ENABLE_AUTO_BED_LEVELING
1062
 #ifdef ENABLE_AUTO_BED_LEVELING
1060
 #ifdef AUTO_BED_LEVELING_GRID
1063
 #ifdef AUTO_BED_LEVELING_GRID
1064
+
1065
+#ifndef DELTA
1061
 static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
1066
 static void set_bed_level_equation_lsq(double *plane_equation_coefficients)
1062
 {
1067
 {
1063
     vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
1068
     vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
1080
 
1085
 
1081
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
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
 #else // not AUTO_BED_LEVELING_GRID
1090
 #else // not AUTO_BED_LEVELING_GRID
1085
 
1091
 
1113
 #endif // AUTO_BED_LEVELING_GRID
1119
 #endif // AUTO_BED_LEVELING_GRID
1114
 
1120
 
1115
 static void run_z_probe() {
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
     plan_bed_level_matrix.set_to_identity();
1143
     plan_bed_level_matrix.set_to_identity();
1117
     feedrate = homing_feedrate[Z_AXIS];
1144
     feedrate = homing_feedrate[Z_AXIS];
1118
 
1145
 
1139
     current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
1166
     current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
1140
     // make sure the planner knows where we are as it may be a bit different than we last said to move to
1167
     // make sure the planner knows where we are as it may be a bit different than we last said to move to
1141
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
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
 static void do_blocking_move_to(float x, float y, float z) {
1173
 static void do_blocking_move_to(float x, float y, float z) {
1145
     float oldFeedRate = feedrate;
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
     feedrate = homing_feedrate[Z_AXIS];
1188
     feedrate = homing_feedrate[Z_AXIS];
1148
 
1189
 
1149
     current_position[Z_AXIS] = z;
1190
     current_position[Z_AXIS] = z;
1157
     plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
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
     st_synchronize();
1199
     st_synchronize();
1159
 
1200
 
1201
+#endif
1202
+
1160
     feedrate = oldFeedRate;
1203
     feedrate = oldFeedRate;
1161
 }
1204
 }
1162
 
1205
 
1196
         servos[servo_endstops[Z_AXIS]].detach();
1239
         servos[servo_endstops[Z_AXIS]].detach();
1197
       #endif
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
   #endif
1274
   #endif
1275
+
1200
 }
1276
 }
1201
 
1277
 
1202
 static void retract_z_probe() {
1278
 static void retract_z_probe() {
1212
         servos[servo_endstops[Z_AXIS]].detach();
1288
         servos[servo_endstops[Z_AXIS]].detach();
1213
       #endif
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
   #endif
1332
   #endif
1333
+
1216
 }
1334
 }
1217
 
1335
 
1218
 enum ProbeAction { ProbeStay, ProbeEngage, ProbeRetract, ProbeEngageRetract };
1336
 enum ProbeAction { ProbeStay, ProbeEngage, ProbeRetract, ProbeEngageRetract };
1223
   do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
1341
   do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
1224
   do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
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
     if (retract_action & ProbeEngage) engage_z_probe();
1345
     if (retract_action & ProbeEngage) engage_z_probe();
1228
   #endif
1346
   #endif
1229
 
1347
 
1230
   run_z_probe();
1348
   run_z_probe();
1231
   float measured_z = current_position[Z_AXIS];
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
     if (retract_action & ProbeRetract) retract_z_probe();
1352
     if (retract_action & ProbeRetract) retract_z_probe();
1235
   #endif
1353
   #endif
1236
 
1354
 
1247
   return measured_z;
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
 #endif // ENABLE_AUTO_BED_LEVELING
1424
 #endif // ENABLE_AUTO_BED_LEVELING
1251
 
1425
 
1252
 static void homeaxis(int axis) {
1426
 static void homeaxis(int axis) {
1523
  */
1697
  */
1524
 inline void gcode_G28() {
1698
 inline void gcode_G28() {
1525
   #ifdef ENABLE_AUTO_BED_LEVELING
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
   #endif
1705
   #endif
1528
 
1706
 
1529
   saved_feedrate = feedrate;
1707
   saved_feedrate = feedrate;
1804
    * Parameters With AUTO_BED_LEVELING_GRID:
1982
    * Parameters With AUTO_BED_LEVELING_GRID:
1805
    *
1983
    *
1806
    *  P  Set the size of the grid that will be probed (P x P points).
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
    *     Example: "G29 P4"
1986
    *     Example: "G29 P4"
1808
    *
1987
    *
1809
    *  V  Set the verbose level (0-4). Example: "G29 V3"
1988
    *  V  Set the verbose level (0-4). Example: "G29 V3"
1811
    *  T  Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report.
1990
    *  T  Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report.
1812
    *     This is useful for manual bed leveling and finding flaws in the bed (to
1991
    *     This is useful for manual bed leveling and finding flaws in the bed (to
1813
    *     assist with part placement).
1992
    *     assist with part placement).
1993
+   *     Not supported by non-linear delta printer bed leveling.
1814
    *
1994
    *
1815
    *  F  Set the Front limit of the probing grid
1995
    *  F  Set the Front limit of the probing grid
1816
    *  B  Set the Back limit of the probing grid
1996
    *  B  Set the Back limit of the probing grid
1856
 
2036
 
1857
     #ifdef AUTO_BED_LEVELING_GRID
2037
     #ifdef AUTO_BED_LEVELING_GRID
1858
 
2038
 
2039
+    #ifndef DELTA
1859
       bool topo_flag = verbose_level > 2 || code_seen('T') || code_seen('t');
2040
       bool topo_flag = verbose_level > 2 || code_seen('T') || code_seen('t');
2041
+    #endif
1860
 
2042
 
1861
       if (verbose_level > 0)
2043
       if (verbose_level > 0)
1862
         SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n");
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
       int left_probe_bed_position = code_seen('L') ? code_value_long() : LEFT_PROBE_BED_POSITION,
2055
       int left_probe_bed_position = code_seen('L') ? code_value_long() : LEFT_PROBE_BED_POSITION,
1871
           right_probe_bed_position = code_seen('R') ? code_value_long() : RIGHT_PROBE_BED_POSITION,
2056
           right_probe_bed_position = code_seen('R') ? code_value_long() : RIGHT_PROBE_BED_POSITION,
1905
 
2090
 
1906
     #ifdef Z_PROBE_SLED
2091
     #ifdef Z_PROBE_SLED
1907
       dock_sled(false); // engage (un-dock) the probe
2092
       dock_sled(false); // engage (un-dock) the probe
2093
+    #elif not defined(SERVO_ENDSTOPS)
2094
+      engage_z_probe();
1908
     #endif
2095
     #endif
1909
 
2096
 
1910
     st_synchronize();
2097
     st_synchronize();
1911
 
2098
 
2099
+  #ifdef DELTA
2100
+    reset_bed_level();
2101
+  #else
1912
     // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
2102
     // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
1913
     //vector_3 corrected_position = plan_get_position_mm();
2103
     //vector_3 corrected_position = plan_get_position_mm();
1914
     //corrected_position.debug("position before G29");
2104
     //corrected_position.debug("position before G29");
1915
     plan_bed_level_matrix.set_to_identity();
2105
     plan_bed_level_matrix.set_to_identity();
1916
     vector_3 uncorrected_position = plan_get_position();
2106
     vector_3 uncorrected_position = plan_get_position();
1917
-    //uncorrected_position.debug("position durring G29");
2107
+    //uncorrected_position.debug("position during G29");
1918
     current_position[X_AXIS] = uncorrected_position.x;
2108
     current_position[X_AXIS] = uncorrected_position.x;
1919
     current_position[Y_AXIS] = uncorrected_position.y;
2109
     current_position[Y_AXIS] = uncorrected_position.y;
1920
     current_position[Z_AXIS] = uncorrected_position.z;
2110
     current_position[Z_AXIS] = uncorrected_position.z;
1921
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2111
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
2112
+  #endif
2113
+
1922
     setup_for_endstop_move();
2114
     setup_for_endstop_move();
1923
 
2115
 
1924
     feedrate = homing_feedrate[Z_AXIS];
2116
     feedrate = homing_feedrate[Z_AXIS];
1926
     #ifdef AUTO_BED_LEVELING_GRID
2118
     #ifdef AUTO_BED_LEVELING_GRID
1927
 
2119
 
1928
       // probe at the points of a lattice grid
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
       // solve the plane equation ax + by + d = z
2125
       // solve the plane equation ax + by + d = z
1933
       // A is the matrix with rows [x y 1] for all the probed points
2126
       // A is the matrix with rows [x y 1] for all the probed points
1934
       // B is the vector of the Z positions
2127
       // B is the vector of the Z positions
1941
              eqnBVector[abl2],     // "B" vector of Z points
2134
              eqnBVector[abl2],     // "B" vector of Z points
1942
              mean = 0.0;
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
       int probePointCounter = 0;
2147
       int probePointCounter = 0;
1945
       bool zig = true;
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
         if (zig)
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
         else
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
         // If topo_flag is set then don't zig-zag. Just scan in one direction.
2171
         // If topo_flag is set then don't zig-zag. Just scan in one direction.
1956
         // This gets the probe points in more readable order.
2172
         // This gets the probe points in more readable order.
1957
         if (!topo_flag) zig = !zig;
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
           // raise extruder
2180
           // raise extruder
1961
           float measured_z,
2181
           float measured_z,
1962
                 z_before = probePointCounter == 0 ? Z_RAISE_BEFORE_PROBING : current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS;
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
           // Enhanced G29 - Do not retract servo between probes
2191
           // Enhanced G29 - Do not retract servo between probes
1965
           ProbeAction act;
2192
           ProbeAction act;
1966
           if (enhanced_g29) {
2193
           if (enhanced_g29) {
1976
 
2203
 
1977
           measured_z = probe_pt(xProbe, yProbe, z_before, act, verbose_level);
2204
           measured_z = probe_pt(xProbe, yProbe, z_before, act, verbose_level);
1978
 
2205
 
2206
+        #ifndef DELTA
1979
           mean += measured_z;
2207
           mean += measured_z;
1980
 
2208
 
1981
           eqnBVector[probePointCounter] = measured_z;
2209
           eqnBVector[probePointCounter] = measured_z;
1982
           eqnAMatrix[probePointCounter + 0 * abl2] = xProbe;
2210
           eqnAMatrix[probePointCounter + 0 * abl2] = xProbe;
1983
           eqnAMatrix[probePointCounter + 1 * abl2] = yProbe;
2211
           eqnAMatrix[probePointCounter + 1 * abl2] = yProbe;
1984
           eqnAMatrix[probePointCounter + 2 * abl2] = 1;
2212
           eqnAMatrix[probePointCounter + 2 * abl2] = 1;
2213
+        #else
2214
+          bed_level[xCount][yCount] = measured_z + z_offset;
2215
+        #endif
1985
 
2216
 
1986
           probePointCounter++;
2217
           probePointCounter++;
1987
-          xProbe += xInc;
1988
-
1989
         } //xProbe
2218
         } //xProbe
1990
-
1991
       } //yProbe
2219
       } //yProbe
1992
 
2220
 
1993
       clean_up_after_endstop_move();
2221
       clean_up_after_endstop_move();
1994
 
2222
 
2223
+    #ifndef DELTA
1995
       // solve lsq problem
2224
       // solve lsq problem
1996
       double *plane_equation_coefficients = qr_solve(abl2, 3, eqnAMatrix, eqnBVector);
2225
       double *plane_equation_coefficients = qr_solve(abl2, 3, eqnAMatrix, eqnBVector);
1997
 
2226
 
2053
 
2282
 
2054
       set_bed_level_equation_lsq(plane_equation_coefficients);
2283
       set_bed_level_equation_lsq(plane_equation_coefficients);
2055
       free(plane_equation_coefficients);
2284
       free(plane_equation_coefficients);
2285
+    #else
2286
+      extrapolate_unprobed_bed_level();
2287
+      print_bed_level();
2288
+    #endif
2056
 
2289
 
2057
     #else // !AUTO_BED_LEVELING_GRID
2290
     #else // !AUTO_BED_LEVELING_GRID
2058
 
2291
 
2075
 
2308
 
2076
     #endif // !AUTO_BED_LEVELING_GRID
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
     st_synchronize();
2312
     st_synchronize();
2079
 
2313
 
2080
     if (verbose_level > 0)
2314
     if (verbose_level > 0)
2081
       plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
2315
       plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
2082
 
2316
 
2317
+  #ifndef DELTA
2083
     // Correct the Z height difference from z-probe position and hotend tip position.
2318
     // Correct the Z height difference from z-probe position and hotend tip position.
2084
     // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
2319
     // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
2085
     // When the bed is uneven, this height must be corrected.
2320
     // When the bed is uneven, this height must be corrected.
2091
     apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp);         //Apply the correction sending the probe offset
2326
     apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp);         //Apply the correction sending the probe offset
2092
     current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS];   //The difference is added to current position and sent to planner.
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
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
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
   #ifndef Z_PROBE_SLED
2338
   #ifndef Z_PROBE_SLED
4920
   SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]);
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
 void prepare_move()
5220
 void prepare_move()
4926
 {
5221
 {

+ 77
- 3
Marlin/example_configurations/delta/Configuration.h View File

110
 // Effective horizontal distance bridged by diagonal push rods.
110
 // Effective horizontal distance bridged by diagonal push rods.
111
 #define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET)
111
 #define DELTA_RADIUS (DELTA_SMOOTH_ROD_OFFSET-DELTA_EFFECTOR_OFFSET-DELTA_CARRIAGE_OFFSET)
112
 
112
 
113
+// Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers).
114
+#define DELTA_PRINTABLE_RADIUS 90
115
+
113
 
116
 
114
 //===========================================================================
117
 //===========================================================================
115
 //============================= Thermal Settings ============================
118
 //============================= Thermal Settings ============================
361
 const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
364
 const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
362
 const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
365
 const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
363
 //#define DISABLE_MAX_ENDSTOPS
366
 //#define DISABLE_MAX_ENDSTOPS
364
-// Deltas never have min endstops
365
-#define DISABLE_MIN_ENDSTOPS
367
+#define DISABLE_MIN_ENDSTOPS // Deltas only use min endstops for probing
366
 
368
 
367
 // For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
369
 // For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
368
 #define X_ENABLE_ON 0
370
 #define X_ENABLE_ON 0
413
 //============================= Bed Auto Leveling ===========================
415
 //============================= Bed Auto Leveling ===========================
414
 //===========================================================================
416
 //===========================================================================
415
 
417
 
416
-//Bed Auto Leveling is still not compatible with Delta Kinematics
418
+//#define ENABLE_AUTO_BED_LEVELING // Delete the comment to enable (remove // at the start of the line)
419
+// Z-Probe Repeatability test is not supported in Deltas yet.
420
+
421
+#ifdef ENABLE_AUTO_BED_LEVELING
422
+
423
+  // Deltas only support grid mode
424
+  #define AUTO_BED_LEVELING_GRID
425
+
426
+  #define DELTA_PROBABLE_RADIUS (DELTA_PRINTABLE_RADIUS - 10)
427
+  #define LEFT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS
428
+  #define RIGHT_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
429
+  #define BACK_PROBE_BED_POSITION DELTA_PROBABLE_RADIUS
430
+  #define FRONT_PROBE_BED_POSITION -DELTA_PROBABLE_RADIUS   
431
+
432
+  // Non-linear bed leveling will be used.
433
+  // Compensate by interpolating between the nearest four Z probe values for each point.
434
+  // Useful for deltas where the print surface may appear like a bowl or dome shape.
435
+  // Works best with ACCURATE_BED_LEVELING_POINTS 5 or higher.
436
+  #define AUTO_BED_LEVELING_GRID_POINTS 9
437
+
438
+  // Offsets to the probe relative to the extruder tip (Hotend - Probe)
439
+  // X and Y offsets must be integers
440
+  #define X_PROBE_OFFSET_FROM_EXTRUDER 0     // -left  +right
441
+  #define Y_PROBE_OFFSET_FROM_EXTRUDER -10   // -front +behind
442
+  #define Z_PROBE_OFFSET_FROM_EXTRUDER -3.5  // -below (always!)
443
+
444
+  #define Z_RAISE_BEFORE_HOMING 4       // (in mm) Raise Z before homing (G28) for Probe Clearance.
445
+                                        // Be sure you have this distance over your Z_MAX_POS in case
446
+
447
+  #define XY_TRAVEL_SPEED 4000         // X and Y axis travel speed between probes, in mm/min
448
+
449
+  #define Z_RAISE_BEFORE_PROBING 15   //How much the extruder will be raised before traveling to the first probing point.
450
+  #define Z_RAISE_BETWEEN_PROBINGS 5  //How much the extruder will be raised when traveling from between next probing points
451
+  #define Z_RAISE_AFTER_PROBING 50    //How much the extruder will be raised after the last probing point.
452
+  
453
+  // Allen key retractable z-probe as seen on many Kossel delta printers - http://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe
454
+  // Deploys by touching z-axis belt. Retracts by pushing the probe down. Uses Z_MIN_PIN.
455
+  //#define Z_PROBE_ALLEN_KEY
456
+  #ifdef Z_PROBE_ALLEN_KEY
457
+    #define Z_PROBE_ALLEN_KEY_DEPLOY_X 30
458
+    #define Z_PROBE_ALLEN_KEY_DEPLOY_Y DELTA_PRINTABLE_RADIUS
459
+    #define Z_PROBE_ALLEN_KEY_DEPLOY_Z 100
460
+    
461
+    #define Z_PROBE_ALLEN_KEY_RETRACT_X     -64
462
+    #define Z_PROBE_ALLEN_KEY_RETRACT_Y     56
463
+    #define Z_PROBE_ALLEN_KEY_RETRACT_Z     23
464
+    #define Z_PROBE_ALLEN_KEY_RETRACT_DEPTH 20
465
+  #endif
466
+  
467
+  //If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk
468
+  //The value is the delay to turn the servo off after powered on - depends on the servo speed; 300ms is good value, but you can try lower it.
469
+  // You MUST HAVE the SERVO_ENDSTOPS defined to use here a value higher than zero otherwise your code will not compile.
470
+
471
+//  #define PROBE_SERVO_DEACTIVATION_DELAY 300
472
+
473
+
474
+//If you have enabled the Bed Auto Leveling and are using the same Z Probe for Z Homing,
475
+//it is highly recommended you let this Z_SAFE_HOMING enabled!!!
476
+
477
+  #define Z_SAFE_HOMING   // This feature is meant to avoid Z homing with probe outside the bed area.
478
+                          // When defined, it will:
479
+                          // - Allow Z homing only after X and Y homing AND stepper drivers still enabled
480
+                          // - If stepper drivers timeout, it will need X and Y homing again before Z homing
481
+                          // - Position the probe in a defined XY point before Z Homing when homing all axis (G28)
482
+                          // - Block Z homing only when the probe is outside bed area.
483
+
484
+  #ifdef Z_SAFE_HOMING
485
+
486
+    #define Z_SAFE_HOMING_X_POINT (X_MAX_LENGTH/2)    // X point for Z homing when homing all axis (G28)
487
+    #define Z_SAFE_HOMING_Y_POINT (Y_MAX_LENGTH/2)    // Y point for Z homing when homing all axis (G28)
488
+
489
+  #endif
417
 
490
 
491
+#endif // ENABLE_AUTO_BED_LEVELING
418
 
492
 
419
 
493
 
420
 
494
 

+ 19
- 1
Marlin/example_configurations/delta/Configuration_adv.h View File

455
 //===========================================================================
455
 //===========================================================================
456
 
456
 
457
 #if defined (ENABLE_AUTO_BED_LEVELING) && defined (DELTA)
457
 #if defined (ENABLE_AUTO_BED_LEVELING) && defined (DELTA)
458
-  #error "Bed Auto Leveling is still not compatible with Delta Kinematics."
458
+
459
+  #if not defined(AUTO_BED_LEVELING_GRID)
460
+    #error "Only Grid Bed Auto Leveling is supported on Deltas."
461
+  #endif
462
+  
463
+  #if defined(Z_PROBE_SLED)
464
+    #error "You cannot use Z_PROBE_SLED together with DELTA."
465
+  #endif
466
+
467
+  #if defined(Z_PROBE_REPEATABILITY_TEST)
468
+    #error "Z-probe repeatability test is not supported on Deltas yet."
469
+  #endif
470
+
459
 #endif  
471
 #endif  
460
 
472
 
473
+#if defined(Z_PROBE_ALLEN_KEY)
474
+  #if !defined(AUTO_BED_LEVELING_GRID) || !defined(DELTA)
475
+    #error "Invalid use of Z_PROBE_ALLEN_KEY."
476
+  #endif
477
+#endif
478
+
461
 #if EXTRUDERS > 1 && defined TEMP_SENSOR_1_AS_REDUNDANT
479
 #if EXTRUDERS > 1 && defined TEMP_SENSOR_1_AS_REDUNDANT
462
   #error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1"
480
   #error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1"
463
 #endif
481
 #endif

+ 1
- 1
Marlin/planner.cpp View File

1057
   st_wake_up();
1057
   st_wake_up();
1058
 }
1058
 }
1059
 
1059
 
1060
-#ifdef ENABLE_AUTO_BED_LEVELING
1060
+#if defined(ENABLE_AUTO_BED_LEVELING) && not defined(DELTA)
1061
 vector_3 plan_get_position() {
1061
 vector_3 plan_get_position() {
1062
 	vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS));
1062
 	vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS));
1063
 
1063
 

+ 4
- 2
Marlin/planner.h View File

85
 #ifdef ENABLE_AUTO_BED_LEVELING
85
 #ifdef ENABLE_AUTO_BED_LEVELING
86
 void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
86
 void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder);
87
 
87
 
88
-// Get the position applying the bed level matrix if enabled
89
-vector_3 plan_get_position();
88
+  #ifndef DELTA
89
+  // Get the position applying the bed level matrix if enabled
90
+  vector_3 plan_get_position();
91
+  #endif
90
 #else
92
 #else
91
 void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
93
 void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
92
 #endif // ENABLE_AUTO_BED_LEVELING
94
 #endif // ENABLE_AUTO_BED_LEVELING

Loading…
Cancel
Save