Browse Source

Merge pull request #1764 from thinkyhead/probe_leveling

Fix homing and leveling
Scott Lahteine 9 years ago
parent
commit
9593f09b99
3 changed files with 309 additions and 313 deletions
  1. 5
    1
      Marlin/Conditionals.h
  2. 2
    0
      Marlin/Marlin.h
  3. 302
    312
      Marlin/Marlin_main.cpp

+ 5
- 1
Marlin/Conditionals.h View File

4
  */
4
  */
5
 #ifndef CONDITIONALS_H
5
 #ifndef CONDITIONALS_H
6
 
6
 
7
+#ifndef M_PI
8
+  #define M_PI 3.1415926536
9
+#endif
10
+
7
 #ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
11
 #ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
8
 
12
 
9
   #define CONFIGURATION_LCD
13
   #define CONFIGURATION_LCD
252
    * Advance calculated values
256
    * Advance calculated values
253
    */
257
    */
254
   #ifdef ADVANCE
258
   #ifdef ADVANCE
255
-    #define EXTRUSION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
259
+    #define EXTRUSION_AREA (0.25 * D_FILAMENT * D_FILAMENT * M_PI)
256
     #define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS] / EXTRUSION_AREA)
260
     #define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS] / EXTRUSION_AREA)
257
   #endif
261
   #endif
258
 
262
 

+ 2
- 0
Marlin/Marlin.h View File

29
 
29
 
30
 #define BIT(b) (1<<(b))
30
 #define BIT(b) (1<<(b))
31
 #define TEST(n,b) (((n)&BIT(b))!=0)
31
 #define TEST(n,b) (((n)&BIT(b))!=0)
32
+#define RADIANS(d) ((d)*M_PI/180.0)
33
+#define DEGREES(r) ((d)*180.0/M_PI)
32
 
34
 
33
 // Arduino < 1.0.0 does not define this, so we need to do it ourselves
35
 // Arduino < 1.0.0 does not define this, so we need to do it ourselves
34
 #ifndef analogInputToDigitalPin
36
 #ifndef analogInputToDigitalPin

+ 302
- 312
Marlin/Marlin_main.cpp View File

1034
 inline void sync_plan_position() {
1034
 inline void sync_plan_position() {
1035
   plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1035
   plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
1036
 }
1036
 }
1037
+#if defined(DELTA) || defined(SCARA)
1038
+  inline void sync_plan_position_delta() {
1039
+    calculate_delta(current_position);
1040
+    plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
1041
+  }
1042
+#endif
1037
 
1043
 
1038
 #ifdef ENABLE_AUTO_BED_LEVELING
1044
 #ifdef ENABLE_AUTO_BED_LEVELING
1039
 
1045
 
1103
       destination[Z_AXIS] = -10;
1109
       destination[Z_AXIS] = -10;
1104
       prepare_move_raw();
1110
       prepare_move_raw();
1105
       st_synchronize();
1111
       st_synchronize();
1106
-      endstops_hit_on_purpose();
1112
+      endstops_hit_on_purpose(); // clear endstop hit flags
1107
       
1113
       
1108
       // we have to let the planner know where we are right now as it is not where we said to go.
1114
       // we have to let the planner know where we are right now as it is not where we said to go.
1109
       long stop_steps = st_get_position(Z_AXIS);
1115
       long stop_steps = st_get_position(Z_AXIS);
1110
       float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
1116
       float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
1111
       current_position[Z_AXIS] = mm;
1117
       current_position[Z_AXIS] = mm;
1112
-      calculate_delta(current_position);
1113
-      plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
1118
+      sync_plan_position_delta();
1114
       
1119
       
1115
     #else // !DELTA
1120
     #else // !DELTA
1116
 
1121
 
1130
       zPosition += home_retract_mm(Z_AXIS);
1135
       zPosition += home_retract_mm(Z_AXIS);
1131
       line_to_z(zPosition);
1136
       line_to_z(zPosition);
1132
       st_synchronize();
1137
       st_synchronize();
1133
-      endstops_hit_on_purpose();
1138
+      endstops_hit_on_purpose(); // clear endstop hit flags
1134
 
1139
 
1135
       // move back down slowly to find bed
1140
       // move back down slowly to find bed
1136
       if (homing_bump_divisor[Z_AXIS] >= 1)
1141
       if (homing_bump_divisor[Z_AXIS] >= 1)
1143
       zPosition -= home_retract_mm(Z_AXIS) * 2;
1148
       zPosition -= home_retract_mm(Z_AXIS) * 2;
1144
       line_to_z(zPosition);
1149
       line_to_z(zPosition);
1145
       st_synchronize();
1150
       st_synchronize();
1146
-      endstops_hit_on_purpose();
1151
+      endstops_hit_on_purpose(); // clear endstop hit flags
1147
 
1152
 
1148
       current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
1153
       current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
1149
       // make sure the planner knows where we are as it may be a bit different than we last said to move to
1154
       // make sure the planner knows where we are as it may be a bit different than we last said to move to
1262
       if (servo_endstops[Z_AXIS] >= 0) {
1267
       if (servo_endstops[Z_AXIS] >= 0) {
1263
 
1268
 
1264
         #if Z_RAISE_AFTER_PROBING > 0
1269
         #if Z_RAISE_AFTER_PROBING > 0
1265
-          do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], Z_RAISE_AFTER_PROBING);
1270
+          do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_AFTER_PROBING);
1266
           st_synchronize();
1271
           st_synchronize();
1267
         #endif
1272
         #endif
1268
 
1273
 
1345
 
1350
 
1346
     #if Z_RAISE_BETWEEN_PROBINGS > 0
1351
     #if Z_RAISE_BETWEEN_PROBINGS > 0
1347
       if (retract_action == ProbeStay) {
1352
       if (retract_action == ProbeStay) {
1348
-        do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], Z_RAISE_BETWEEN_PROBINGS);
1353
+        do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
1349
         st_synchronize();
1354
         st_synchronize();
1350
       }
1355
       }
1351
     #endif
1356
     #endif
1430
 
1435
 
1431
 #endif // ENABLE_AUTO_BED_LEVELING
1436
 #endif // ENABLE_AUTO_BED_LEVELING
1432
 
1437
 
