Motion and units¶
How the TMC5160's internal ramp generator moves the motor, and how the driver converts degrees, millimetres and RPM into register values.
The ramp generator¶
With SD_MODE low the chip generates the step pulses itself. You write a target and a speed profile; it accelerates, cruises and decelerates on its own, and the host only polls for completion. All motion parameters can be changed while the motor runs.
| Ramp mode | RampMode |
Behaviour |
|---|---|---|
| Positioning | POSITIONING |
Moves to XTARGET with the full six-segment profile and stops there. Initialize() selects it |
| Velocity, positive / negative | VELOCITY_POS, VELOCITY_NEG |
Accelerates with AMAX to VMAX and keeps running |
| Hold | HOLD |
Keeps the current velocity unless a stop event occurs |
In positioning mode the chip uses a SixPoint ramp:
| Segment | From → to | Rate | Driver call |
|---|---|---|---|
| Start | 0 → VSTART |
jump | SetRampSpeeds() |
| First acceleration | VSTART → V1 |
A1 |
SetFirstAcceleration() |
| Main acceleration | V1 → VMAX |
AMAX |
SetAcceleration(), SetAccelerations() |
| Main deceleration | VMAX → V1 |
DMAX |
SetDeceleration(), SetAccelerations() |
| Final deceleration | V1 → VSTOP |
D1 |
SetFinalDeceleration() |
| Stop | VSTOP → 0 |
jump | SetRampSpeeds() |
With V1 = 0 the ramp is a plain trapezoid using AMAX and DMAX. D1 must not be 0 in positioning mode, even
when V1 is 0, and VSTOP must be at least VSTART.
driver.rampControl.SetRampSpeeds(0.05f, 0.1f, 1.0f, Unit::RevPerSec); // VSTART, VSTOP, V1
driver.rampControl.SetFirstAcceleration(8.0f, Unit::RevPerSec); // A1: VSTART .. V1
driver.rampControl.SetAccelerations(4.0f, 4.0f, Unit::RevPerSec); // AMAX, DMAX: V1 .. VMAX
driver.rampControl.SetFinalDeceleration(8.0f, Unit::RevPerSec); // D1: V1 .. VSTOP (never 0)
driver.rampControl.SetMaxSpeed(3.0f, Unit::RevPerSec); // VMAX
After a stop the chip waits TZEROWAIT before reversing (SetZeroWaitTimeMs()), and after TPOWERDOWN at
standstill it lowers the current from IRUN to IHOLD (SetPowerDownDelayMs()).
Units¶
Every position, speed and acceleration call takes a Unit:
Unit |
Position | Speed | Acceleration |
|---|---|---|---|
Steps |
full steps | full steps/s | full steps/s² |
Deg, Rad |
of the output shaft | per second | per second² |
RevPerSec |
n/a | rev/s (the recommended default) | rev/s² |
RPM |
n/a | rev/min | n/a |
Mm |
linear, needs a lead screw or belt | mm/s | mm/s² |
The register values are microsteps: one full step is 2MRES microsteps (256 by default). The driver converts with the formulas of the datasheet (section 12.1):
| Quantity | Register to physical |
|---|---|
| Velocity | v[µsteps/s] = VMAX × fCLK / 224 |
| Acceleration | a[µsteps/s²] = AMAX × fCLK² / (512 × 256) / 224 |
| Revolutions | v[rev/s] = v[µsteps/s] / microsteps per full step / full steps per rev |
At the internal 12 MHz clock, 1 rev/s of a 200-step motor at 256 microsteps is 51 200 µsteps/s, a VMAX of
about 71 600. The conversions use DriverConfig::external_clk_config.frequency_hz (0 means the internal
12 MHz), motor_spec.steps_per_rev and the current microstep resolution, so a change of MRES keeps the physical
speed. The internal oscillator is accurate to about ± 4 %; feed an external clock where speed accuracy matters.
Mechanical systems¶
DriverConfig::mechanical turns motor revolutions into output motion.
MechanicalSystemType |
Fields | Effect |
|---|---|---|
DirectDrive |
none | Degrees and revolutions are the motor shaft |
Gearbox |
gear_ratio (output / input) |
Degrees and revolutions are the output shaft |
LeadScrew |
lead_screw_pitch_mm |
Unit::Mm: one revolution = pitch |
BeltDrive |
belt_pulley_teeth, belt_pitch_mm |
Unit::Mm: one revolution = teeth × pitch |
// With cfg.mechanical = LeadScrew, 8 mm pitch, given to Initialize():
driver.rampControl.SetMaxSpeed(40.0f, Unit::Mm); // mm/s: 5 rev/s
driver.rampControl.MoveRelative(12.5f, Unit::Mm); // 1.5625 rev
const float where_mm = driver.rampControl.GetCurrentPosition(Unit::Mm).ValueOr(0.0f);
std::printf("at %.2f mm\n", where_mm);
Millimetres need a mechanical system
With DirectDrive or Gearbox, or a zero pitch, millimetres cannot be converted: the calls that take a
Unit (targets, speeds, accelerations, X_COMPARE, homing) return INVALID_VALUE and write nothing.
IsUnitConvertible(Unit::Mm) tells you in advance. Configure mechanical before you use millimetres.
Position readback¶
GetCurrentPosition() reads XACTUAL; GetTargetPosition() reads XTARGET. SetCurrentPosition() redefines
where you are without moving (for homing), and can update the encoder count with it. The raw microstep values
are available from GetCurrentPositionMicrosteps() and GetTargetPositionMicrosteps().
Next: Current and chopper.