TMC2209 with Encoder Feedback: What the Driver Does and What Firmware Must Do

·Grafito Innovations
Block diagram showing TMC2209 driver responsibilities vs firmware/MCU responsibilities in a closed-loop stepper system with MT6701 encoder and ESP32-C3

TMC2209 with Encoder Feedback: What the Driver Does and What Firmware Must Do

Search for "TMC2209 closed loop" and you will find tutorials, forum threads, and product listings that make it sound like the TMC2209 is a closed-loop stepper driver. It is not.

The TMC2209 is a microstepping motor driver. It handles current regulation, chopper control, and smooth step interpolation. It has zero encoder input pins, zero position comparison logic, and zero ability to close a position loop on its own.

Closed-loop control — the ability to measure actual shaft angle and correct for position error — lives entirely in firmware running on an external microcontroller paired with a rotary encoder. The TMC2209 just executes the step pulses it is told to.

This article clarifies exactly what the TMC2209 does, what it does not do, how closed-loop control actually works with this driver, and what a complete firmware stack looks like in practice (using Grafito CANStepper's ESP32-C3 stack as a concrete example).


1. What the TMC2209 Does

The TMC2209 is an excellent stepper driver. It is worth understanding its feature set precisely, because the features that make it a good choice for closed-loop systems are not closed-loop features — they are drive-quality features.

Microstepping up to 1/256

The TMC2209 supports microstepping from full-step down to 1/256 through its internal MicroPlyer™ interpolation. At 1/256 microstepping on a standard 200-step/rev motor, each microstep is ~0.007° — far finer than any encoder you will reasonably pair with it. This smooth step resolution is what enables the firmware PID loop to make fine corrections without audible step quantization.

StealthChop2™

StealthChop2 is Trinamic's voltage-chopper mode for silent operation at low to medium speeds. Instead of hard PWM switching, it modulates coil current with a spread-cycle approach that eliminates the audible whine typical of chopper drivers. In a closed-loop system, this means the motor runs quietly during position-hold corrections — important for lab automation, camera gimbals, and noise-sensitive environments.

StallGuard4™

StallGuard4 measures back-EMF to estimate motor load without an external sensor. It can detect a stall (blocked rotor) and signal it via the DIAG pin. This is sensorless load detection, not position feedback. It cannot tell you where the shaft is — only that the load has exceeded a configurable threshold.

Key distinction: StallGuard4 does not measure position. It detects load change. Many people confuse this with closed-loop position control. It is not.

UART Configuration

The TMC2209 exposes a single-wire UART interface for runtime configuration. You can change:

  • Run / hold current
  • Microstep resolution
  • StealthChop vs. SpreadCycle mode
  • StallGuard threshold
  • TOFF, hysteresis, and other chopper parameters

This is critical for closed-loop firmware: the MCU can reconfigure driver parameters on the fly without resetting the motor or power-cycling. For example, dropping IHOLD when the PID error is near zero reduces motor heating during position hold.

Current Regulation

The TMC2209 is, at its core, a constant-current chopper driver. Its job is to regulate the current through the two motor coils so that each microstep produces the correct magnetic field vector. It does this with fast decay control and adaptive blanking time. This regulation loop runs entirely inside the driver IC — at the coil level, not the position level.


2. What the TMC2209 Does NOT Do

This section is the entire reason this article exists. The TMC2209 has none of the following:

CapabilityPresent in TMC2209?What would be needed
Encoder input (ABI, SSI, SPI, I²C)❌ NoDedicated encoder interface pins
Position comparison (commanded vs actual)❌ NoA register comparing setpoint to encoder angle
Closed-loop position correction❌ NoPID or other control law in silicon
PID controller❌ NoOn-chip control loop logic
Trajectory planning (accel/decel ramps)❌ NoVelocity profile generator
Step pulse generation❌ No (consumes, not generates)Timer-based pulse train output
Multi-axis coordination❌ NoCross-axis synchronization

The TMC2209 is a step/direction consumer. It receives STEP pulses and a DIR signal, and it energizes the motor coils to advance the rotor by one microstep per pulse. That is its entire function.

Everything else — reading the encoder, comparing actual angle to target, running a PID loop, computing velocity profiles, and generating the STEP/DIR pulse train — is the firmware's job.


3. How Closed-Loop Actually Works with TMC2209

Here is the real control flow in a closed-loop stepper system built around a TMC2209:

Encoder (MT6701) ──SSI──▶ ESP32-C3 ──PID loop──▶ STEP/DIR pulses ──▶ TMC2209 ──▶ NEMA 17 Motor
                              ▲                                                    │
                              │                                                    │
                              └─────────────── feedback path ──────────────────────┘
                                   (encoder angle is the feedback signal)

Step-by-step, at 200 Hz

  1. Encoder read: Firmware reads the MT6701 magnetic encoder over SSI (Serial Synchronous Interface) at ~200 Hz. The MT6701 provides 14-bit raw angle (~0.022° resolution).

  2. Position comparison: Firmware subtracts the current encoder angle from the commanded setpoint to compute the position error.

  3. PID computation: A PID controller (proportional + integral + derivative) converts the position error into a step-rate command. The proportional term handles immediate error, the integral term eliminates steady-state offset, and the derivative term damps overshoot.

  4. Trajectory limiting: Before sending steps, the firmware clamps the commanded velocity to acceleration/deceleration limits defined by the trapezoidal planner. This prevents step-rate jumps that would cause the motor to stall.

  5. Step pulse generation: Firmware configures a hardware timer to generate STEP pulses at the computed rate, with the DIR pin set accordingly. The TMC2209 receives these pulses and energizes the coils.

  6. Loop repeats: At the next 200 Hz tick, the encoder is read again, and the loop corrects any remaining error.

The TMC2209 never sees the encoder data. It never knows the actual shaft position. It never knows there is an error. It blindly executes whatever STEP/DIR pulses arrive on its input pins.


4. Real Firmware Stack: CANStepper (ESP32-C3)

To make this concrete, here is the actual firmware architecture running on Grafito's CANStepper — a production closed-loop NEMA 17 adapter that pairs a TMC2209 with an MT6701 encoder:

LayerTechnologyRole
MCUESP32-C3 (RISC-V, 160 MHz)Hosts all control logic
RTOSFreeRTOSTask scheduling: PID loop, CAN comms, UART config
Encoder interfaceSSI (bit-banged GPIO)Reads MT6701 at 200 Hz
PID controllerC implementation, 200 Hz tickPosition → step-rate conversion
Trajectory plannerTrapezoidal velocity profileAcceleration / cruise / deceleration phases
Step generatorESP32 RMT (Remote Control Transceiver)Hardware-precise STEP/DIR pulse train
Driver interfaceTMC2209 UART (single-wire)Runtime current, microstep, mode changes
Host protocolGCSP v1 over CAN BusPosition commands, status, telemetry at up to 1 Mbps
Multi-axisCAN daisy-chain (up to 31 nodes)One CAN pair for the whole machine

Why FreeRTOS matters

The PID loop runs as a high-priority FreeRTOS task at a fixed 200 Hz tick. CAN message handling runs in a separate task. UART configuration runs on demand. This separation ensures the control loop is never starved by communication overhead.

Why 200 Hz?

200 Hz (5 ms loop period) is a sweet spot for stepper closed-loop control:

  • Fast enough to catch missed steps before they accumulate into mechanical error
  • Slow enough to run comfortably on a 160 MHz RISC-V core alongside FreeRTOS and CAN
  • The MT6701 encoder updates at up to 55 kHz — the bottleneck is the control computation, not the sensor

5. Why This Distinction Matters

People search for "TMC2209 closed loop" expecting to find a driver that does closed-loop control. They buy a TMC2209 breakout board, wire it to a stepper, and discover... nothing. No encoder port. No position feedback. No closed-loop.

The confusion has real consequences:

  • Wasted hardware purchases: Buying TMC2209 boards expecting plug-and-play closed-loop
  • Incomplete designs: Assuming the driver handles position error, skipping the encoder and firmware entirely
  • Misleading product marketing: Some vendors list "TMC2209 closed-loop stepper driver kit" when the kit is really TMC2209 + separate MCU + encoder — the driver itself is unchanged

The correct framing is: "TMC2209-based closed-loop system" or "closed-loop stepper with TMC2209 driver" — never "TMC2209 closed-loop driver."


6. Other Approaches: What Truly Does On-Chip Closed-Loop?

If you want a single IC that actually closes the position loop in hardware, Trinamic makes one: the TMC4361A.

TMC4361A — Trinamic's Closed-Loop Motion Controller

FeatureTMC2209TMC4361A
PurposeStepper driver (coil current)Motion controller + closed-loop
Encoder input❌ None✅ ABN, SSI, SPI, BiSS, EnDat
PID position loop❌ No✅ On-chip, configurable gains
Trajectory planner❌ No✅ S-curve and trapezoidal
STEP/DIR output❌ (consumes)✅ (generates for external driver)
InterfaceUART (config only)SPI + STEP/DIR output
Pair withExternal MCU for closed-loopExternal driver (TMC2130, TMC5160, etc.)

The TMC4361A reads an encoder, runs a PID loop, generates STEP/DIR pulses, and outputs them to a separate driver IC. It is the closest thing to a "closed-loop stepper driver on a chip" — but it still needs an external motor driver.

External MCU Approach (CANStepper, MKS SERVO42C, etc.)

The alternative — and the architecture most hobbyist and prosumer closed-loop boards use — is a general-purpose MCU running firmware that:

  1. Reads the encoder
  2. Runs the control loop
  3. Drives the TMC2209 over STEP/DIR

This is cheaper, more flexible, and allows features like CAN networking, WiFi configuration, and custom protocols — things a fixed-function motion IC cannot do.

ApproachCostFlexibilityMulti-axisDevelopment effort
TMC4361A + driverHigherLow (fixed function)SPI per axisLow (configure registers)
ESP32 + TMC2209 + encoderLowerHigh (custom firmware)CAN daisy-chainMedium–high (write firmware)
Ready board (CANStepper)MediumMedium (configured)CAN daisy-chainLow (Python host library)

7. Real-World Performance

What can you expect from a TMC2209 + MT6701 + well-tuned firmware stack? Here are measured numbers from the CANStepper platform running firmware v1.2+ on a standard 1.2 A NEMA 17 at 24 V:

MetricValue
Encoder resolution14-bit (~0.022°)
PID loop rate200 Hz
Settling error (static)≤ 0.1°
Closed-loop position cruise800 RPM
Open-loop continuous spin1,200 RPM
Acceleration (trapezoidal)Configurable, tested at 5,000–50,000 steps/s²
Step loss recoveryAutomatic — PID integral term compensates within 2–3 loop cycles

Why 800 RPM closed-loop vs 1,200 RPM open-loop?

The 400 RPM gap is the PID loop overhead. At high speeds, the 200 Hz loop rate means fewer correction opportunities per revolution. The firmware is still tracking position, but above ~800 RPM the control bandwidth starts to limit correction authority. This is a firmware constraint, not a TMC2209 constraint — the driver itself can handle much higher step rates.


8. Practical Recommendations

If you are building a closed-loop system around a TMC2209:

  1. Choose an encoder with enough resolution. 12-bit (0.088°) is workable; 14-bit (0.022°) is ideal. The MT6701 (14-bit, SSI) and AS5600 (12-bit, I²C) are common choices.

  2. Match the control loop rate to your MCU. 100–200 Hz is practical on ESP32-class hardware. Faster MCUs (STM32F4, Teensy 4) can push 500–1000 Hz for higher-speed closed-loop.

  3. Use the TMC2209's UART interface. Dynamically adjusting run current during position hold (drop to ~40% when error is near zero) cuts motor heating dramatically.

  4. Disable StealthChop at high speeds. Above ~300 RPM, switch to SpreadCycle for better torque. The UART interface lets you flip modes mid-motion.

  5. Plan your trajectory. Don't command instantaneous velocity jumps — the TMC2209 will try to execute them, and the motor will stall. Use a trapezoidal or S-curve velocity profile.

  6. Consider a ready-made board. The CANStepper adapter board packages TMC2209 + MT6701 + ESP32-C3 + CAN transceiver in a NEMA 17 mountable format with pre-tuned firmware and a Python host library — skip the driver/encoder/MCU integration work.


Bottom Line

The TMC2209 is a microstepping driver with excellent current control, silent operation, and UART configurability. It has no encoder input, no position comparison, and no closed-loop control logic. It is a step executor, not a motion controller.

Closed-loop stepper control with a TMC2209 requires:

  • A rotary encoder (magnetic or optical) mounted on the motor shaft
  • An MCU (ESP32, STM32, etc.) running firmware that reads the encoder, computes position error, runs a PID loop, and generates STEP/DIR pulses
  • Proper trajectory planning and loop-rate tuning

The TMC2209 makes an excellent driver for closed-loop systems — but it is never the thing closing the loop. That distinction matters for system design, debugging, and for anyone searching "TMC2209 closed loop" expecting the driver to do the heavy lifting.


Related reading:


Published by Grafito Innovations. We build closed-loop stepper hardware and firmware — including the CANStepper adapter board — so we live at the intersection of driver ICs, encoder feedback, and real-time control firmware. This distinction between "what the silicon does" and "what the firmware does" is something we debug daily.