Просмотр исходного кода

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 9 лет назад
Родитель
Сommit
7c24b97958

+ 6
- 0
Marlin/Marlin.h Просмотреть файл

@@ -189,12 +189,18 @@ void ClearToSend();
189 189
 void get_coordinates();
190 190
 #ifdef DELTA
191 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 196
 extern float delta[3];
197
+void prepare_move_raw();
193 198
 #endif
194 199
 #ifdef SCARA
195 200
 void calculate_delta(float cartesian[3]);
196 201
 void calculate_SCARA_forward_Transform(float f_scara[3]);
197 202
 #endif
203
+void reset_bed_level();
198 204
 void prepare_move();
199 205
 void kill();
200 206
 void Stop();

+ 318
- 23
Marlin/Marlin_main.cpp Просмотреть файл

@@ -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
 {

+ 77
- 3
Marlin/example_configurations/delta/Configuration.h Просмотреть файл

@@ -110,6 +110,9 @@ Here are some standard links for getting your machine calibrated:
110 110
 // Effective horizontal distance bridged by diagonal push rods.
111 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 118
 //============================= Thermal Settings ============================
@@ -361,8 +364,7 @@ const bool X_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
361 364
 const bool Y_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
362 365
 const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of the endstop.
363 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 369
 // For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
368 370
 #define X_ENABLE_ON 0
@@ -413,8 +415,80 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
413 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 Просмотреть файл

@@ -455,9 +455,27 @@ const unsigned int dropsegments=5; //everything with less than this number of st
455 455
 //===========================================================================
456 456
 
457 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 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 479
 #if EXTRUDERS > 1 && defined TEMP_SENSOR_1_AS_REDUNDANT
462 480
   #error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1"
463 481
 #endif

+ 1
- 1
Marlin/planner.cpp Просмотреть файл

@@ -1057,7 +1057,7 @@ Having the real displacement of the head, we can calculate the total movement le
1057 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 1061
 vector_3 plan_get_position() {
1062 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 Просмотреть файл

@@ -85,8 +85,10 @@ void plan_init();
85 85
 #ifdef ENABLE_AUTO_BED_LEVELING
86 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 92
 #else
91 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 94
 #endif // ENABLE_AUTO_BED_LEVELING

Загрузка…
Отмена
Сохранить