Aziz Bench

3D printer: calibrating steps/mm and setting stepper driver Vref

Two numbers decide whether a 3D printer moves the right distance with the right force: the steps per millimetre of each axis and the current of each stepper driver. Both can be worked out from the parts, not guessed. This guide shows how, for Marlin and Klipper, with a worked example and real parts.

By AzizPublished 16 min read

Checked on 6 November 2026 against the Klipper and Marlin documentation, the Trinamic (Analog Devices) TMC2209, TI DRV8825 and Pololu driver pages, and the makers’ pages of every part named. The numbers come from our steps per mm and Vref calculators.

Steps per millimetre from first principles

A stepper motor turns a fixed angle per full step: 1.8° on almost every printer motor, so 200 full steps per turn (0.9° motors have 400). The driver splits each full step into microsteps, usually 16, so the firmware sends 3,200 steps for one turn of the shaft. Divide that by how far one turn moves the axis and you have the steps per millimetre.

steps/mm = full steps per turn × microsteps × gear ratio ÷ travel per turn
belt:      travel per turn = belt pitch × pulley teeth
leadscrew: travel per turn = thread pitch × starts (the lead)
Motor 1.8°200 full steps× 16 microsteps= 3,200 per turntravel per turnGT2 belt, 20 teeth2 mm × 20 = 40 mm80 steps/mmT8 leadscrew2 mm × 4 = 8 mm400 steps/mmBMG gears 50:1722.68 mm per gear turn415 steps/mmMotor 1.8°200 full steps× 16 microsteps= 3,200 per turntravel per turnGT2 belt, 20 teeth2 mm × 20 = 40 mm80 steps/mmT8 leadscrew2 mm × 4 = 8 mm400 steps/mmBMG gears 50:1722.68 mm per gear turn415 steps/mm
The same motor turn, three ways of turning it into millimetres. Klipper asks for the travel per turn itself, as rotation_distance.

Nothing in this chain needs measuring with a ruler: the pitch, the tooth count and the number of starts are part of the parts’ names. That is why the belt and leadscrew axes are calculated, not calibrated, and only the extruder, which grips soft filament with toothed gears, is measured.

Belts, leadscrews and geared extruders

DriveTravel per turnSteps/mm at 1/16 (1.8°)Klipper rotation_distance
GT2 belt, 20-tooth pulley2 mm × 20 = 40 mm8040
GT2 belt, 16-tooth pulley2 mm × 16 = 32 mm10032
T8 leadscrew (Tr8x8, 4 starts)2 mm × 4 = 8 mm4008
Tr8x2 leadscrew (single start)2 mm1,6002
Bondtech BMG, gears 50:1722.679 mm per drive-gear turn41522.679 with gear_ratio: 50:17, or 7.711 without

Belt and leadscrew rows from our steps per mm calculator (16 teeth, T8, BMG); the BMG figure is Bondtech’s.

Count the pulley teeth (the number is often stamped on it) and look at the end of a leadscrew: a T8 shows four separate threads, so its 2 mm pitch becomes an 8 mm lead. A geared extruder is where the advertised ratio misleads: the BMG is sold as 3:1, but its gears are 50:17, 2.94:1, which is why Bondtech gives 415 steps/mm, about 2 % less than a true 3:1 would.

Extruder (example)Maker’s figureWhat to enter
Bondtech BMG (and BMG-type clones)50:17 gearing, 415 steps/mm at 1/16gear_ratio: 50:17 and rotation_distance 22.679, or 415 steps/mm in Marlin
LDO Orbiter v2.5690 steps/mm at 1/16, rotation_distance 4.637, as for the v2.0As given, then calibrate: Rat Rig notes that the v2.5’s values may shift slightly. LDO’s v2.0 sheet gives 0.85 A RMS for its motor
FYSETC Sherpa Mini (rev. 1.5)6.25:1 reduction, 870 steps/mm870 steps/mm in Marlin, then calibrate

Starting points from Bondtech’s BMG page, Rat Rig’s Orbiter v2.5 page, LDO’s Orbiter v2.0 firmware sheet and FYSETC’s Sherpa Mini page. Clones of these designs usually copy the ratio, not always the gear diameter: calibrate anyway.

Enter your belt, pulley, screw or gear ratio: the calculator gives the steps/mm, rotation_distance, the step rate at your top speed and the lines for Marlin and Klipper.Open the steps per mm calculator