1438
+/**
1439
+ * Home an individual axis
1440
+ */
1441
+
1442
+#define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS)
1443
+
1433
 static void homeaxis(int axis) {
1444
 static void homeaxis(int axis) {
1434
   #define HOMEAXIS_DO(LETTER) \
1445
   #define HOMEAXIS_DO(LETTER) \
1435
     ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
1446
     ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
1436
 
1447
 
1437
-  if (axis == X_AXIS ? HOMEAXIS_DO(X) :
1438
-      axis == Y_AXIS ? HOMEAXIS_DO(Y) :
1439
-      axis == Z_AXIS ? HOMEAXIS_DO(Z) : 0) {
1448
+  if (axis == X_AXIS ? HOMEAXIS_DO(X) : axis == Y_AXIS ? HOMEAXIS_DO(Y) : axis == Z_AXIS ? HOMEAXIS_DO(Z) : 0) {
1440
 
1449
 
1441
     int axis_home_dir;
1450
     int axis_home_dir;
1442
 
1451
 
1446
       axis_home_dir = home_dir(axis);
1455
       axis_home_dir = home_dir(axis);
1447
     #endif
1456
     #endif
1448
 
1457
 
1458
+    // Set the axis position as setup for the move
1449
     current_position[axis] = 0;
1459
     current_position[axis] = 0;
1450
     sync_plan_position();
1460
     sync_plan_position();
1451
 
1461
 
1452
-    #ifndef Z_PROBE_SLED
1453
-      // Engage Servo endstop if enabled
1454
-      #ifdef SERVO_ENDSTOPS
1455
-        #if SERVO_LEVELING
1456
-          if (axis == Z_AXIS) {
1457
-            engage_z_probe();
1458
-          }
1459
-          else
1460
-        #endif // SERVO_LEVELING
1461
-
1462
-        if (servo_endstops[axis] > -1)
1463
-          servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
1462
+    // Engage Servo endstop if enabled
1463
+    #ifdef SERVO_ENDSTOPS && !defined(Z_PROBE_SLED)
1464
 
1464
 
1465
-      #endif // SERVO_ENDSTOPS
1465
+      #if SERVO_LEVELING
1466
+        if (axis == Z_AXIS) engage_z_probe(); else
1467
+      #endif
1468
+        {
1469
+          if (servo_endstops[axis] > -1)
1470
+            servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
1471
+        }
1466
 
1472
 
1467
-    #endif // Z_PROBE_SLED
1473
+    #endif // SERVO_ENDSTOPS && !Z_PROBE_SLED
1468
 
1474
 
1469
     #ifdef Z_DUAL_ENDSTOPS
1475
     #ifdef Z_DUAL_ENDSTOPS
1470
       if (axis == Z_AXIS) In_Homing_Process(true);
1476
       if (axis == Z_AXIS) In_Homing_Process(true);
1471
     #endif
1477
     #endif
1472
 
1478
 
1479
+    // Move towards the endstop until an endstop is triggered
1473
     destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
1480
     destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
1474
     feedrate = homing_feedrate[axis];
1481
     feedrate = homing_feedrate[axis];
1475
     line_to_destination();
1482
     line_to_destination();
1476
     st_synchronize();
1483
     st_synchronize();
1477
 
1484
 
1485
+    // Set the axis position as setup for the move
1478
     current_position[axis] = 0;
1486
     current_position[axis] = 0;
1479
     sync_plan_position();
1487
     sync_plan_position();
1488
+
1489
+    // Move away from the endstop by the axis HOME_RETRACT_MM
1480
     destination[axis] = -home_retract_mm(axis) * axis_home_dir;
1490
     destination[axis] = -home_retract_mm(axis) * axis_home_dir;
1481
     line_to_destination();
1491
     line_to_destination();
1482
     st_synchronize();
1492
     st_synchronize();
1483
 
1493
 
1484
-    destination[axis] = 2 * home_retract_mm(axis) * axis_home_dir;
1485
-
1494
+    // Slow down the feedrate for the next move
1486
     if (homing_bump_divisor[axis] >= 1)
1495
     if (homing_bump_divisor[axis] >= 1)
1487
       feedrate = homing_feedrate[axis] / homing_bump_divisor[axis];
1496
       feedrate = homing_feedrate[axis] / homing_bump_divisor[axis];
1488
     else {
1497
     else {
1489
       feedrate = homing_feedrate[axis] / 10;
1498
       feedrate = homing_feedrate[axis] / 10;
1490
-      SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
1499
+      SERIAL_ECHOLNPGM("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
1491
     }
1500
     }
1492
 
1501
 
1502
+    // Move slowly towards the endstop until triggered
1503
+    destination[axis] = 2 * home_retract_mm(axis) * axis_home_dir;
1493
     line_to_destination();
1504
     line_to_destination();
1494
     st_synchronize();
1505
     st_synchronize();
1506
+
1495
     #ifdef Z_DUAL_ENDSTOPS
1507
     #ifdef Z_DUAL_ENDSTOPS
1496
-      if (axis==Z_AXIS)
1497
-      {
1498
-        feedrate = homing_feedrate[axis];
1499
-        sync_plan_position();
1500
-        if (axis_home_dir > 0)
1501
-        {
1502
-          destination[axis] = (-1) * fabs(z_endstop_adj);
1503
-          if (z_endstop_adj > 0) Lock_z_motor(true); else Lock_z2_motor(true);
1504
-        } else {
1505
-          destination[axis] = fabs(z_endstop_adj);
1506
-          if (z_endstop_adj < 0) Lock_z_motor(true); else Lock_z2_motor(true);        
1508
+      if (axis == Z_AXIS) {
1509
+        float adj = fabs(z_endstop_adj);
1510
+        bool lockZ1;
1511
+        if (axis_home_dir > 0) {
1512
+          adj = -adj;
1513
+          lockZ1 = (z_endstop_adj > 0);
1507
         }
1514
         }
1515
+        else
1516
+          lockZ1 = (z_endstop_adj < 0);
1517
+
1518
+        if (lockZ1) Lock_z_motor(true); else Lock_z2_motor(true);
1519
+        sync_plan_position();
1520
+
1521
+        // Move to the adjusted endstop height
1522
+        feedrate = homing_feedrate[axis];
1523
+        destination[Z_AXIS] = adj;
1508
         line_to_destination();
1524
         line_to_destination();
1509
         st_synchronize();
1525
         st_synchronize();
1510
-        Lock_z_motor(false);
1511
-        Lock_z2_motor(false);
1526
+
1527
+        if (lockZ1) Lock_z_motor(false); else Lock_z2_motor(false);
1512
         In_Homing_Process(false);
1528
         In_Homing_Process(false);
1529
+      } // Z_AXIS
1530
+    #endif
1531
+
1532
+    #ifdef DELTA
1533
+      // retrace by the amount specified in endstop_adj
1534
+      if (endstop_adj[axis] * axis_home_dir < 0) {
1535
+        sync_plan_position();
1536
+        destination[axis] = endstop_adj[axis];
1537
+        line_to_destination();
1538
+        st_synchronize();
1513
       }
1539
       }
1514
     #endif
1540
     #endif
1515
 
1541
 
1516
-#ifdef DELTA
1517
-    // retrace by the amount specified in endstop_adj
1518
-    if (endstop_adj[axis] * axis_home_dir < 0) {
1519
-      sync_plan_position();
1520
-      destination[axis] = endstop_adj[axis];
1521
-      line_to_destination();
1522
-      st_synchronize();
1523
-    }
1524
-#endif
1542
+    // Set the axis position to its home position (plus home offsets)
1525
     axis_is_at_home(axis);
1543
     axis_is_at_home(axis);
1544
+
1526
     destination[axis] = current_position[axis];
1545
     destination[axis] = current_position[axis];
1527
     feedrate = 0.0;
1546
     feedrate = 0.0;
1528
-    endstops_hit_on_purpose();
1547
+    endstops_hit_on_purpose(); // clear endstop hit flags
1529
     axis_known_position[axis] = true;
1548
     axis_known_position[axis] = true;
1530
 
1549
 
1531
     // Retract Servo endstop if enabled
1550
     // Retract Servo endstop if enabled
1532
     #ifdef SERVO_ENDSTOPS
1551
     #ifdef SERVO_ENDSTOPS
1533
-      if (servo_endstops[axis] > -1) {
1552
+      if (servo_endstops[axis] > -1)
1534
         servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2 + 1]);
1553
         servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2 + 1]);
1535
-      }
1536
     #endif
1554
     #endif
1537
-#if SERVO_LEVELING
1538
-  #ifndef Z_PROBE_SLED
1539
-    if (axis==Z_AXIS) retract_z_probe();
1540
-  #endif
1541
-#endif
1555
+
1556
+    #if SERVO_LEVELING && !defined(Z_PROBE_SLED)
1557
+      if (axis == Z_AXIS) retract_z_probe();
1558
+    #endif
1542
 
1559
 
1543
   }
