Stall detection and sensorless homing
The TMC2660 drivers used on the Duet WiFi, Duet Ethernet and the TMC5160 drivers used on the Duet 3 support the stallGuardTM feature. This feature allows the driver to detect motor stalls under some circumstances. Stall detection may be useful for detecting when a motor has skipped steps due to the nozzle hitting an obstruction, and for homing the printer without using endstop switches. RepRapFirmware 1.20 and later provides facilities for configuring and using stall detection.
The TMC2224 drivers on the Duet Maestro do not support stall detection.
Limitations of stall detection
- The stall detection threshold has to be tuned to the particular stepper motors you use.
- The stepper drivers only update the stall detection state every 1 or 4 full steps, depending on configuration. So the actual position of the stall is uncertain to either +/- half a full step or +/- 2 full steps. This means that when using stall detection to replace endstop switches, the position defined by the stall is much less accurate than with typical endstop switches.
- Stall detection is not reliable at low motor speeds. It would typically give false stall indications at low speeds. To avoid this, the firmware allows you to set minimum speeds (in motor full steps per second) below which stall indications will be ignored. These values may need to be tuned to suit your requirements. It is easier to get reliable stall detection at higher motor speeds.
- Stall detection is not reliable at motor speeds that are too high for the drivers to be able to supply sufficient voltage to maintain motor current. Therefore if you wish to use stall detection to detect skipped steps during printing, you must limit the motor speed to a value that does not require a higher voltage than your power supply provides (maximum 25V). See Choosing Stepper Motors: How to work out the power supply voltage you need.
- The stall detection threshold varies a little with motor temperature, therefore the motor temperatures must not be allowed to vary widely.
- Stall detection works by detecting an increase in the motor load. You may need to reduce acceleration and/or jerk to avoid false stall detection.
- It is very likely that stall detection works better on low current high inductance motors than on high current low inductance motors, although we have not verified this experimentally. Unfortunately, high inductance motors suffer from torque reduction and increased noise at lower speeds than low inductance motors do, so they are not recommended if you want high speed motion.
Minimum recommended speed for stall detection
A rough figure for the minimum speed in full steps per second (M915 H parameter) for which you should be able to get reliable stall detection is given by this formula:
- Hmin = full_steps_per_rev * rated_current * actual_current/(sqrt(2) * pi * rated_holding_torque)
where full_steps_per_rev is 200 or 400 (for 1.8 or 0.9deg motors), currents are in amps, and holding torque is in Nm. From this it can be seen that stall detection at low speeds is easier at lower motor currents. This is one reason why motor current is often reduced during stall-detect homing,
Configuring stall detection
Stall detection is configured using the M915 command, The parameters are:
- Pnnn:nnn:... Drive number(s) to configure
- X,Y,Z,U,V,W,A,B,C Axes to configure (alternative to using the P parameter)
- Snnn Stall detection threshold (-64 to +63, values below -10 not recommended). Higher values reduce the sensitivity; lower values make false stall detection more likely.
- Fn Stall detection filter mode, 1 = filtered (one reading per 4 full steps), 0 = unfiltered (default, 1 reading per full step)
- Hnnn (optional) Minimum motor full steps per second for stall detection to be considered reliable, default 200 (try 400 for 0.9deg motors)
- Rn Action to take on detecting a stall from any of these drivers: 0 = no action (default), 1 = just report it, 2 = pause print, 3 = pause print, execute /sys/rehome/.g, and resume print
Stall detection sensitivity (S, F and H parameters)
- Using F1 should reduce the likelihood of getting false stall reports, and it also allows stall detection to work at higher speeds. In the worst case (Duet + Duex 5) the stall status of each driver is checked every 100us. So if you use F0, the time between full steps must be at least 100us to guarantee that the stall is detected. With F1 this is reduced to 25us. However, F1 delays stall detection slightly, so you may wish to use F0 when using stall detection for sensorless homing.
- Set the S parameter to the lowest value at which you do not get false stall reports. Typical values for nema 17 motors are between 1 and 3. False stall reports are most likely during fast travel moves, because the acceleration increases the load on the motor. False stall reports are also more likely when the motors are hot.
- If you have difficulty finding a value for S that detects stalls reliably without also giving rise to false stall reports, try the following:
- Increase the minimum full steps/second for stall detection (H parameter) and use corresponding higher movement speeds
- Reduce acceleration (M201) and/or jerk (M566)
- If you are using stall detection for homing, reduce motor current while homing (see the M913 command)
Action to take on detecting a stall (R parameter)
- Use R0 if you are configuring stall detection for sensorless homing only.
- Use R1 when experimenting with the other parameters, so that you can see what effect they have during a print. If logging is enabled, stalls will be logged as well as reported.
- Use R2 when you have tuned stall detection and you want to pause the print automatically when a stall is detected.
- Use R3 when you have tuned stall detection and you want to re-home and continue the print automatically. You must have a rehome.g file in /sys on the SD card, to instruct the printer on how you'd like to rehome. On a Cartesian or CoreXY printer, typically you would enable stall detection on just the X and Y motors, and re-home just the X and Y axes in rehome.g.
Configuring sensorless homing
The motor stall status is updated every 1 or 4 full steps depending on whether you configure filtered or unfiltered stall detection (see earlier). If the physical point at which the axis stalls is "on the edge" between two steps, then this could cause the stall detection point to vary from one homing attempt to another by 1 or 4 full steps.
Once you've had a stall, the stall condition doesn't get cleared until you do a non-stalling move. Therefore, before doing any G1 H1 move that relies on stall detection, you should back off a little, at least 5 full steps if using filtered mode, or at least 2 full steps if using unfiltered mode.
On a Cartesian printer, the exact X and Y homing positions don't matter if you home once before or at the start of the print and then print the whole object. However, if you want to use the facility to save the status of a print prior to power down (either manually or automatically) and resume it after a subsequent power up, you will need to re-home the printer as part of the resume procedure. A difference in homing position of just one full step represents 0.2mm of travel on a typical printer (with 80 steps/mm @ x16 microstepping), which would cause a noticeable layer shift.
On a delta printer, the towers home to the top and a variation of 1 full step in the homing position would cause a significant calibration error. This error can be removed with just one cycle of delta auto calibration. Therefore, if using sensorless homing, you should always auto-calibrate after homing and before printing. For example, if you normally include G28 in your slicer start script, add G32 after the G28. If you want to use the resume-after-power-cycle facility, then in your resurrect-prologue.g file you can home and then probe the bed at 3 or more points at the periphery while keeping the head clear of the print, and use S3 on the final G30 command to adjust the endstop positions only. Or you can just home and hope that the motor stall positions didn't change.
On a CoreXY printer, both of the X and Y motors are active in all XY movements except for diagonal movements. Therefore, when homing either X or Y the firmware monitors both the X and Y motors for stalls. This means that when tuning the stall detection sensitivity and the motor current reduction used when homing, you should always set the same sensitivity and current values for both the X and Y drivers - assuming of course that the X and Y motors are the same type. The increased elasticity of CoreXY systems (caused by the involvement of 2 motors and the long belt lengths) can make it difficult to get a sufficiently hard stall.
- For each motor that you wish to use for sensorless homing, configure motor stall detection thresholds and minimum speeds as previously described.
- In the M574 command for the endstops concerned, use parameter S3 to indicate that you will use the motor stall indication instead of a homing switch.
- When the carriage hits the physical endstop, the belt must not slip on the pulley because that will prevent the motor from stalling. To ensure this, you may need to use the [M913 command] to temporarily reduce the motor current. Reducing the current also makes it easier to detect stalls at low speeds.
- The motor speeds during homing moves (G1 moves with S1 parameter) must be higher than the full steps/second threshold that you set in the stall detection parameters. For example, if you use the default threshold of 200 full steps/sec and at x16 microstepping you have 80 steps/mm , then the minimum homing speed is (200 * 16 / 80) = 40mm/sec = 2400mm/min. So your homing moves must have an F parameter greater than 2400. The standard homing files generated by configtool do a fast homing, then back off by a few mm, then a slow fine homing. You won't be able to do a slow fine homing if you are using sensorless homing.
- If you normally use filtered stall detection mode to detect motor stalls during printing, you may wish to switch to unfiltered mode during homing.
Testing it using a macro file
While tuning the stall detection threshold, you may find it useful to create a macro file to test sensorless homing, without overwriting your standard homing files. Here is the one I used on my delta printer when it was running RepRapFirmware 2:
; Sensorless Homing test file for RepRapFirmware on Kossel M400 ; make sure everything has stopped before we make changes M574 X2 Y2 Z2 S3 ; set endstops to use motor stall M913 X50 Y50 Z50 ; reduce motor current to 50% to prevent belts slipping G91 ; use relative positioning G1 H1 X700 Y700 Z700 F4000 ; move all carriages up 700mm, stopping at the endstops G1 Z-5 F2000 ; down a few mm so that we can centre the head G90 ; back to absolute positioning M400 ; make sure everything has stopped before we reset the motor currents M913 X100 Y100 Z100 ; motor currents back to normal G1 X0 Y0 F2000 ; centre the head and set a reasonable feed rate M574 X2 Y2 Z2 S1 ; set endstops back to normal so that homedelta.g works
If using this for real instead of endstop switches, you would move the first M574 command into config.g and remove the second M574 command.
Using extruder stall detection during filament loading
In firmware 1.20 and later you can use extruder motor stall detection to feed filament into the hot end until resistance is encountered. Here's how.
- Find a motor current that causes the motor to skip steps (not grind the filament) if you try to push filament too fast through the hot end, or when the hot end is cold. Your normal extruder motor current may already be suitable, but you may want to use a lower one.
- Using that motor current, find a stall detection threshold that causes motor stall to be reported when you extrude fast and resistance is encountered, but that is not triggered during normal acceleration at the start of a filament feeding move. It may be helpful to use M122 to look at the SG max value when you send a large extrusion move and resistance is not encountered, and when resistance is encountered and the motor skips steps.
- Configure stall detection on your extruder motor using M915 and the stall detection threshold you found.
- Create a "Load filament" macro file that does the following:
- Preheat the hot end, if desired (or send M302 P1 if you intend to use the macro when the hot end is cold)
- Use M913 Ennn to reduce the motor current, if necessary (see #1 above)
- Use M83 to select relative extruder motion, in case the macro is called when absolute extrusion is in effect
- If on a delta printer, send G91 to select relative movement (bug workaround for firmware 1.21 and earlier, see later)
- In case the motor is already stalled, retract a small amount of filament (e.g. 1mm) to ensure that it is not flagged as stalled.
- Send a G1 H1 Ennn Fnnn command with appropriate E and F parameters. The E parameter should be long enough for the filament to reach the hot end, and the F parameter should be fast enough to activate stall detection (see the H parameter in the M915 command). The H1 parameter means "stop at the endstop" as usual, and for an extruder the endstop is always stall detection.
- Use M913 E100 to restore the extruder motor current to 100%
- If your macro is intended to be used with the hot end hot, do whatever priming you want to do.
Here is an example file:
; Load T0 with PLA G10 P0 S200 R160 ; set temperatures for PLA T0 ; select tool M116 ; wait for temperatures to be reached G1 E-0.3 F300 ; retract a little filament M400 ; wait for move to finish before changing current M915 E0 S3 ; set stall sensitivity M913 E30 ; motor current to 30% M83 ; relative extrusion G1 H1 E800 F6000 ; feed up to 800mm until stall M913 E100 ; restore normal motor current G1 E50 F120 ; extrude 50mm @ 2mm/sec
Known bug in firmware 1.20 and 1.21: if you send a G1 H1 E command on a delta machine and the printer is in absolute XYZ coordinate mode, it will fail with error "G0/G1: attempt to move delta motors to absolute positions". This is fixed in firmware version 2.0 and later. The workaround is to use G91 to set relative motion before doing the G1 H1 E command. Don't forget to use G90 to set it back to absolute afterwards if your macro subsequently does any XYZ movement commands!