Marlin and Klipper: where the numbers go

Marlin stores steps per unit. M92 X80 Y80 Z400 E415 sets them, M92 alone shows the current values (M503 on older versions), and M500 saves them to EEPROM, if the firmware was built with EEPROM_SETTINGS, as most printer builds are. The values compiled into the firmware are DEFAULT_AXIS_STEPS_PER_UNIT in Configuration.h; M502 brings them back.

Klipper has no steps per mm. Each [stepper_…] section takes rotation_distance (the travel per turn), microsteps, and, when they are not the defaults, full_steps_per_rotation (200; 400 for a 0.9° motor) and gear_ratio. To convert an old Marlin value: rotation_distance = full steps × microsteps ÷ steps/mm, so 200 × 16 ÷ 80 = 40. With gear_ratio: 50:17, rotation_distance is the travel of the last gear, which is why the BMG’s is about 22.68 and not 7.71.

Calibrating the extruder

The extruder gears bite into filament, so the real feed depends on the filament and the tension. Start from the maker’s value, then measure:

  1. Heat the hot end to printing temperature and load filament.
  2. Mark the filament 120 mm above the point where it enters the extruder, and measure the mark precisely with calipers.
  3. Extrude slowly. Marlin: M83, then G1 E100 F100. Klipper’s procedure: G91, then G1 E50 F60 (a mark at about 70 mm is enough for 50 mm). Don’t use the extrude button of a screen or app: it is too fast and the pressure skews the result.
  4. Measure from the extruder entry to the mark again. Extruded = mark before − mark after.
  5. Marlin: new steps/mm = old × requested ÷ extruded. Klipper: new rotation_distance = old × extruded ÷ requested, rounded to three decimals.
  6. Save it, and repeat if the first result was more than about 2 mm off.

Example with a BMG-type extruder at 415 steps/mm: the mark at 120 mm ends at 22.4 mm, so 97.6 mm went in instead of 100. Marlin: 415 × 100 ÷ 97.6 = 425.2 steps/mm, saved with M92 E425.205 and M500. Klipper, with gear_ratio: 50:17: 22.679 × 97.6 ÷ 100 = 22.135. That is more than 2 mm off, so run the test once more with the new value.

Enter your current value and the two mark distances: the calculator gives the new steps/mm and rotation_distance.Calibrate the extruder

Motor current: rated, RMS and peak

The current printed on a stepper motor, 2.0 A for many 48 mm NEMA 17 motors, is the current per phase it is rated for with both phases on, as in full-step mode. With microstepping the two coils carry sine waves, and drivers are set in one of two ways:

  • A4988 and DRV8825 set a current limit: the peak of the sine. Each coil then carries about 71 % of it as RMS.
  • TMC2208, TMC2209 and TMC5160 are set in RMS current: Klipper’s run_current and Marlin’s X_CURRENT are both RMS (Marlin’s comment: “Multiply by 1.414 for peak current”).
peak 1.7 ARMS 1.2 Acoil Acoil Bone electrical cycle = 4 full steps = 64 microstepsA4988, DRV8825: Vref sets the peakTMC: Vref or run_current sets the RMSpeak 1.7 ARMS 1.2 Acoil Acoil Bone electrical cycle= 4 full steps = 64 microstepsA4988, DRV8825: Vref sets the peakTMC: Vref or run_current sets the RMS
The same coil current described two ways. Mixing them up is the most common reason a TMC driver runs a motor hotter than expected.

How much of the rating to use? Watterott, which makes the original SilentStepStick, suggests starting at half the rated current and raising it in 0.1 A steps if the motor skips; the Voron documentation uses 70 % of the rating as RMS, or the driver’s limit if that is lower. Klipper says the same without numbers: as much current as the motor tolerates without getting too hot to touch. For a 2.0 A motor that is a range of 1.0 to 1.4 A RMS.

That current flows even when the motor stands still. In a 1.6 Ω coil, 1.2 A RMS is 2.3 W per phase, about 4.6 W for the two: a motor that holds position all print long is meant to run warm.

Motor (examples)Rated currentHolding torqueResistance, inductanceLength
StepperOnline 17HS19-2004S12.0 A per phase59 N cm1.6 Ω, 3.0 mH48 mm
LDO-42STH48-2004AC2.0 A per phase59 N cm1.6 Ω ±20 %, 3.0 mH ±20 %48 mm
Moons’ MS17HD6P42002.0 A per phase63 N cm1.3 Ω, 2.9 mH48.3 mm