1560
   }
1544
 }
1561
 }
1545
-#define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS)
1546
 
1562
 
1547
-void refresh_cmd_timeout(void)
1548
-{
1549
-  previous_millis_cmd = millis();
1550
-}
1563
+void refresh_cmd_timeout(void) { previous_millis_cmd = millis(); }
1551
 
1564
 
1552
 #ifdef FWRETRACT
1565
 #ifdef FWRETRACT
1566
+
1553
   void retract(bool retracting, bool swapretract = false) {
1567
   void retract(bool retracting, bool swapretract = false) {
1554
-    if(retracting && !retracted[active_extruder]) {
1555
-      destination[X_AXIS]=current_position[X_AXIS];
1556
-      destination[Y_AXIS]=current_position[Y_AXIS];
1557
-      destination[Z_AXIS]=current_position[Z_AXIS];
1558
-      destination[E_AXIS]=current_position[E_AXIS];
1559
-      if (swapretract) {
1560
-        current_position[E_AXIS]+=retract_length_swap/volumetric_multiplier[active_extruder];
1561
-      } else {
1562
-        current_position[E_AXIS]+=retract_length/volumetric_multiplier[active_extruder];
1563
-      }
1564
-      plan_set_e_position(current_position[E_AXIS]);
1565
-      float oldFeedrate = feedrate;
1568
+
1569
+    if (retracting == retracted[active_extruder]) return;
1570
+
1571
+    float oldFeedrate = feedrate;
1572
+
1573
+    for (int i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i];
1574
+
1575
+    if (retracting) {
1576
+
1566
       feedrate = retract_feedrate * 60;
1577
       feedrate = retract_feedrate * 60;
1567
-      retracted[active_extruder]=true;
1578
+      current_position[E_AXIS] += (swapretract ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder];
1579
+      plan_set_e_position(current_position[E_AXIS]);
1568
       prepare_move();
1580
       prepare_move();
1569
-      if(retract_zlift > 0.01) {
1570
-         current_position[Z_AXIS]-=retract_zlift;
1571
-#ifdef DELTA
1572
-         calculate_delta(current_position); // change cartesian kinematic to  delta kinematic;
1573
-         plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
1574
-#else
1575
-         sync_plan_position();
1576
-#endif
1577
-         prepare_move();
1578
-      }
1579
-      feedrate = oldFeedrate;
1580
-    } else if(!retracting && retracted[active_extruder]) {
1581
-      destination[X_AXIS]=current_position[X_AXIS];
1582
-      destination[Y_AXIS]=current_position[Y_AXIS];
1583
-      destination[Z_AXIS]=current_position[Z_AXIS];
1584
-      destination[E_AXIS]=current_position[E_AXIS];
1585
-      if(retract_zlift > 0.01) {
1586
-         current_position[Z_AXIS]+=retract_zlift;
1587
-#ifdef DELTA
1588
-         calculate_delta(current_position); // change cartesian kinematic  to  delta kinematic;
1589
-         plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
1590
-#else
1591
-         sync_plan_position();
1592
-#endif
1593
-         //prepare_move();
1581
+
1582
+      if (retract_zlift > 0.01) {
1583
+        current_position[Z_AXIS] -= retract_zlift;
1584
+        #ifdef DELTA
1585
+          sync_plan_position_delta();
1586
+        #else
1587
+          sync_plan_position();
1588
+        #endif
1589
+        prepare_move();
1594
       }
1590
       }
1595
-      if (swapretract) {
1596
-        current_position[E_AXIS]-=(retract_length_swap+retract_recover_length_swap)/volumetric_multiplier[active_extruder]; 
1597
-      } else {
1598
-        current_position[E_AXIS]-=(retract_length+retract_recover_length)/volumetric_multiplier[active_extruder]; 
1591
+    }
1592
+    else {
1593
+
1594
+      if (retract_zlift > 0.01) {
1595
+        current_position[Z_AXIS] + =retract_zlift;
1596
+        #ifdef DELTA
1597
+          sync_plan_position_delta();
1598
+        #else
1599
+          sync_plan_position();
1600
+        #endif
1601
+        //prepare_move();
1599
       }
1602
       }
1600
-      plan_set_e_position(current_position[E_AXIS]);
1601
-      float oldFeedrate = feedrate;
1603
+
1602
       feedrate = retract_recover_feedrate * 60;
1604
       feedrate = retract_recover_feedrate * 60;
1603
-      retracted[active_extruder] = false;
1605
+      float move_e = swapretract ? retract_length_swap + retract_recover_length_swap : retract_length + retract_recover_length;
1606
+      current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder];
1607
+      plan_set_e_position(current_position[E_AXIS]);
1604
       prepare_move();
1608
       prepare_move();
1605
-      feedrate = oldFeedrate;
1606
     }
1609
     }
1607
-  } //retract
1608
-#endif //FWRETRACT
1610
+
1611
+    feedrate = oldFeedrate;
1612
+    retracted[active_extruder] = retract;
1613
+
1614
+  } // retract()
1615
+
1616
+#endif // FWRETRACT
1609
 
1617
 
1610
 #ifdef Z_PROBE_SLED
1618
 #ifdef Z_PROBE_SLED
1611
 
1619
 
1613
     #define SLED_DOCKING_OFFSET 0
1621
     #define SLED_DOCKING_OFFSET 0
1614
   #endif
1622
   #endif
1615
 
1623
 
1616
-//
1617
-// Method to dock/undock a sled designed by Charles Bell.
1618
-//
1619
-// dock[in]     If true, move to MAX_X and engage the electromagnet
1620
-// offset[in]   The additional distance to move to adjust docking location
1621
-//
1622
-static void dock_sled(bool dock, int offset=0) {
1623
- int z_loc;
1624
- 
1625
- if (!((axis_known_position[X_AXIS]) && (axis_known_position[Y_AXIS]))) {
1626
-   LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
1627
-   SERIAL_ECHO_START;
1628
-   SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
1629
-   return;
1630
- }
1631
-
1632
- if (dock) {
1633
-   do_blocking_move_to(X_MAX_POS + SLED_DOCKING_OFFSET + offset,
1634
-                       current_position[Y_AXIS],
1635
-                       current_position[Z_AXIS]);
1636
-   // turn off magnet
1637
-   digitalWrite(SERVO0_PIN, LOW);
1638
- } else {
1639
-   if (current_position[Z_AXIS] < (Z_RAISE_BEFORE_PROBING + 5))
1640
-     z_loc = Z_RAISE_BEFORE_PROBING;
1641
-   else
1642
-     z_loc = current_position[Z_AXIS];
1643
-   do_blocking_move_to(X_MAX_POS + SLED_DOCKING_OFFSET + offset,
1644
-                       Y_PROBE_OFFSET_FROM_EXTRUDER, z_loc);
1645
-   // turn on magnet
1646
-   digitalWrite(SERVO0_PIN, HIGH);
1647
- }
1648
-}
1649
-#endif
1624
+  //
1625
+  // Method to dock/undock a sled designed by Charles Bell.
1626
+  //
1627
+  // dock[in]     If true, move to MAX_X and engage the electromagnet
1628
+  // offset[in]   The additional distance to move to adjust docking location
1629
+  //
1630
+  static void dock_sled(bool dock, int offset=0) {
1631
+    if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
1632
+      LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
1633
+      SERIAL_ECHO_START;
1634
+      SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
1635
+      return;
1636
+    }
1637
+
1638
+    if (dock) {
1639
+      do_blocking_move_to(X_MAX_POS + SLED_DOCKING_OFFSET + offset, current_position[Y_AXIS], current_position[Z_AXIS]);
1640
+      digitalWrite(SERVO0_PIN, LOW); // turn off magnet
1641
+    } else {
1642
+      float z_loc = current_position[Z_AXIS];
1643
+      if (z_loc < Z_RAISE_BEFORE_PROBING + 5) z_loc = Z_RAISE_BEFORE_PROBING;
1644
+      do_blocking_move_to(X_MAX_POS + SLED_DOCKING_OFFSET + offset, Y_PROBE_OFFSET_FROM_EXTRUDER, z_loc);
1645
+      digitalWrite(SERVO0_PIN, HIGH); // turn on magnet
1646
+    }
1647
+  }
1648
+
1649
+#endif // Z_PROBE_SLED
1650
 
