This article is about the implementation details of Trinamic stepper motor drivers. The goal is to give an intuition for how these drivers operate. This may be useful for those interested in tuning the low-level parameters of the drivers.
Background
Before discussing the drivers it helps to give an overview of the critical components of stepper motors and stepper motor drivers.
Briefly:
-
Each stepper motor has two electrical coils. Each coil is a copper wire wrapped around an iron stator. The stepper motor also has a permanent magnet attached to its rotor. Inducing electrical current flow through a coil will create a magnetic force. The strength of this magnetic force is proportional to the amount of current flowing through the coil. Depending on the direction of current flow through the coil, this magnetic force may either attract or repel the permanent magnet on the rotor. By varying the direction and amount of electrical current in the two coils, it’s possible to manipulate the angle of the rotor.
-
Controlling the electrical current in the two coils can thus be used to maintain a desired position of the rotor. The rotor can also be moved by modifying the current in the coils. With precise control of the coil currents it is possible to implement high level 3d printer actions, such as constant speed velocity and linear acceleration.
-
The primary goal of a stepper motor driver is thus to regulate electrical current in the two motor coils.
-
Unfortunately, common stepper motor drivers are unable to directly control the amount of electrical current flowing through each coil. Indeed, the drivers have only a limited ability to control the current - it can configure the wires of each coil in one of three modes: forward current mode, reverse current mode, and recirculate mode.
-
In “forward current” mode one wire of the coil is connected to the voltage source (often 24V) and the other side is connected to GND. If left in this state then a large amount of current would flow through the coil (this is often referred to as an “electrical short”). However, by putting the coil in this state for only a short period of time (think microseconds) only a limited amount of current will actually flow. The amount of current is dependent on the inductance of the stepper motor and the time that power is applied.
-
The “reverse current” mode is just the opposite of “forward current” mode - the application of voltage and GND is reversed on the two wires of the coil. This also forces current through the coil, but in the opposite direction.
-
Finally, in “recirculate” mode the two ends of the coil wire are connected together and neither side is connected to the power supply or GND. This might seem like an odd configuration, but it is an important mode that utilizes the motor inductance. Electrical inductance is an intrinsic property of the coils - it resists a change in the flow of electrical current. So, if the driver induces a current flow (using “forward current” mode or “reverse current” mode) and then switches the coils to “recirculate” mode then inductance will cause current to continue flowing through the coil. Eventually this recirculating current will fade away as energy is lost to resistance within the coils, but for short time periods (think microseconds) this mechanism is an efficient way to maintain current in a coil.
-
-
The next major part of the stepper motor driver is measuring the electrical current in each coil. This is implemented by placing a small resistor between GND and the coil, and then measuring the voltage change across that resistor. A higher voltage across the resistor would indicate a higher current flowing through the coil and into GND. Using Ohm’s Law one can get an accurate measurement of the electrical current by measuring this voltage. To facilitate these measurements, when the coils are wired in “forward mode” and “reverse mode” they are actually routed to this sense resistor instead of directly to GND. Thus it is possible to measure the current going through the coils when in these two modes. Crucially, stepper motor drivers can not measure the current when in “recirculate mode”.
-
In practice, stepper motor drivers indirectly measure the electrical current in the coil using an analog comparator. That is, instead of using an analog to digital converter (ADC) to measure a precise voltage across the sense resistor, they typically use a digital to analog converter (DAC) to produce a target voltage, and then compare if the sense resistor voltage is greater or less than the target voltage. Thus, the stepper motor drivers internally designate a target electrical current flow and then test if the actual current is below or above that target.
-
To obtain good efficiency, the goal is for the motor coils to be in “recirculate” mode for the majority of the time. This utilizes the inherent inductance of the stepper motor to maintain the desired electrical current. It reduces the amount of heat generated in the stepper motor, stepper motor driver, and power supply.
So to review, the main goal of the stepper motor driver is to regulate the electrical current in the stepper motor coils. It can’t actually directly regulate that current though, and it can’t even measure the current the majority of the time. Quite the challenge.
SpreadCycle
The Trinamic “SpreadCycle” mode regulates electrical current by repeatedly applying four modes: “forward mode”, “recirculate mode”, “reverse mode”, and then “recirculate mode” again. The two coils in the stepper motor are independently regulated (that is, the feedback from one coil does not influence the control of the second coil).
-
In “forward mode” power is applied until the measured current is slightly above the desired current. Once this target level is reached, power is removed and the coils are switched to the next phase (“recirculate mode”). This act of applying power until the driver measures a target current is referred to as a “current chopper”, because it induces current in the coil until the measured current reaches a target at which point the power is abruptly “chopped off”.
-
The driver stays in “recirculate mode” for a fixed period of time. We could call this the “recirculate time”.
-
In “reverse mode” power is applied in the opposite direction until the measured current is slightly below the desired current.
-
The driver then goes back into “recirculate mode” for a fixed period of time (the same “recirculate time” used above).
It may seem strange to be constantly going above and below the desired current. Why not just go directly to the desired current? There are some key reasons for this:
-
If one were to “zoom in” on the actual electrical current passing through the coil, one would indeed see a repeated oscillation above and below the desired current. However, ideally these oscillations are small and occur only during small time periods (think microseconds). If one were to “zoom out” to a larger time period and larger current scale then one should observe an overall average current that does match the desired current. It is this “average current” that is the ultimate goal.
-
The desired current can change as the 3d printer software instructs the driver to move to a new position. If that new position requires a greater desired current then the “forward mode” phase helps rapidly inject that current. If that new position requires a smaller desired current then the “reverse mode” phase can rapidly reduce the current.
-
When the coil is in “recirculate mode” the electrical current can be thought of as “doing its own thing”. Sure, over a long period of time the current will diminish, but the coil is not left in “recirculate mode” for long periods. The motor inductance will prevent dramatic changes in current over these small time periods, but for our purposes it is unknown if the current will stay mostly the same, decrease a little, or even increase a little. It may seem odd that the current could increase on its own, but a moving stepper motor can induce a current in the coil. The longer the recirculate time the more uncertainty there is on the actual coil current. Consistently utilizing both “forward mode” and “reverse mode” helps consistently regulate the coil current regardless of the behavior during recirculate mode.
Tuning SpreadCycle
The primary desired tunable on SpreadCycle is the “chopper frequency”. A secondary desired tunable is the “hysteresis”. The “chopper frequency” is the number of times per second the driver completes one full cycle of the four phases (“forward mode”, “recirculate mode”, “reverse mode”, and “recirculate mode”). The “hysteresis” is the amount of current above and below the actual desired current to target during each “forward mode” and “reverse mode”.
Trinamic recommends that the chopper frequency be between 16000 and 30000 cycles per second. If the frequency is too low then the driver will not be responsive to changing conditions. It’ll be “idling” too much and not actively “regulating current”. If the frequency is too high then the driver will be constantly injecting and removing current pointlessly. This leads to excessive heat in the motor, driver, and power supply with no gain.
The ideal “hysteresis” is just slightly above the worst case drift that is expected when in “recirculate mode”. Recall that when the coil is in recirculate mode that the actual current isn’t known and can vary based on printer activity. Ideally, one could estimate the worst case current drift during normal 3d printer operation and then program a slightly larger value as the “hysteresis”. The reason to program a larger value is a little subtle. Recall that if one were to “zoom out” on the coil current, the goal is for one to see that the average current matches the desired current. If, however, the hysteresis is less than the drift then if one were to “zoom out” one would see an average current dominated by that drift. The driver would no longer be actively regulating current, as the average current would be significantly influenced by the motor and its environment.
Unfortunately it is not possible to directly configure the chopper frequency. It’s the primary desirable tunable, but it can’t be configured directly. The chopper frequency could be calculated as 1 / (forward_time + reverse_time + 2*recirculate_time)
. The recirculate time is fixed, but the amount of time in “forward mode” and “reverse mode” depends on how long it takes for the measured current to reach the target current. That varies depending on the load of the motor at that time and how much the current has drifted while in recirculate mode. Although the chopper frequency can not be directly configured, the goal is to choose parameters so that the chopper frequency stays within a desirable range during normal 3d printing (ideally between 16Khz and 30Khz).
There are several parameters that can be configured directly. Keep in mind that these parameters influence each other and it is often difficult to tune one without having to tune others as well.
-
driver_TOFF
: This configures the recirculate time. This is the primary contributor to the overall “chopper frequency” (recall that it is desirable for the majority of the time to be spent in recirculate mode for good efficiency). -
driver_TBL
: This configures a measurement “blank time”. The motor current flowing through the coil is limited by the motor inductance, but there is also always a small amount of capacitance in the driver itself, in the board holding the driver, and in the wires near it. Immediately after switching the coils from recirculating mode to a powered mode the initial current flowing through the sense resistor will be a result of this capacitance (think nanoseconds). Therefore, the initial sense resistor measurements will not accurately reflect the current flowing through the coils. The blank time sets a period of time to ignore these invalid measurements - the current chopper only activates after this time. Lower blank time settings allow the driver to be a little more response, but a setting too small will result in completely inaccurate measurements. This setting also has an indirect effect on hysteresis - larger values effectively increase the minimum possible hysteresis. For example, if during the blank time the current reliably increases by 0.005 amps then only hysteresis settings over 0.005 amps will have an effect on behavior. -
driver_HEND
: This sets the basic hysteresis value. The hysteresis determines how much the current should increase over the actual desired current during forward mode as well as how much under the desired current during reverse mode. The hysteresis setting also influences the chopper frequency - that is, a higher hysteresis takes more time to obtain and thus results in a lower chopper frequency. The configured “recirculate time” also impacts the desired hysteresis, because a larger recirculating time results in a larger possible current drift which calls for a larger hysteresis. -
driver_HSTRT
: The Trinamic drivers support a dynamically changing hysteresis which this setting configures. It is expected this capability is of little use on 3d printers. At the start of each phase the desired electrical current is offset by an amount based ondriver_HSTRT + driver_HEND
, but if it takes a long time for the power supply to bring about that offset then the driver reduces the target. The ultimate target can go as low as the value specified indriver_HEND
. The idea is to reduce the chance of a low chopper frequency by reducing the chance that the driver spends a long time in forward mode or reverse mode. However, this only avoids a low chopper frequency by sacrificing accurate current regulation.
If planning to tune these parameters, then the next step is to read the Trinamic specifications for the driver. Trinamic also has tuning guides describing their recommended test hardware and testing steps. Note that the low-level settings are dependent on the specific model of tmc driver (eg, tmc2130 vs tmc2240). The parameters also vary based on the clock rate of each driver. Other settings (such as run_current
) also alter the behavior of these settings. Finally, note that the Trinamic specifications refer to “forward mode”, “reverse mode” and “recirculate mode” as “on phase”, “fast decay phase” and “slow decay phase”.
Audible noise when using SpreadCycle
On some printers SpreadCycle mode can be annoyingly loud. Unfortunately, tuning the SpreadCycle parameters is unlikely to improve this.
The Trinamic specifications often have statements like, “a too low frequency might generate audible noise”. However, these statements are misleading because the drivers often create audible noise for reasons other than a too low frequency.
If you are interested in understanding how the SpreadCycle settings impact noise then consider running the following test procedure:
-
Install an audio spectrum analyzer on a smartphone. An example of this is the “Spectroid” app on Android. Configure the app to record the microphone at the highest frequency possible, and configure the app to show a linear frequency display (instead of logarithmic). Start the software and place the smartphone near a motor for testing.
-
Set
microsteps: 256
for the motor in the printer.cfg for testing purposes. Then fully power down the printer so that the stepper drivers are fully reset. Restart the printer and restart the Klipper software. -
Use the DUMP_TMC command to see what microstep position (mscnt) the motor is currently in. Ideally the driver will report “mscnt=0” - this is a good starting point for testing as only one coil will be powered.
-
Use the STEPPER_ENABLE command to turn on and off that motor. Look at the audio spectrum and compare the noise between the on and off state. If the motor is noisy you should be able to observe a clear difference between on and off states in the spectrum analyzer.
-
With the motor enabled use the SET_TMC_FIELD command to purposely misconfigure TOFF by setting it to its highest value (for example
SET_TMC_FIELD STEPPER=stepper_x FIELD=TOFF VALUE=15
). Setting the TOFF field to a high number is the easiest way to introduce a very low chopper frequency. At the highest values (and depending on how good your hearing is) it may be possible to directly hear the chopper frequency - it sounds like a high pitched whistle. Try a few TOFF settings and observe the corresponding changes in the spectrum analyzer. -
Try moving the motor in small increments and use the DUMP_TMC command to check the “mscnt” field. When both coils are powered (and when the TOFF field is very high) it may be possible to observe two high energy bands on the spectrum analyzer - these two bands are the chopper frequencies of the two coils. Try changing TOFF and observe how the bands change.
-
Try altering TOFF, TBL, HEND, and HSTRT settings and look for changes in the spectrum analyzer.
-
Try using the SET_TMC_CURRENT command to alter the CURRENT setting while using a very low chopper frequency. Look for how this setting impacts the magnitude of the chopper frequency in the spectrum analyzer, and look for how the setting impacts other audible frequencies. Altering the CURRENT setting may also change the chopper frequency.
-
Try returning to the default TOFF, TBL, HEND, and HSTRT settings and default CURRENT setting. See if the spectrum analyzer can still directly observe the chopper frequency. Observe the impact of enabling and disabling the motor when at the default settings.
It is common to find that the spectrum analyzer shows a wide spectrum of increased energy across the entire audible range when the driver is enabled. This noise is not directly due to a low chopper frequency.
It is thought that this wide spectrum noise is the result of resonance. That is, each coil’s “current chopper” creates vibrations at a high frequency which interact with the motor, the printer frame, and the other coil’s chopper to induce a wide range of lower frequencies that are audible. Tuning the chopper frequency is unlikely to improve these secondary resonances.
StealthChop
StealthChop is an alternate mode for regulating current on Trinamic drivers. It has the same goals as SpreadCycle and uses the same three fundamental coil settings (forward mode, reverse mode, recirculate mode). However, it has a notably different implementation.
In this mode the driver operates at a fixed frequency. At the start of each cycle the driver determines whether power should be added to each coil in a forward or reverse direction based on the desired microstep position (mscnt). It then guesses how long it would take the power supply to bring about the desired current. The driver then enables the corresponding powered mode for the corresponding amount of time. The driver then switches to recirculate mode for the remaining of the cycle. Simple! Just guess how much power to apply and then apply that power!
The driver can use the sense resistor to measure the current while power is applied, but it does not use that measurement to alter the power. It only uses the measurement to improve future guesses.
In this mode the driver is not a “current chopper”. It is sometimes described as a Pulse Width Modulation (PWM) mode. The “pulse” is the switching from powered to recirculation and the “width” is the guessed time that power is applied for.
There are a few advantages to this mode:
-
The driver operates at fixed frequency that can be directly configured (and often does not need to be configured).
-
During each cycle, current is only added. The driver does not oscillate between adding and removing current within a single cycle.
-
The update cycle of both coils begin at the same time and therefore remains synchronized. This is in contrast to SpreadCycle mode where each coil is independently regulated. The separate high frequency updates in SpreadCycle is more likely to induce secondary frequencies.
Of course, the big disadvantage of StealthChop is that it requires making good guesses. There are fundamental limits to how well the driver can make good guesses.
-
The driver can infer velocity by looking at the timing of past movement commands. However, the driver does not know if that velocity will accelerate or decelerate.
-
The driver does not know what other motors are doing. This can be a particular issue for some kinematics such as corexy. On corexy, for example, the amount of torque a stepper needs to produce can vary depending on the movement of the other stepper attached to that belt.
-
The driver can’t predict other possible situations where additional torque may be needed. For example, the driver doesn’t know where the carriage is located on a rail and can not know if certain positions require additional torque. The driver doesn’t know if the toolhead may be close to the print and thus can not account for situations where the toolhead may have minor nozzle/print contacts.
-
The configured
run_current
is only used as part of the feedback mechanism for refining future guesses. It is possible that a series of bad guessing could utilize more current than configured. This can lead to higher heat in the motor, driver, and power supply.
Bad guesses that are too low will result in poor position tracking. Bad guesses that are too high will result in excess heat. Very bad guesses that are too low can result in a failed print due to the stepper motor losing its position (a “lost” step). Very bad guesses that are too high can result in a failed print if the excess current triggers the driver’s over current protection system.
Given these limitations, SpreadCycle is generally preferred over StealthChop for best positional accuracy and for best performance at high speeds. However, in cases where SpreadCycle is too loud, some prefer the quieter operation of StealthChop.
Tuning StealthChop
There are several settings that can be used to alter this mode.
-
driver_PWM_FREQ
: This specifies the number of cycles per second. It sets the update frequency. -
driver_PWM_AUTOSCALE
: This determines if the driver refines future guesses using electrical current measurements during powered modes. It only makes sense to disable this option if one also tells the driver exactly how long to enable each pulse via thedriver_PWM_OFS
anddriver_PWM_GRAD
options. -
driver_PWM_AUTOGRAD
: This determines if the driver uses current measurements to improve guesses based on the observed velocity. This feature only works ifdriver_PWM_AUTOSCALE
is also enabled. It only make senses to disable this option if one also tells the driver exactly how observed velocity should be utilized via thedriver_PWM_GRAD
option. -
driver_PWM_REG
: This determines how aggressively the driver alters its guesses based on current measurements. This feature only works ifdriver_PWM_AUTOSCALE
is also enabled.
If planning to tune these parameters, then the next step is to read the Trinamic specifications for the driver and look for tuning guides provided by Trinamic. Note that the low-level settings are dependent on the specific model of tmc driver (eg, tmc2130 vs tmc2240). The parameters may also vary based on the clock rate of each driver and other settings (such as run_current
).