All 1.8°, from StepperOnline’s product page, LDO’s drawing and Moons’ product page. They are examples, not endorsements. On any alternative check the rated current per phase, the inductance (lower keeps more torque at speed on 24 V), the shaft and the coil pairs on the connector.

Vref for A4988, DRV8825 and TMC2209

On a driver set by potentiometer, the current follows from two things only: the reference voltage Vref and the value of the sense resistors next to the chip, marked R068 (0.068 Ω), R100 or R110.

A4988     I limit (peak) = Vref ÷ (8 × Rs)
DRV8825   I limit (peak) = Vref ÷ (5 × Rs)
TMC2208/9 I RMS = (Vref ÷ 2.5 V) × 0.325 V ÷ (Rs + 0.02 Ω) ÷ √2
          (Rs 0.110 Ω: I RMS = Vref ÷ 1.41, and above 2.5 V Vref adds nothing)

For our 2.0 A motor we want about 1.2 A RMS in the coils, 60 % of the rating: a little under the 1.4 A from which the TMC2209 datasheet asks for special care with heat. On each driver that is:

DriverSense resistorsSettingVrefCooling at this current
TMC22090.110 Ω1.2 A RMS (60 %)1.7 VHeat sink and a fan: above about 1 A RMS, says Watterott
A49880.068 Ω (Pololu)1.7 A limit (85 %) ≈ 1.2 A RMS0.92 VHeat sink and airflow: above about 1 A per phase, says Pololu
DRV88250.100 Ω (Pololu)1.7 A limit (85 %) ≈ 1.2 A RMS0.85 VHeat sink and airflow: above about 1.5 A per phase, says Pololu

Values from our Vref calculator; each link opens it with these settings. Note the different percentages: 85 % on an A4988 gives the same coil current as 60 % on a TMC2209.

Going to 70 % on the TMC2209, 1.4 A RMS, needs 1.98 V, and only on a module rated for it: FYSETC says its SilentStepSticks can only be used up to 1.2 A RMS, and the Voron documentation recommends at most 1.4 A for a TMC2209 stepstick, well cooled. With 0.110 Ω resistors a TMC2209 cannot go past 1.77 A RMS however far you turn the trimmer.