1650
 
1651
 /**
1651
 /**
1652
  *
1652
  *
1788
     feedrate = 1.732 * homing_feedrate[X_AXIS];
1788
     feedrate = 1.732 * homing_feedrate[X_AXIS];
1789
     line_to_destination();
1789
     line_to_destination();
1790
     st_synchronize();
1790
     st_synchronize();
1791
-    endstops_hit_on_purpose();
1791
+    endstops_hit_on_purpose(); // clear endstop hit flags
1792
 
1792
 
1793
     // Destination reached
1793
     // Destination reached
1794
     for (int i = X_AXIS; i <= Z_AXIS; i++) current_position[i] = destination[i];
1794
     for (int i = X_AXIS; i <= Z_AXIS; i++) current_position[i] = destination[i];
1798
     HOMEAXIS(Y);
1798
     HOMEAXIS(Y);
1799
     HOMEAXIS(Z);
1799
     HOMEAXIS(Z);
1800
 
1800
 
1801
-    calculate_delta(current_position);
1802
-    plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
1801
+    sync_plan_position_delta();
1803
 
1802
 
1804
   #else // NOT DELTA
1803
   #else // NOT DELTA
1805
 
1804
 
1807
           homeY = code_seen(axis_codes[Y_AXIS]),
1806
           homeY = code_seen(axis_codes[Y_AXIS]),
1808
           homeZ = code_seen(axis_codes[Z_AXIS]);
1807
           homeZ = code_seen(axis_codes[Z_AXIS]);
1809
 
1808
 
1810
-    home_all_axis = !homeX && !homeY && !homeZ; // No parameters means home all axes
1809
+    home_all_axis = !(homeX || homeY || homeZ) || (homeX && homeY && homeZ);
1811
 
1810
 
1812
     #if Z_HOME_DIR > 0                      // If homing away from BED do Z first
1811
     #if Z_HOME_DIR > 0                      // If homing away from BED do Z first
1813
 
1812
 
1826
     #endif
1825
     #endif
1827
 
1826
 
1828
     #ifdef QUICK_HOME
1827
     #ifdef QUICK_HOME
1829
-      if (home_all_axis || (homeX && homeY)) {  //first diagonal move
1828
+
1829
+      if (home_all_axis || (homeX && homeY)) {  // First diagonal move
1830
+
1830
         current_position[X_AXIS] = current_position[Y_AXIS] = 0;
1831
         current_position[X_AXIS] = current_position[Y_AXIS] = 0;
1831
 
1832
 
1832
         #ifdef DUAL_X_CARRIAGE
1833
         #ifdef DUAL_X_CARRIAGE
1837
         #endif
1838
         #endif
1838
 
1839
 
1839
         sync_plan_position();
1840
         sync_plan_position();
1840
-        destination[X_AXIS] = 1.5 * max_length(X_AXIS) * x_axis_home_dir;
1841
-        destination[Y_AXIS] = 1.5 * max_length(Y_AXIS) * home_dir(Y_AXIS);
1842
-        feedrate = homing_feedrate[X_AXIS];
1843
-        if (homing_feedrate[Y_AXIS] < feedrate) feedrate = homing_feedrate[Y_AXIS];
1844
-        if (max_length(X_AXIS) > max_length(Y_AXIS)) {
1845
-          feedrate *= sqrt(pow(max_length(Y_AXIS) / max_length(X_AXIS), 2) + 1);
1846
-        } else {
1847
-          feedrate *= sqrt(pow(max_length(X_AXIS) / max_length(Y_AXIS), 2) + 1);
1848
-        }
1841
+
1842
+        float mlx = max_length(X_AXIS), mly = max_length(Y_AXIS),
1843
+              mlratio = mlx>mly ? mly/mlx : mlx/mly;
1844
+
1845
+        destination[X_AXIS] = 1.5 * mlx * x_axis_home_dir;
1846
+        destination[Y_AXIS] = 1.5 * mly * home_dir(Y_AXIS);
1847
+        feedrate = min(homing_feedrate[X_AXIS], homing_feedrate[Y_AXIS]) * sqrt(mlratio * mlratio + 1);
1849
         line_to_destination();
1848
         line_to_destination();
1850
         st_synchronize();
1849
         st_synchronize();
1851
 
1850
 
1852
         axis_is_at_home(X_AXIS);
1851
         axis_is_at_home(X_AXIS);
1853
         axis_is_at_home(Y_AXIS);
1852
         axis_is_at_home(Y_AXIS);
1854
         sync_plan_position();
1853
         sync_plan_position();
1854
+
1855
         destination[X_AXIS] = current_position[X_AXIS];
1855
         destination[X_AXIS] = current_position[X_AXIS];
1856
         destination[Y_AXIS] = current_position[Y_AXIS];
1856
         destination[Y_AXIS] = current_position[Y_AXIS];
1857
         line_to_destination();
1857
         line_to_destination();
1858
         feedrate = 0.0;
1858
         feedrate = 0.0;
1859
         st_synchronize();
1859
         st_synchronize();
1860
-        endstops_hit_on_purpose();
1860
+        endstops_hit_on_purpose(); // clear endstop hit flags
1861
 
1861
 
1862
         current_position[X_AXIS] = destination[X_AXIS];
1862
         current_position[X_AXIS] = destination[X_AXIS];
1863
         current_position[Y_AXIS] = destination[Y_AXIS];
1863
         current_position[Y_AXIS] = destination[Y_AXIS];
1865
           current_position[Z_AXIS] = destination[Z_AXIS];
1865
           current_position[Z_AXIS] = destination[Z_AXIS];
1866
         #endif
1866
         #endif
1867
       }
1867
       }
1868
-    #endif //QUICK_HOME
1868
+
1869
+    #endif // QUICK_HOME
1869
 
1870
 
1870
     // Home X
1871
     // Home X
1871
     if (home_all_axis || homeX) {
1872
     if (home_all_axis || homeX) {
1947
                 && cpy >= Y_MIN_POS - Y_PROBE_OFFSET_FROM_EXTRUDER
1948
                 && cpy >= Y_MIN_POS - Y_PROBE_OFFSET_FROM_EXTRUDER
1948
                 && cpy <= Y_MAX_POS - Y_PROBE_OFFSET_FROM_EXTRUDER) {
1949
                 && cpy <= Y_MAX_POS - Y_PROBE_OFFSET_FROM_EXTRUDER) {
1949
               current_position[Z_AXIS] = 0;
1950
               current_position[Z_AXIS] = 0;
1950
-              plan_set_position(cpx, cpy, current_position[Z_AXIS], current_position[E_AXIS]);
1951
+              plan_set_position(cpx, cpy, 0, current_position[E_AXIS]);
1951
               destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
1952
               destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
1952
               feedrate = max_feedrate[Z_AXIS];
1953
               feedrate = max_feedrate[Z_AXIS];
1953
               line_to_destination();
1954
               line_to_destination();
1986
   #endif // else DELTA
1987
   #endif // else DELTA
1987
 
1988
 
1988
   #ifdef SCARA
1989
   #ifdef SCARA
1989
-    calculate_delta(current_position);
1990
-    plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
1990
+    sync_plan_position_delta();
1991
   #endif
1991
   #endif
1992
 
1992
 
1993
   #ifdef ENDSTOPS_ONLY_FOR_HOMING
1993
   #ifdef ENDSTOPS_ONLY_FOR_HOMING
2014
   feedrate = saved_feedrate;
2014
   feedrate = saved_feedrate;
2015
   feedmultiply = saved_feedmultiply;
2015
   feedmultiply = saved_feedmultiply;
2016
   previous_millis_cmd = millis();
2016
   previous_millis_cmd = millis();
2017
-  endstops_hit_on_purpose();
2017
+  endstops_hit_on_purpose(); // clear endstop hit flags
2018
 }
2018
 }
2019
 
2019
 
2020
 #if defined(MESH_BED_LEVELING) || defined(ENABLE_AUTO_BED_LEVELING)
2020
 #if defined(MESH_BED_LEVELING) || defined(ENABLE_AUTO_BED_LEVELING)
2186
         bool do_topography_map = verbose_level > 2 || code_seen('T') || code_seen('t');
2186
         bool do_topography_map = verbose_level > 2 || code_seen('T') || code_seen('t');
2187
       #endif
2187
       #endif
2188
 
2188
 
2189
-      if (verbose_level > 0)
2190
-      {
2189
+      if (verbose_level > 0) {
2191
         SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n");
2190
         SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n");
2192
         if (dryrun) SERIAL_ECHOLN("Running in DRY-RUN mode");
2191
         if (dryrun) SERIAL_ECHOLN("Running in DRY-RUN mode");
2193
       }
2192
       }
2262
         current_position[Y_AXIS] = uncorrected_position.y;
2261
         current_position[Y_AXIS] = uncorrected_position.y;
2263
         current_position[Z_AXIS] = uncorrected_position.z;
2262
         current_position[Z_AXIS] = uncorrected_position.z;
2264
         sync_plan_position();
2263
         sync_plan_position();
2265
-
2266
       #endif // !DELTA
2264
       #endif // !DELTA
2267
     }
2265
     }
2268
-    
2266
+
2269
     setup_for_endstop_move();
2267
     setup_for_endstop_move();
2270
 
2268
 
2271
     feedrate = homing_feedrate[Z_AXIS];
2269
     feedrate = homing_feedrate[Z_AXIS];
2273
     #ifdef AUTO_BED_LEVELING_GRID
2271
     #ifdef AUTO_BED_LEVELING_GRID
2274
 
2272
 
2275
       // probe at the points of a lattice grid
2273
       // probe at the points of a lattice grid
2276
-      const int xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (auto_bed_leveling_grid_points-1);
2277
-      const int yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (auto_bed_leveling_grid_points-1);
2274
+      const int xGridSpacing = (right_probe_bed_position - left_probe_bed_position) / (auto_bed_leveling_grid_points - 1),
2275
+                yGridSpacing = (back_probe_bed_position - front_probe_bed_position) / (auto_bed_leveling_grid_points - 1);
2278
 
2276
 
2279
       #ifdef DELTA
2277
       #ifdef DELTA
2280
         delta_grid_spacing[0] = xGridSpacing;
2278
         delta_grid_spacing[0] = xGridSpacing;
2826
   inline void gcode_M48() {
2824
   inline void gcode_M48() {
2827
 
2825
 
2828
     double sum = 0.0, mean = 0.0, sigma = 0.0, sample_set[50];
2826
     double sum = 0.0, mean = 0.0, sigma = 0.0, sample_set[50];
2829
-    int verbose_level = 1, n = 0, j, n_samples = 10, n_legs = 0, engage_probe_for_each_reading = 0;
2830
-    double X_current, Y_current, Z_current;
2831
-    double X_probe_location, Y_probe_location, Z_start_location, ext_position;
2827
+    int verbose_level = 1, n_samples = 10, n_legs = 0;
2832
     
2828
     
2833
     if (code_seen('V') || code_seen('v')) {
2829
     if (code_seen('V') || code_seen('v')) {
2834
       verbose_level = code_value();
2830
       verbose_level = code_value();
2849
       }
2845
       }
2850
     }
2846
     }
2851
 
2847
 
2852
-    X_current = X_probe_location = st_get_position_mm(X_AXIS);
2853
-    Y_current = Y_probe_location = st_get_position_mm(Y_AXIS);
2854
-    Z_current = st_get_position_mm(Z_AXIS);
2855
-    Z_start_location = st_get_position_mm(Z_AXIS) + Z_RAISE_BEFORE_PROBING;
2856
-    ext_position = st_get_position_mm(E_AXIS);
2848
+    double X_probe_location, Y_probe_location,
2849
+           X_current = X_probe_location = st_get_position_mm(X_AXIS),
2850
+           Y_current = Y_probe_location = st_get_position_mm(Y_AXIS),
2851
+           Z_current = st_get_position_mm(Z_AXIS),
2852
+           Z_start_location = Z_current + Z_RAISE_BEFORE_PROBING,
2853
+           ext_position = st_get_position_mm(E_AXIS);
2857
 
2854
 
2858
-    if (code_seen('E') || code_seen('e'))
2859
-      engage_probe_for_each_reading++;
2855
+    bool engage_probe_for_each_reading = code_seen('E') || code_seen('e');
2860
 
2856
 
2861
     if (code_seen('X') || code_seen('x')) {
2857
     if (code_seen('X') || code_seen('x')) {
2862
       X_probe_location = code_value() - X_PROBE_OFFSET_FROM_EXTRUDER;
2858
       X_probe_location = code_value() - X_PROBE_OFFSET_FROM_EXTRUDER;
2936
 
2932
 
2937
     if (engage_probe_for_each_reading) retract_z_probe();
2933
     if (engage_probe_for_each_reading) retract_z_probe();
2938
 
2934
 
2939
-    for (n=0; n < n_samples; n++) {
2935
+    for (uint16_t n=0; n < n_samples; n++) {
2940
 
2936
 
2941
-      do_blocking_move_to( X_probe_location, Y_probe_location, Z_start_location); // Make sure we are at the probe location
2937
+      do_blocking_move_to(X_probe_location, Y_probe_location, Z_start_location); // Make sure we are at the probe location
2942
 
2938
 
2943
       if (n_legs) {
2939
       if (n_legs) {
2944
-        double radius=0.0, theta=0.0;
2945
-        int l;
2946
-        int rotational_direction = (unsigned long) millis() & 0x0001;     // clockwise or counter clockwise
2947
-        radius = (unsigned long)millis() % (long)(X_MAX_LENGTH / 4);      // limit how far out to go
2948
-        theta = (float)((unsigned long)millis() % 360L) / (360. / (2 * 3.1415926)); // turn into radians
2940
+        unsigned long ms = millis();
2941
+        double radius = ms % (X_MAX_LENGTH / 4),       // limit how far out to go
2942
+               theta = RADIANS(ms % 360L);
2943
+        float dir = (ms & 0x0001) ? 1 : -1;            // clockwise or counter clockwise
2949
 
2944
 
2950
         //SERIAL_ECHOPAIR("starting radius: ",radius);
2945
         //SERIAL_ECHOPAIR("starting radius: ",radius);
2951
         //SERIAL_ECHOPAIR("   theta: ",theta);
2946
         //SERIAL_ECHOPAIR("   theta: ",theta);
2952
-        //SERIAL_ECHOPAIR("   direction: ",rotational_direction);
2947
+        //SERIAL_ECHOPAIR("   direction: ",dir);
2953
         //SERIAL_EOL;
2948
         //SERIAL_EOL;
2954
 
2949
 
2955
-        float dir = rotational_direction ? 1 : -1;
2956
-        for (l = 0; l < n_legs - 1; l++) {
2957
-          theta += dir * (float)((unsigned long)millis() % 20L) / (360.0/(2*3.1415926)); // turn into radians
2958
-
2959
-          radius += (float)(((long)((unsigned long) millis() % 10L)) - 5L);
2950
+        for (int l = 0; l < n_legs - 1; l++) {
2951
+          ms = millis();
2952
+          theta += RADIANS(dir * (ms % 20L));
2953
+          radius += (ms % 10L) - 5L;
2960
           if (radius < 0.0) radius = -radius;
2954
           if (radius < 0.0) radius = -radius;
2961
 
2955
 
2962
           X_current = X_probe_location + cos(theta) * radius;
2956
           X_current = X_probe_location + cos(theta) * radius;
2963
           Y_current = Y_probe_location + sin(theta) * radius;
2957
           Y_current = Y_probe_location + sin(theta) * radius;
2964
-
2965
-          // Make sure our X & Y are sane
2966
           X_current = constrain(X_current, X_MIN_POS, X_MAX_POS);
2958
           X_current = constrain(X_current, X_MIN_POS, X_MAX_POS);
2967
           Y_current = constrain(Y_current, Y_MIN_POS, Y_MAX_POS);
2959
           Y_current = constrain(Y_current, Y_MIN_POS, Y_MAX_POS);
2968
 
2960
 
2972
             SERIAL_EOL;
2964
             SERIAL_EOL;
2973
           }
2965
           }
2974
 
2966
 
2975
-          do_blocking_move_to( X_current, Y_current, Z_current );
2976
-        }
2977
-        do_blocking_move_to( X_probe_location, Y_probe_location, Z_start_location); // Go back to the probe location
2978
-      }
2967
+          do_blocking_move_to(X_current, Y_current, Z_current);
2968
+
2969
+        } // n_legs loop
2970
+
2971
+        do_blocking_move_to(X_probe_location, Y_probe_location, Z_start_location); // Go back to the probe location
2972
+
2973
+      } // n_legs
2979
 
2974
 
2980
       if (engage_probe_for_each_reading)  {
2975
       if (engage_probe_for_each_reading)  {
2981
         engage_z_probe(); 
2976
         engage_z_probe(); 
2991
       // Get the current mean for the data points we have so far
2986
       // Get the current mean for the data points we have so far
2992
       //
2987
       //
2993
       sum = 0.0;
2988
       sum = 0.0;
2994
-      for (j=0; j<=n; j++) sum += sample_set[j];
2995
-      mean = sum / (double (n+1));
2989
+      for (int j = 0; j <= n; j++) sum += sample_set[j];
2990
+      mean = sum / (n + 1);
2996
 
2991
 
2997
       //
2992
       //
2998
       // Now, use that mean to calculate the standard deviation for the
2993
       // Now, use that mean to calculate the standard deviation for the
2999
       // data points we have so far
2994
       // data points we have so far
3000
       //
2995
       //
3001
       sum = 0.0;
2996
       sum = 0.0;
3002
-      for (j=0; j<=n; j++) sum += (sample_set[j]-mean) * (sample_set[j]-mean);
3003
-      sigma = sqrt( sum / (double (n+1)) );
2997
+      for (int j = 0; j <= n; j++) {
2998
+        float ss = sample_set[j] - mean;
2999
+        sum += ss * ss;
3000
+      }
3001
+      sigma = sqrt(sum / (n + 1));
3004
 
3002
 
3005
       if (verbose_level > 1) {
3003
       if (verbose_level > 1) {
3006
         SERIAL_PROTOCOL(n+1);
3004
         SERIAL_PROTOCOL(n+1);
3007
-        SERIAL_PROTOCOL(" of ");
3005
+        SERIAL_PROTOCOLPGM(" of ");
3008
         SERIAL_PROTOCOL(n_samples);
3006
         SERIAL_PROTOCOL(n_samples);
3009
         SERIAL_PROTOCOLPGM("   z: ");
3007
         SERIAL_PROTOCOLPGM("   z: ");
3010
         SERIAL_PROTOCOL_F(current_position[Z_AXIS], 6);
3008
         SERIAL_PROTOCOL_F(current_position[Z_AXIS], 6);
3011
-      }
3012
-
3013
-      if (verbose_level > 2) {
3014
-        SERIAL_PROTOCOL(" mean: ");
3015
-        SERIAL_PROTOCOL_F(mean,6);
3016
-        SERIAL_PROTOCOL("   sigma: ");
3017
-        SERIAL_PROTOCOL_F(sigma,6);
3009
+        if (verbose_level > 2) {
3010
+          SERIAL_PROTOCOLPGM(" mean: ");
3011
+          SERIAL_PROTOCOL_F(mean,6);
3012
+          SERIAL_PROTOCOLPGM("   sigma: ");
3013
+          SERIAL_PROTOCOL_F(sigma,6);
3014
+        }
3018
       }
3015
       }
3019
 
3016
 
3020
       if (verbose_level > 0) SERIAL_EOL;
3017
       if (verbose_level > 0) SERIAL_EOL;
3021
 
3018
 
3022
-      plan_buffer_line(X_probe_location, Y_probe_location, Z_start_location,
3023
-          current_position[E_AXIS], homing_feedrate[Z_AXIS]/60, active_extruder);
3019
+      plan_buffer_line(X_probe_location, Y_probe_location, Z_start_location, current_position[E_AXIS], homing_feedrate[Z_AXIS]/60, active_extruder);
3024
       st_synchronize();
3020
       st_synchronize();
3025
 
3021
 
3026
       if (engage_probe_for_each_reading) {
3022
       if (engage_probe_for_each_reading) {
3027
-        retract_z_probe();  
3023
+        retract_z_probe();
3028
         delay(1000);
3024
         delay(1000);
3029
       }
3025
       }
3030
     }
3026
     }
3031
 
3027
 
3032
-    retract_z_probe();
3033
-    delay(1000);
3028
+    if (!engage_probe_for_each_reading) {
3029
+      retract_z_probe();
3030
+      delay(1000);
3031
+    }
3034
 
3032
 
3035
     clean_up_after_endstop_move();
3033
     clean_up_after_endstop_move();
3036
 
3034
 
4674
           active_extruder = tmp_extruder;
4672
           active_extruder = tmp_extruder;
4675
         #endif // !DUAL_X_CARRIAGE
4673
         #endif // !DUAL_X_CARRIAGE
4676
         #ifdef DELTA
4674
         #ifdef DELTA
4677
-          calculate_delta(current_position); // change cartesian kinematic  to  delta kinematic;
4678
-          //sent position to plan_set_position();
4679
-          plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],current_position[E_AXIS]);
4675
+          sync_plan_position_delta();
4680
         #else
4676
         #else
4681
           sync_plan_position();
4677
           sync_plan_position();
4682
         #endif
4678
         #endif
5265
 }
5261
 }
5266
 
5262
 
5267
 #ifdef DELTA
5263
 #ifdef DELTA
5268
-void recalc_delta_settings(float radius, float diagonal_rod)
5269
-{
5270
-   delta_tower1_x= -SIN_60*radius; // front left tower
5271
-   delta_tower1_y= -COS_60*radius;     
5272
-   delta_tower2_x=  SIN_60*radius; // front right tower
5273
-   delta_tower2_y= -COS_60*radius;     
5274
-   delta_tower3_x= 0.0;                  // back middle tower
5275
-   delta_tower3_y= radius;
5276
-   delta_diagonal_rod_2= sq(diagonal_rod);
5277
-}
5278
 
5264
 
5279
-void calculate_delta(float cartesian[3])
5280
-{
5281
-  delta[X_AXIS] = sqrt(delta_diagonal_rod_2
5282
-                       - sq(delta_tower1_x-cartesian[X_AXIS])
5283
-                       - sq(delta_tower1_y-cartesian[Y_AXIS])
5284
-                       ) + cartesian[Z_AXIS];
5285
-  delta[Y_AXIS] = sqrt(delta_diagonal_rod_2
5286
-                       - sq(delta_tower2_x-cartesian[X_AXIS])
5287
-                       - sq(delta_tower2_y-cartesian[Y_AXIS])
5288
-                       ) + cartesian[Z_AXIS];
5289
-  delta[Z_AXIS] = sqrt(delta_diagonal_rod_2
5290
-                       - sq(delta_tower3_x-cartesian[X_AXIS])
5291
-                       - sq(delta_tower3_y-cartesian[Y_AXIS])
5292
-                       ) + cartesian[Z_AXIS];
5293
-  /*
5294
-  SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]);
5295
-  SERIAL_ECHOPGM(" y="); SERIAL_ECHO(cartesian[Y_AXIS]);
5296
-  SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(cartesian[Z_AXIS]);
5265
+  void recalc_delta_settings(float radius, float diagonal_rod) {
5266
+    delta_tower1_x = -SIN_60 * radius;  // front left tower
5267
+    delta_tower1_y = -COS_60 * radius;
5268
+    delta_tower2_x =  SIN_60 * radius;  // front right tower
5269
+    delta_tower2_y = -COS_60 * radius;
5270
+    delta_tower3_x = 0.0;               // back middle tower
5271
+    delta_tower3_y = radius;
5272
+    delta_diagonal_rod_2 = sq(diagonal_rod);
5273
+  }
5297
 
5274
 
5298
-  SERIAL_ECHOPGM("delta x="); SERIAL_ECHO(delta[X_AXIS]);
5299
-  SERIAL_ECHOPGM(" y="); SERIAL_ECHO(delta[Y_AXIS]);
5300
-  SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]);
5301
-  */
5302
-}
5275
+  void calculate_delta(float cartesian[3]) {
5276
+    delta[X_AXIS] = sqrt(delta_diagonal_rod_2
5277
+                         - sq(delta_tower1_x-cartesian[X_AXIS])
5278
+                         - sq(delta_tower1_y-cartesian[Y_AXIS])
5279
+                         ) + cartesian[Z_AXIS];
5280
+    delta[Y_AXIS] = sqrt(delta_diagonal_rod_2
5281
+                         - sq(delta_tower2_x-cartesian[X_AXIS])
5282
+                         - sq(delta_tower2_y-cartesian[Y_AXIS])
5283
+                         ) + cartesian[Z_AXIS];
5284
+    delta[Z_AXIS] = sqrt(delta_diagonal_rod_2
5285
+                         - sq(delta_tower3_x-cartesian[X_AXIS])
5286
+                         - sq(delta_tower3_y-cartesian[Y_AXIS])
5287
+                         ) + cartesian[Z_AXIS];
5288
+    /*
5289
+    SERIAL_ECHOPGM("cartesian x="); SERIAL_ECHO(cartesian[X_AXIS]);
5290
+    SERIAL_ECHOPGM(" y="); SERIAL_ECHO(cartesian[Y_AXIS]);
5291
+    SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(cartesian[Z_AXIS]);
5292
+
5293
+    SERIAL_ECHOPGM("delta x="); SERIAL_ECHO(delta[X_AXIS]);
5294
+    SERIAL_ECHOPGM(" y="); SERIAL_ECHO(delta[Y_AXIS]);
5295
+    SERIAL_ECHOPGM(" z="); SERIAL_ECHOLN(delta[Z_AXIS]);
5296
+    */
5297
+  }
5303
 
