Browse Source

Trinamic steppers Homing Phase (#17299)

Fabio Santos 5 years ago
parent
commit
ccfd5c1010
No account linked to committer's email address
3 changed files with 104 additions and 8 deletions
  1. 15
    3
      Marlin/Configuration_adv.h
  2. 5
    1
      Marlin/src/feature/tmc_util.h
  3. 84
    4
      Marlin/src/module/motion.cpp

+ 15
- 3
Marlin/Configuration_adv.h View File

2272
   #define CHOPPER_TIMING CHOPPER_DEFAULT_12V
2272
   #define CHOPPER_TIMING CHOPPER_DEFAULT_12V
2273
 
2273
 
2274
   /**
2274
   /**
2275
-   * Monitor Trinamic drivers for error conditions,
2276
-   * like overtemperature and short to ground.
2277
-   * In the case of overtemperature Marlin can decrease the driver current until error condition clears.
2275
+   * Monitor Trinamic drivers
2276
+   * for error conditions like overtemperature and short to ground.
2277
+   * To manage over-temp Marlin can decrease the driver current until the error condition clears.
2278
    * Other detected conditions can be used to stop the current print.
2278
    * Other detected conditions can be used to stop the current print.
2279
    * Relevant g-codes:
2279
    * Relevant g-codes:
2280
    * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given.
2280
    * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given.
2352
   #endif
2352
   #endif
2353
 
2353
 
2354
   /**
2354
   /**
2355
+   * TMC Homing stepper phase.
2356
+   *
2357
+   * Improve homing repeatability by homing to stepper coil's nearest absolute
2358
+   * phase position. Trinamic drivers use a stepper phase table with 1024 values
2359
+   * spanning 4 full steps with 256 positions each (ergo, 1024 positions).
2360
+   * Full step positions (128, 384, 640, 896) have the highest holding torque.
2361
+   *  
2362
+   * Values from 0..1023, -1 to disable homing phase for that axis.
2363
+   */
2364
+   //#define TMC_HOME_PHASE { 896, 896, 896 }
2365
+
2366
+  /**
2355
    * Beta feature!
2367
    * Beta feature!
2356
    * Create a 50/50 square wave step pulse optimal for stepper drivers.
2368
    * Create a 50/50 square wave step pulse optimal for stepper drivers.
2357
    */
2369
    */

+ 5
- 1
Marlin/src/feature/tmc_util.h View File

105
       this->val_mA = mA;
105
       this->val_mA = mA;
106
       TMC::rms_current(mA, mult);
106
       TMC::rms_current(mA, mult);
107
     }
107
     }
108
-
108
+    inline uint16_t get_microstep_counter() { return TMC::MSCNT(); }
109
+ 
109
     #if HAS_STEALTHCHOP
110
     #if HAS_STEALTHCHOP
110
       inline void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); }
111
       inline void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); }
111
       inline bool get_stealthChop_status() { return this->en_pwm_mode(); }
112
       inline bool get_stealthChop_status() { return this->en_pwm_mode(); }
170
       this->val_mA = mA;
171
       this->val_mA = mA;
171
       TMC2208Stepper::rms_current(mA, mult);
172
       TMC2208Stepper::rms_current(mA, mult);
172
     }
173
     }
174
+    inline uint16_t get_microstep_counter() { return TMC2208Stepper::MSCNT(); }
173
 
175
 
174
     #if HAS_STEALTHCHOP
176
     #if HAS_STEALTHCHOP
175
       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
177
       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
216
       this->val_mA = mA;
218
       this->val_mA = mA;
217
       TMC2209Stepper::rms_current(mA, mult);
219
       TMC2209Stepper::rms_current(mA, mult);
218
     }
220
     }
221
+    inline uint16_t get_microstep_counter() { return TMC2209Stepper::MSCNT(); }
219
 
222
 
220
     #if HAS_STEALTHCHOP
223
     #if HAS_STEALTHCHOP
221
       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
224
       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); }
273
       this->val_mA = mA;
276
       this->val_mA = mA;
274
       TMC2660Stepper::rms_current(mA);
277
       TMC2660Stepper::rms_current(mA);
275
     }
278
     }
279
+    inline uint16_t get_microstep_counter() { return TMC2660Stepper::mstep(); }
276
 
280
 
277
     #if USE_SENSORLESS
281
     #if USE_SENSORLESS
278
       inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); }
282
       inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); }

+ 84
- 4
Marlin/src/module/motion.cpp View File

1484
 }
1484
 }
1485
 
1485
 