Driver (examples)Key specsFor this motor
Pololu A4988 carrier (#1182)0.068 Ω, 8–35 V, up to 1/16; about 1 A per phase without cooling, 2 A withWorks at 0.92 V with a heat sink and airflow; loud, and only 1/16
Pololu DRV8825 carrier (#2133)0.100 Ω, 8.2–45 V, up to 1/32; about 1.5 A per phase without cooling, 2.2 A withWorks at 0.85 V with cooling
BIGTREETECH TMC2209, FYSETC Silent22090.110 Ω; chip rated 2 A RMS, 2.8 A peak; 1.77 A RMS settable; UARTSuits 1.2 A RMS with heat sink and fan; quiet, current in firmware
BIGTREETECH TMC5160T ProSPI only, 0.075 Ω, 3.1 A RMS, 4.4 A peak, 8–56 VRuns this motor at full current with margin; the choice for bigger motors

From the makers’ pages: Pololu, BIGTREETECH (bttwiki), FYSETC. Clones differ: read the sense resistor marking on your own board. A TMC2208 (1.4 A RMS) is better kept to Z and extruder motors.

Pick the driver, read the sense resistors and enter the motor current: the calculator gives Vref, peak and RMS current, and the cooling it needs.Open the Vref calculator

Measuring and setting Vref safely

  1. Switch off and unplug the motor from the driver you are adjusting. FYSETC asks for this explicitly; Pololu notes that the motor doesn’t need to be connected to set the limit.
  2. Power the board from its main supply, not just USB. On USB alone the reading may be wrong, and a DRV8825 or a TMC driver may read nothing at all: a DRV8825 gives its reference only with the motor supply on and SLEEP and RESET high.
  3. Black probe on a GND pin, red probe on the centre of the potentiometer or the board’s Vref test point.
  4. Turn in small steps with a ceramic or plastic screwdriver: a metal tip can short the pot to a neighbouring pin. Which way raises Vref differs between boards, so watch the meter.
  5. Switch off, wait for the board to discharge, connect the motor, and only then switch on again.
  6. Run the axis for a few minutes and touch the motor and driver: warm is fine, too hot to keep a finger on is too much current.

UART and SPI: setting the current in firmware

A TMC2209 on a board wired for UART, such as the onboard drivers of a BIGTREETECH SKR Mini E3 V3.0 or the sockets of a BTT Octopus with the UART jumpers set, takes its current from the firmware. Marlin switches the driver to its internal reference, so the trimmer does nothing; Klipper sets it from the config. A TMC5160 module has no trimmer at all: it is set over SPI.

In Klipper: run_current: 1.2 in the [tmc2209 stepper_x] section (amps RMS), with sense_resistor left at its default 0.110 or set to your module’s value (0.075 for the TMC5160T Pro). Klipper advises against hold_current. In Marlin: X_CURRENT 1200 in Configuration_adv.h (mA RMS) with X_RSENSE 0.11, or at run time M906 X1200 and M500.

Skipped steps, heat, microsteps and modes

SymptomLikely causeWhat to do
Layer shifts at speed, grinding noiseToo little current, too much acceleration or speed, belt too looseRaise current 10 %, lower acceleration, check belt tension and pulley grub screws
Shifts after some minutes of printingDriver overheating and shutting down for a momentLower the current, add a heat sink and a fan on the drivers; Klipper reports TMC overtemperature errors
Motor too hot to touchCurrent too high for the motorLower by 10 to 20 % and check it still doesn’t skip
Extruder clicks, under-extrusionExtruder current too low, or the hot end too cold or cloggedCheck the temperature first, then raise the extruder current a little
Wrong size on every axis by the same factorMicrosteps in the firmware differ from the driver’s pinsMatch microsteps (or Marlin’s X_MICROSTEPS) to the jumpers or UART setting

Klipper’s TMC documentation: the driver switches itself off when too hot, and a motor that is too hot loses torque and accuracy.

  • Microsteps add smoothness, not precision. 16 is the usual choice; TMC drivers interpolate it to 256 internally (interpolate: True is Klipper’s default), which Klipper notes costs about 0.006 mm on a 40 mm rotation_distance axis. For best accuracy Klipper suggests spreadCycle, interpolate: False and 64 or 128 microsteps.
  • StealthChop or SpreadCycle. StealthChop is near-silent; SpreadCycle gives more torque and accuracy and handles speed better. A standalone TMC2209 starts in StealthChop, Klipper defaults to SpreadCycle, and Marlin enables StealthChop on all axes by default. Pick one per axis: Klipper warns that switching mode while moving gives poor results.
  • Cooling. Drivers above about 1 A RMS want a heat sink stuck on firmly and a fan blowing across it. The motor runs warm by design: it carries current even when standing still.

Worked example: the whole printer

A Cartesian printer with 1.8° motors, 2.0 A on X and Y, TMC2209 drivers at 16 microsteps, GT2 belts on 20-tooth pulleys, a T8 leadscrew on Z and a BMG-type extruder. From the sections above: X and Y 80 steps/mm, Z 400, E calibrated to 425.2; 1.2 A RMS on X and Y, which is 1.7 V on the trimmer in standalone mode. The extruder and Z motors get their own current from their own ratings.

Klipper (add the uart_pin and the other pins from your board’s sample config):

[stepper_x]
microsteps: 16
rotation_distance: 40

[tmc2209 stepper_x]
run_current: 1.2
sense_resistor: 0.110

[stepper_z]
microsteps: 16
rotation_distance: 8

[extruder]
microsteps: 16
rotation_distance: 22.135
gear_ratio: 50:17

Marlin, compiled in Configuration.h and Configuration_adv.h, or sent once and saved with M500:

#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 425.205 }
#define X_CURRENT 1200
#define X_RSENSE  0.11

M92 X80 Y80 Z400 E425.205
M906 X1200 Y1200
M500

Common mistakes

  • Calibrating X and Y with a printed cube. Calculate them; calibrate only the extruder.
  • Using the extruder’s advertised ratio. “3:1” is 50:17 on a BMG: put the real gear ratio in, or start from the maker’s steps/mm.
  • Treating a TMC setting as a peak. 2.0 A RMS on a TMC is the full rating of a 2.0 A motor with no margin, and more than a 0.110 Ω module can set (1.77 A).
  • Setting Vref with only USB power. The reading may be wrong, and a DRV8825 or a TMC driver may read nothing: switch the main supply on.
  • Assuming a sense resistor value. Clones of the same driver come with R050, R068, R100 or R110 resistors: read yours.
  • Turning the trimmer on a UART driver. It does nothing; change run_current or X_CURRENT.
  • Mismatched microsteps. Jumpers at 1/32 and firmware at 1/16 halve every move.

Safety

  • Power off before touching the wiring. Connecting a motor, a driver module or a jumper with power on can destroy the driver.
  • Mains supplies. Most printers run from a mains power supply with screw terminals: keep its cover on and the earth connected, and work on the low-voltage side only with the plug out.
  • Heat. A very hot motor can soften the plastic parts mounted on it, as the Klipper documentation warns, and burn fingers. Drivers without cooling shut down or fail: the board’s fan is part of the design.
  • Moving parts. Test new current settings with your hands clear of belts and pulleys, and keep the emergency stop or the power switch within reach.

Frequently asked questions

What are the steps/mm for a GT2 belt with a 20-tooth pulley?

80 with a 1.8° motor at 16 microsteps (rotation_distance 40 in Klipper). A 16-tooth pulley gives 100 (rotation_distance 32), and a T8 leadscrew 400 (rotation_distance 8).

How do I calibrate the extruder steps?

Mark the filament 120 mm above the extruder, extrude 100 mm slowly with the hot end at temperature, and measure what is left. New value = old × 100 ÷ millimetres actually extruded: 415 × 100 ÷ 97.6 = 425.2. In Klipper scale rotation_distance the other way: old × extruded ÷ requested.

What Vref should I set on a TMC2209 for a 2 A motor?

With 0.110 Ω sense resistors, Vref = RMS current × 1.41: 1.7 V for 1.2 A RMS, 1.98 V for 1.4 A on a module rated for it. Above about 1 A RMS the module needs a heat sink and a fan.

Is a motor’s rated current peak or RMS?

It is the current per phase with both phases on. Treat it as the RMS ceiling for a TMC setting and start at 50 to 70 % of it; on an A4988 or DRV8825 the Vref sets the peak, so the same percentage gives about 30 % less current.

Does Vref matter if the TMC2209 runs over UART?

No. Marlin switches the driver to its internal reference and uses X_CURRENT or M906; Klipper uses run_current. The trimmer is ignored.

Should the motor be connected while I measure Vref?

No need: FYSETC says to disconnect it, and Pololu that it doesn’t have to be connected. What matters is never plugging or unplugging it while the driver is powered.

Why does my stepper skip steps?

Too little current, too much acceleration, a loose belt or pulley, or a driver that overheats and cuts out. If it happens only after a while, it is heat: add cooling or lower the current.

StealthChop or SpreadCycle?

StealthChop for quiet printing at moderate speeds, SpreadCycle for torque and accuracy at high speed. Klipper defaults to SpreadCycle; a standalone TMC2209 starts in StealthChop.

Sources

  1. Klipper documentation: Rotation distance
  2. Klipper documentation: TMC drivers
  3. Klipper documentation: configuration reference, [tmc2209]
  4. Marlin documentation: M92, set axis steps per unit
  5. Marlin documentation: M906, stepper motor current
  6. Marlin source: Configuration_adv.h (X_CURRENT, X_RSENSE, StealthChop)
  7. Analog Devices (Trinamic): TMC2209 datasheet, rev. 1.08
  8. Texas Instruments: DRV8825 datasheet, detailed description
  9. Pololu: A4988 stepper motor driver carrier (#1182)
  10. Pololu: DRV8825 stepper motor driver carrier (#2133)
  11. Pololu: setting the current limit on stepper driver carriers
  12. BIGTREETECH: TMC2209 module
  13. BIGTREETECH: TMC5160T Pro V1.0
  14. FYSETC: Silent2209 (Vref, microstepping)
  15. Watterott: SilentStepStick FAQ
  16. Voron documentation: calculating driver current
  17. StepperOnline: 17HS19-2004S1
  18. LDO Motors: LDO-42STH48-2004AC drawing
  19. Moons’: MS17HD6P4200
  20. Bondtech: BMG extruder
  21. Rat Rig: LDO Orbiter v2.5 extruder
  22. LDO: Orbiter v2.0 firmware configuration
  23. FYSETC: Sherpa Mini extruder
  24. BIGTREETECH: SKR Mini E3 V3.0
  25. BIGTREETECH: Octopus