5298
 
5304
-#ifdef ENABLE_AUTO_BED_LEVELING
5305
-// Adjust print surface height by linear interpolation over the bed_level array.
5306
-int delta_grid_spacing[2] = { 0, 0 };
5307
-void adjust_delta(float cartesian[3])
5308
-{
5309
-  if (delta_grid_spacing[0] == 0 || delta_grid_spacing[1] == 0)
5310
-    return; // G29 not done
5311
-
5312
-  int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2;
5313
-  float grid_x = max(0.001-half, min(half-0.001, cartesian[X_AXIS] / delta_grid_spacing[0]));
5314
-  float grid_y = max(0.001-half, min(half-0.001, cartesian[Y_AXIS] / delta_grid_spacing[1]));
5315
-  int floor_x = floor(grid_x);
5316
-  int floor_y = floor(grid_y);
5317
-  float ratio_x = grid_x - floor_x;
5318
-  float ratio_y = grid_y - floor_y;
5319
-  float z1 = bed_level[floor_x+half][floor_y+half];
5320
-  float z2 = bed_level[floor_x+half][floor_y+half+1];
5321
-  float z3 = bed_level[floor_x+half+1][floor_y+half];
5322
-  float z4 = bed_level[floor_x+half+1][floor_y+half+1];
5323
-  float left = (1-ratio_y)*z1 + ratio_y*z2;
5324
-  float right = (1-ratio_y)*z3 + ratio_y*z4;
5325
-  float offset = (1-ratio_x)*left + ratio_x*right;
5326
-
5327
-  delta[X_AXIS] += offset;
5328
-  delta[Y_AXIS] += offset;
5329
-  delta[Z_AXIS] += offset;
5299
+  #ifdef ENABLE_AUTO_BED_LEVELING
5330
 
5300
 
5331
-  /*
5332
-  SERIAL_ECHOPGM("grid_x="); SERIAL_ECHO(grid_x);
5333
-  SERIAL_ECHOPGM(" grid_y="); SERIAL_ECHO(grid_y);
5334
-  SERIAL_ECHOPGM(" floor_x="); SERIAL_ECHO(floor_x);
5335
-  SERIAL_ECHOPGM(" floor_y="); SERIAL_ECHO(floor_y);
5336
-  SERIAL_ECHOPGM(" ratio_x="); SERIAL_ECHO(ratio_x);
5337
-  SERIAL_ECHOPGM(" ratio_y="); SERIAL_ECHO(ratio_y);
5338
-  SERIAL_ECHOPGM(" z1="); SERIAL_ECHO(z1);
5339
-  SERIAL_ECHOPGM(" z2="); SERIAL_ECHO(z2);
5340
-  SERIAL_ECHOPGM(" z3="); SERIAL_ECHO(z3);
5341
-  SERIAL_ECHOPGM(" z4="); SERIAL_ECHO(z4);
5342
-  SERIAL_ECHOPGM(" left="); SERIAL_ECHO(left);
5343
-  SERIAL_ECHOPGM(" right="); SERIAL_ECHO(right);
5344
-  SERIAL_ECHOPGM(" offset="); SERIAL_ECHOLN(offset);
5345
-  */
5346
-}
5347
-#endif //ENABLE_AUTO_BED_LEVELING
5301
+    // Adjust print surface height by linear interpolation over the bed_level array.
5302
+    int delta_grid_spacing[2] = { 0, 0 };
5303
+    void adjust_delta(float cartesian[3]) {
5304
+      if (delta_grid_spacing[0] == 0 || delta_grid_spacing[1] == 0) return; // G29 not done!
5305
+
5306
+      int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2;
5307
+      float h1 = 0.001 - half, h2 = half - 0.001,
5308
+            grid_x = max(h1, min(h2, cartesian[X_AXIS] / delta_grid_spacing[0])),
5309
+            grid_y = max(h1, min(h2, cartesian[Y_AXIS] / delta_grid_spacing[1]));
5310
+      int floor_x = floor(grid_x), floor_y = floor(grid_y);
5311
+      float ratio_x = grid_x - floor_x, ratio_y = grid_y - floor_y,
5312
+            z1 = bed_level[floor_x + half][floor_y + half],
5313
+            z2 = bed_level[floor_x + half][floor_y + half + 1],
5314
+            z3 = bed_level[floor_x + half + 1][floor_y + half],
5315
+            z4 = bed_level[floor_x + half + 1][floor_y + half + 1],
5316
+            left = (1 - ratio_y) * z1 + ratio_y * z2,
5317
+            right = (1 - ratio_y) * z3 + ratio_y * z4,
5318
+            offset = (1 - ratio_x) * left + ratio_x * right;
5319
+
5320
+      delta[X_AXIS] += offset;
5321
+      delta[Y_AXIS] += offset;
5322
+      delta[Z_AXIS] += offset;
5323
+
5324
+      /*
5325
+      SERIAL_ECHOPGM("grid_x="); SERIAL_ECHO(grid_x);
5326
+      SERIAL_ECHOPGM(" grid_y="); SERIAL_ECHO(grid_y);
5327
+      SERIAL_ECHOPGM(" floor_x="); SERIAL_ECHO(floor_x);
5328
+      SERIAL_ECHOPGM(" floor_y="); SERIAL_ECHO(floor_y);
5329
+      SERIAL_ECHOPGM(" ratio_x="); SERIAL_ECHO(ratio_x);
5330
+      SERIAL_ECHOPGM(" ratio_y="); SERIAL_ECHO(ratio_y);
5331
+      SERIAL_ECHOPGM(" z1="); SERIAL_ECHO(z1);
5332
+      SERIAL_ECHOPGM(" z2="); SERIAL_ECHO(z2);
5333
+      SERIAL_ECHOPGM(" z3="); SERIAL_ECHO(z3);
5334
+      SERIAL_ECHOPGM(" z4="); SERIAL_ECHO(z4);
5335
+      SERIAL_ECHOPGM(" left="); SERIAL_ECHO(left);
5336
+      SERIAL_ECHOPGM(" right="); SERIAL_ECHO(right);
5337
+      SERIAL_ECHOPGM(" offset="); SERIAL_ECHOLN(offset);
5338
+      */
5339
+    }
5340
+  #endif // ENABLE_AUTO_BED_LEVELING
5348
 
