Trinamic steppers Homing Phase (#17299)
This commit is contained in:
		| @@ -2272,9 +2272,9 @@ | |||||||
|   #define CHOPPER_TIMING CHOPPER_DEFAULT_12V |   #define CHOPPER_TIMING CHOPPER_DEFAULT_12V | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Monitor Trinamic drivers for error conditions, |    * Monitor Trinamic drivers | ||||||
|    * like overtemperature and short to ground. |    * for error conditions like overtemperature and short to ground. | ||||||
|    * In the case of overtemperature Marlin can decrease the driver current until error condition clears. |    * To manage over-temp Marlin can decrease the driver current until the error condition clears. | ||||||
|    * Other detected conditions can be used to stop the current print. |    * Other detected conditions can be used to stop the current print. | ||||||
|    * Relevant g-codes: |    * Relevant g-codes: | ||||||
|    * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. |    * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. | ||||||
| @@ -2351,6 +2351,18 @@ | |||||||
|     //#define IMPROVE_HOMING_RELIABILITY |     //#define IMPROVE_HOMING_RELIABILITY | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * TMC Homing stepper phase. | ||||||
|  |    * | ||||||
|  |    * Improve homing repeatability by homing to stepper coil's nearest absolute | ||||||
|  |    * phase position. Trinamic drivers use a stepper phase table with 1024 values | ||||||
|  |    * spanning 4 full steps with 256 positions each (ergo, 1024 positions). | ||||||
|  |    * Full step positions (128, 384, 640, 896) have the highest holding torque. | ||||||
|  |    *   | ||||||
|  |    * Values from 0..1023, -1 to disable homing phase for that axis. | ||||||
|  |    */ | ||||||
|  |    //#define TMC_HOME_PHASE { 896, 896, 896 } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Beta feature! |    * Beta feature! | ||||||
|    * Create a 50/50 square wave step pulse optimal for stepper drivers. |    * Create a 50/50 square wave step pulse optimal for stepper drivers. | ||||||
|   | |||||||
| @@ -105,6 +105,7 @@ class TMCMarlin : public TMC, public TMCStorage<AXIS_LETTER, DRIVER_ID> { | |||||||
|       this->val_mA = mA; |       this->val_mA = mA; | ||||||
|       TMC::rms_current(mA, mult); |       TMC::rms_current(mA, mult); | ||||||
|     } |     } | ||||||
|  |     inline uint16_t get_microstep_counter() { return TMC::MSCNT(); } | ||||||
|   |   | ||||||
|     #if HAS_STEALTHCHOP |     #if HAS_STEALTHCHOP | ||||||
|       inline void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); } |       inline void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); } | ||||||
| @@ -170,6 +171,7 @@ class TMCMarlin<TMC2208Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220 | |||||||
|       this->val_mA = mA; |       this->val_mA = mA; | ||||||
|       TMC2208Stepper::rms_current(mA, mult); |       TMC2208Stepper::rms_current(mA, mult); | ||||||
|     } |     } | ||||||
|  |     inline uint16_t get_microstep_counter() { return TMC2208Stepper::MSCNT(); } | ||||||
|  |  | ||||||
|     #if HAS_STEALTHCHOP |     #if HAS_STEALTHCHOP | ||||||
|       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } |       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } | ||||||
| @@ -216,6 +218,7 @@ class TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC220 | |||||||
|       this->val_mA = mA; |       this->val_mA = mA; | ||||||
|       TMC2209Stepper::rms_current(mA, mult); |       TMC2209Stepper::rms_current(mA, mult); | ||||||
|     } |     } | ||||||
|  |     inline uint16_t get_microstep_counter() { return TMC2209Stepper::MSCNT(); } | ||||||
|  |  | ||||||
|     #if HAS_STEALTHCHOP |     #if HAS_STEALTHCHOP | ||||||
|       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } |       inline void refresh_stepping_mode() { en_spreadCycle(!this->stored.stealthChop_enabled); } | ||||||
| @@ -273,6 +276,7 @@ class TMCMarlin<TMC2660Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> : public TMC266 | |||||||
|       this->val_mA = mA; |       this->val_mA = mA; | ||||||
|       TMC2660Stepper::rms_current(mA); |       TMC2660Stepper::rms_current(mA); | ||||||
|     } |     } | ||||||
|  |     inline uint16_t get_microstep_counter() { return TMC2660Stepper::mstep(); } | ||||||
|  |  | ||||||
|     #if USE_SENSORLESS |     #if USE_SENSORLESS | ||||||
|       inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); } |       inline int16_t homing_threshold() { return TMC2660Stepper::sgt(); } | ||||||
|   | |||||||
| @@ -1483,6 +1483,80 @@ void set_axis_not_trusted(const AxisEnum axis) { | |||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Move the axis back to its home_phase if set and driver is capable (TMC) | ||||||
|  |  * | ||||||
|  |  * Improves homing repeatability by homing to stepper coil's nearest absolute | ||||||
|  |  * phase position. Trinamic drivers use a stepper phase table with 1024 values | ||||||
|  |  * spanning 4 full steps with 256 positions each (ergo, 1024 positions). | ||||||
|  |  */ | ||||||
|  | void backout_to_tmc_homing_phase(const AxisEnum axis) { | ||||||
|  |   #ifdef TMC_HOME_PHASE | ||||||
|  |     const abc_long_t home_phase = TMC_HOME_PHASE; | ||||||
|  |  | ||||||
|  |     // check if home phase is disabled for this axis. | ||||||
|  |     if (home_phase[axis] < 0) return; | ||||||
|  |  | ||||||
|  |     int16_t axisMicrostepSize; | ||||||
|  |     int16_t phaseCurrent; | ||||||
|  |     bool invertDir; | ||||||
|  |  | ||||||
|  |     switch (axis) { | ||||||
|  |       #ifdef X_MICROSTEPS | ||||||
|  |         case X_AXIS: | ||||||
|  |           axisMicrostepSize = 256 / (X_MICROSTEPS); | ||||||
|  |           phaseCurrent = stepperX.get_microstep_counter(); | ||||||
|  |           invertDir = INVERT_X_DIR; | ||||||
|  |           break; | ||||||
|  |       #endif | ||||||
|  |       #ifdef Y_MICROSTEPS | ||||||
|  |         case Y_AXIS: | ||||||
|  |           axisMicrostepSize = 256 / (Y_MICROSTEPS); | ||||||
|  |           phaseCurrent = stepperY.get_microstep_counter(); | ||||||
|  |           invertDir = INVERT_Y_DIR; | ||||||
|  |           break; | ||||||
|  |       #endif | ||||||
|  |       #ifdef Z_MICROSTEPS | ||||||
|  |         case Z_AXIS: | ||||||
|  |           axisMicrostepSize = 256 / (Z_MICROSTEPS); | ||||||
|  |           phaseCurrent = stepperZ.get_microstep_counter(); | ||||||
|  |           invertDir = INVERT_Z_DIR; | ||||||
|  |           break; | ||||||
|  |       #endif | ||||||
|  |       default: return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Depending on invert dir measure the distance to nearest home phase. | ||||||
|  |     int16_t phaseDelta = (invertDir ? -1 : 1) * (home_phase[axis] - phaseCurrent); | ||||||
|  |  | ||||||
|  |     // Check if home distance within endstop assumed repeatability noise of .05mm and warn. | ||||||
|  |     if (ABS(phaseDelta) * planner.steps_to_mm[axis] / axisMicrostepSize < 0.05f) | ||||||
|  |       DEBUG_ECHOLNPAIR("Selected home phase ", home_phase[axis], | ||||||
|  |                        " too close to endstop trigger phase ", phaseCurrent, | ||||||
|  |                        ". Pick a different phase for ", axis_codes[axis]); | ||||||
|  |  | ||||||
|  |     // Skip to next if target position is behind current. So it only moves away from endstop. | ||||||
|  |     if (phaseDelta < 0) phaseDelta += 1024; | ||||||
|  |  | ||||||
|  |     // Get the integer µsteps to target. Unreachable phase? Consistently stop at the µstep before / after based on invertDir. | ||||||
|  |     const float mmDelta = -(int16_t(phaseDelta / axisMicrostepSize) * planner.steps_to_mm[axis] * (Z_HOME_DIR)); | ||||||
|  |  | ||||||
|  |     // optional debug messages. | ||||||
|  |     if (DEBUGGING(LEVELING)) { | ||||||
|  |       DEBUG_ECHOLNPAIR( | ||||||
|  |         "Endstop ", axis_codes[axis], " hit at Phase:", phaseCurrent, | ||||||
|  |         " Delta:", phaseDelta, " Distance:", mmDelta | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (mmDelta != 0) { | ||||||
|  |       // retrace by the amount computed in mmDelta. | ||||||
|  |       do_homing_move(axis, mmDelta, get_homing_bump_feedrate(axis)); | ||||||
|  |     } | ||||||
|  |   #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Home an individual "raw axis" to its endstop. |  * Home an individual "raw axis" to its endstop. | ||||||
|  * This applies to XYZ on Cartesian and Core robots, and |  * This applies to XYZ on Cartesian and Core robots, and | ||||||
| @@ -1742,6 +1816,9 @@ void homeaxis(const AxisEnum axis) { | |||||||
|     } |     } | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|  |   // move back to homing phase if configured and capable | ||||||
|  |   backout_to_tmc_homing_phase(axis); | ||||||
|  |  | ||||||
|   #if IS_SCARA |   #if IS_SCARA | ||||||
|  |  | ||||||
|     set_axis_is_at_home(axis); |     set_axis_is_at_home(axis); | ||||||
| @@ -1753,10 +1830,13 @@ void homeaxis(const AxisEnum axis) { | |||||||
|     // so here it re-homes each tower in turn. |     // so here it re-homes each tower in turn. | ||||||
|     // Delta homing treats the axes as normal linear axes. |     // Delta homing treats the axes as normal linear axes. | ||||||
|  |  | ||||||
|     // retrace by the amount specified in delta_endstop_adj + additional dist in order to have minimum steps |     const float adjDistance = delta_endstop_adj[axis], | ||||||
|     if (delta_endstop_adj[axis] * Z_HOME_DIR <= 0) { |                 minDistance = (MIN_STEPS_PER_SEGMENT) * planner.steps_to_mm[axis]; | ||||||
|       if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj:"); |  | ||||||
|       do_homing_move(axis, delta_endstop_adj[axis] - (MIN_STEPS_PER_SEGMENT + 1) * planner.steps_to_mm[axis] * Z_HOME_DIR); |     // Retrace by the amount specified in delta_endstop_adj if more than min steps. | ||||||
|  |     if (adjDistance * (Z_HOME_DIR) < 0 && ABS(adjDistance) > minDistance) { // away from endstop, more than min distance | ||||||
|  |       if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("adjDistance:", adjDistance); | ||||||
|  |       do_homing_move(axis, adjDistance, get_homing_bump_feedrate(axis)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   #else // CARTESIAN / CORE |   #else // CARTESIAN / CORE | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user