1486
 /**
1486
 /**
1487
+ * Move the axis back to its home_phase if set and driver is capable (TMC)
1488
+ *
1489
+ * Improves homing repeatability by homing to stepper coil's nearest absolute
1490
+ * phase position. Trinamic drivers use a stepper phase table with 1024 values
1491
+ * spanning 4 full steps with 256 positions each (ergo, 1024 positions).
1492
+ */
1493
+void backout_to_tmc_homing_phase(const AxisEnum axis) {
1494
+  #ifdef TMC_HOME_PHASE
1495
+    const abc_long_t home_phase = TMC_HOME_PHASE;
1496
+
1497
+    // check if home phase is disabled for this axis.
1498
+    if (home_phase[axis] < 0) return;
1499
+
1500
+    int16_t axisMicrostepSize;
1501
+    int16_t phaseCurrent;
1502
+    bool invertDir;
1503
+
1504
+    switch (axis) {
1505
+      #ifdef X_MICROSTEPS
1506
+        case X_AXIS:
1507
+          axisMicrostepSize = 256 / (X_MICROSTEPS);
1508
+          phaseCurrent = stepperX.get_microstep_counter();
1509
+          invertDir = INVERT_X_DIR;
1510
+          break;
1511
+      #endif
1512
+      #ifdef Y_MICROSTEPS
1513
+        case Y_AXIS:
1514
+          axisMicrostepSize = 256 / (Y_MICROSTEPS);
1515
+          phaseCurrent = stepperY.get_microstep_counter();
1516
+          invertDir = INVERT_Y_DIR;
1517
+          break;
1518
+      #endif
1519
+      #ifdef Z_MICROSTEPS
1520
+        case Z_AXIS:
1521
+          axisMicrostepSize = 256 / (Z_MICROSTEPS);
1522
+          phaseCurrent = stepperZ.get_microstep_counter();
1523
+          invertDir = INVERT_Z_DIR;
1524
+          break;
1525
+      #endif
1526
+      default: return;
1527
+    }
1528
+
1529
+    // Depending on invert dir measure the distance to nearest home phase.
1530
+    int16_t phaseDelta = (invertDir ? -1 : 1) * (home_phase[axis] - phaseCurrent);
1531
+
1532
+    // Check if home distance within endstop assumed repeatability noise of .05mm and warn.
1533
+    if (ABS(phaseDelta) * planner.steps_to_mm[axis] / axisMicrostepSize < 0.05f)
1534
+      DEBUG_ECHOLNPAIR("Selected home phase ", home_phase[axis],
1535
+                       " too close to endstop trigger phase ", phaseCurrent,
1536
+                       ". Pick a different phase for ", axis_codes[axis]);
1537
+
1538
+    // Skip to next if target position is behind current. So it only moves away from endstop.
1539
+    if (phaseDelta < 0) phaseDelta += 1024;
1540
+
1541
+    // Get the integer µsteps to target. Unreachable phase? Consistently stop at the µstep before / after based on invertDir.
1542
+    const float mmDelta = -(int16_t(phaseDelta / axisMicrostepSize) * planner.steps_to_mm[axis] * (Z_HOME_DIR));
1543
+
1544
+    // optional debug messages.
1545
+    if (DEBUGGING(LEVELING)) {
1546
+      DEBUG_ECHOLNPAIR(
1547
+        "Endstop ", axis_codes[axis], " hit at Phase:", phaseCurrent,
1548
+        " Delta:", phaseDelta, " Distance:", mmDelta
1549
+      );
1550
+    }
1551
+
1552
+    if (mmDelta != 0) {
1553
+      // retrace by the amount computed in mmDelta.
1554
+      do_homing_move(axis, mmDelta, get_homing_bump_feedrate(axis));
1555
+    }
1556
+  #endif
1557
+}
1558
+
1559
+
1560
+/**
1487
  * Home an individual "raw axis" to its endstop.
1561
  * Home an individual "raw axis" to its endstop.
1488
  * This applies to XYZ on Cartesian and Core robots, and
1562
  * This applies to XYZ on Cartesian and Core robots, and
1489
  * to the individual ABC steppers on DELTA and SCARA.
1563
  * to the individual ABC steppers on DELTA and SCARA.
1742
     }
1816
     }
1743
   #endif
1817
   #endif
1744
 
1818
 
1819
+  // move back to homing phase if configured and capable
1820
+  backout_to_tmc_homing_phase(axis);
1821
+
1745
   #if IS_SCARA
1822
   #if IS_SCARA
1746
 
1823
 
1747
     set_axis_is_at_home(axis);
1824
     set_axis_is_at_home(axis);
1753
     // so here it re-homes each tower in turn.
1830
     // so here it re-homes each tower in turn.
1754
     // Delta homing treats the axes as normal linear axes.
1831
     // Delta homing treats the axes as normal linear axes.
1755
 
1832
 
1756
-    // retrace by the amount specified in delta_endstop_adj + additional dist in order to have minimum steps
1757
-    if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0) {
1758
-      if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj:");
1759
-      do_homing_move(axis, delta_endstop_adj[axis] - (MIN_STEPS_PER_SEGMENT + 1) * planner.steps_to_mm[axis] * Z_HOME_DIR);
1833
+    const float adjDistance = delta_endstop_adj[axis],
1834
+                minDistance = (MIN_STEPS_PER_SEGMENT) * planner.steps_to_mm[axis];
1835
+
1836
+    // Retrace by the amount specified in delta_endstop_adj if more than min steps.
1837
+    if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance
1838
+      if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("adjDistance:", adjDistance);
1839
+      do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis));
1760
     }
1840
     }
1761
 
1841
 
1762
   #else // CARTESIAN / CORE
1842
   #else // CARTESIAN / CORE

Loading…
Cancel
Save