5341
 
5349
-void prepare_move_raw()
5350
-{
5351
-  previous_millis_cmd = millis();
5352
-  calculate_delta(destination);
5353
-  plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
5354
-                   destination[E_AXIS], feedrate*feedmultiply/60/100.0,
5355
-                   active_extruder);
5356
-  for(int8_t i=0; i < NUM_AXIS; i++) {
5357
-    current_position[i] = destination[i];
5342
+  void prepare_move_raw() {
5343
+    previous_millis_cmd = millis();
5344
+    calculate_delta(destination);
5345
+    plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
5346
+    for (int i = 0; i < NUM_AXIS; i++) current_position[i] = destination[i];
5358
   }
5347
   }
5359
-}
5360
-#endif //DELTA
5348
+
5349
+#endif // DELTA
5361
 
5350
 
5362
 #if defined(MESH_BED_LEVELING)
5351
 #if defined(MESH_BED_LEVELING)
5363
-#if !defined(MIN)
5364
-#define MIN(_v1, _v2) (((_v1) < (_v2)) ? (_v1) : (_v2))
5365
-#endif  // ! MIN
5352
+
5353
+  #if !defined(MIN)
5354
+    #define MIN(_v1, _v2) (((_v1) < (_v2)) ? (_v1) : (_v2))
5355
+  #endif  // ! MIN
5356
+
5366
 // This function is used to split lines on mesh borders so each segment is only part of one mesh area
5357
 // This function is used to split lines on mesh borders so each segment is only part of one mesh area
5367
 void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_rate, const uint8_t &extruder, uint8_t x_splits=0xff, uint8_t y_splits=0xff)
5358
 void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_rate, const uint8_t &extruder, uint8_t x_splits=0xff, uint8_t y_splits=0xff)
5368
 {
5359
 {
5434
 }
5425
 }
5435
 #endif  // MESH_BED_LEVELING
5426
 #endif  // MESH_BED_LEVELING
5436
 
5427
 
5437
-void prepare_move()
5438
-{
5428
+void prepare_move() {
5439
   clamp_to_software_endstops(destination);
5429
   clamp_to_software_endstops(destination);
5440
   previous_millis_cmd = millis();
5430
   previous_millis_cmd = millis();
5441
   
5431
   
5549
   }
5539
   }
5550
 #endif //DUAL_X_CARRIAGE
5540
 #endif //DUAL_X_CARRIAGE
5551
 
5541
 
5552
-#if ! (defined DELTA || defined SCARA)
5542
+#if !defined(DELTA) && !defined(SCARA)
5553
   // Do not use feedmultiply for E or Z only moves
5543
   // Do not use feedmultiply for E or Z only moves
5554
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
5544
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
5555
     line_to_destination();
5545
     line_to_destination();

Loading…
Cancel
Save