TMCStepper: set up a TMC2209 or TMC2208 over UART
Trinamic’s TMC2208 and TMC2209 are the quiet stepper drivers in most current 3D printers. They step a motor from STEP and DIR pins like an A4988, but they also have a one-wire UART on the PDN_UART pin that sets the motor current, the microstep resolution, stealthChop or spreadCycle, and on the TMC2209 the stall detection. TMCStepper by teemuatlut is the library that speaks that UART, with a named function for every register field.
Built in on Mokxi: #include <TMCStepper.h> and it builds, with nothing to install. Free, and no account needed.
What TMCStepper does
Note what it does not do: TMCStepper never moves the motor. It configures the driver, and you step it yourself with digitalWrite() pulses, AccelStepper or FastAccelStepper. A typical setup() calls begin(), toff() to enable the driver, rms_current() in milliamps, microsteps(), and pwm_autoscale(true) for stealthChop, then test_connection() to confirm the driver answered. R_SENSE must match the board, 0.11 ohms on the common SilentStepStick-style modules.
In Mokxi the TMC2209 and TMC2208 parts turn the motor from STEP, DIR, EN and the MS1 and MS2 pins, but their UART is not modeled. The register writes go out on the wire and change nothing, reads time out so test_connection() returns 2, and the step size comes from the MS pins. The example wires DIR to pin 2, STEP to 3, EN to 7 and the UART to pins 10 and 9, sends the usual setup, then makes 400 steps by hand: a quarter turn at the eighth step the grounded MS pins give.
| Library Manager name | TMCStepper |
|---|---|
| Author | teemuatlut |
| Include | #include <TMCStepper.h> |
| Boards | Arduino Uno, Arduino Nano, Arduino Mega 2560, Arduino Leonardo, SparkFun Pro Micro, Arduino Micro, Arduino Pro Mini 3.3 V, ESP8266 NodeMCU, ESP32 DevKit, ESP32-DevKitC V4, LOLIN32 Lite, Wemos D1 R32, Cheap Yellow Display, TTGO T-Display, ESP32-S3-DevKitC-1, Seeed XIAO ESP32-S3, Arduino Nano ESP32 |
| In the simulator | Runs, with a gap the note below names. |
| Parts it drives | TMC2209 stepper driver, TMC2208 stepper driver, Stepper motor, NEMA 17 |
Install it
It builds on Arduino Uno, Arduino Nano, Arduino Mega 2560, Arduino Leonardo, SparkFun Pro Micro, Arduino Micro, Arduino Pro Mini 3.3 V, ESP8266 NodeMCU, ESP32 DevKit, ESP32-DevKitC V4, LOLIN32 Lite, Wemos D1 R32, Cheap Yellow Display, TTGO T-Display, ESP32-S3-DevKitC-1, Seeed XIAO ESP32-S3, Arduino Nano ESP32.
In Mokxi it is built in: #include <TMCStepper.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "TMCStepper" by teemuatlut from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add TMCStepper to lib_deps in PlatformIO. Mokxi follows the calls of release 0.7.3, so a sketch written here builds there too.
What to know in the simulator: The tmc2208 and tmc2209 parts take STEP, DIR, EN and MS1/MS2, so the motor turns as the sketch steps it, but their UART is not modeled: the datagrams go out and change nothing, reads time out (test_connection() returns 2), and microsteps(), rms_current() and shaft() have no effect; the MS pins set the step. No TMC2130 part answers SPI. TMC2160, TMC5130, TMC5160 and TMC2660 are not here. The boards are the ones with SoftwareSerial, for the two-pin constructor; elsewhere pass a hardware Serial1.
The calls you will use
In the order a sketch meets them.
TMC2209Stepper driver(SW_RX, SW_TX, R_SENSE, DRIVER_ADDRESS)
A TMC2209 on a SoftwareSerial pair, with the sense resistor in ohms and the address 0 to 3 set by MS1 and MS2. A TMC2208 takes no address.
driver.begin()
Opens the UART (115200 baud for SoftwareSerial) and writes the startup registers.
driver.toff(5)
Sets the chopper off time; any value from 1 to 15 enables the driver in software, and 0 disables it.
driver.rms_current(600)
Motor current in milliamps RMS, worked out with R_SENSE. Start near 70 percent of the motor’s rated current.
driver.microsteps(16)
Microsteps per full step, 1 to 256. Over UART this overrides the MS1 and MS2 pins on a real driver.
driver.pwm_autoscale(true)
Lets stealthChop tune its own current regulation. Needed for quiet running.
driver.en_spreadCycle(false)
false keeps the silent stealthChop mode; true switches to spreadCycle, which is louder but holds torque better at speed.
driver.test_connection()
Reads a register back: 0 means the driver answered, 1 or 2 mean no or a bad answer, usually a wiring fault.
uint8_t result = driver.test_connection();
if (result) Serial.println("UART not answering");Example: Configure a TMC2209 and step a NEMA 17
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include <TMCStepper.h>
#define EN_PIN 7 // Enable
#define DIR_PIN 2 // Direction
#define STEP_PIN 3 // Step
#define SW_RX 10 // SoftwareSerial receive pin
#define SW_TX 9 // SoftwareSerial transmit pin
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2
#define R_SENSE 0.11f // SilentStepStick series use 0.11
TMC2209Stepper driver(SW_RX, SW_TX, R_SENSE, DRIVER_ADDRESS);
void setup() {
Serial.begin(115200);
pinMode(EN_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW); // Enable driver in hardware
driver.begin(); // UART: Init SW UART with default 115200 baudrate
driver.toff(5); // Enables driver in software
driver.rms_current(600); // Set motor RMS current
driver.microsteps(16); // Set microsteps to 1/16th
driver.pwm_autoscale(true); // Needed for stealthChop
Serial.print("test_connection: ");
Serial.println(driver.test_connection());
// 400 steps, a quarter turn at the 1/8 step MS1 and MS2 give
for (uint16_t i = 400; i > 0; i--) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(160);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(160);
}
Serial.println("done");
}
void loop() {}Wiring
- Arduino Uno R3 3 to TMC2209 stepper driver STEP
- Arduino Uno R3 2 to TMC2209 stepper driver DIR
- Arduino Uno R3 7 to TMC2209 stepper driver EN
- Arduino Uno R3 9 to TMC2209 stepper driver PDN_UART
- Arduino Uno R3 10 to TMC2209 stepper driver PDN_UART
- Arduino Uno R3 GND to TMC2209 stepper driver MS1
- Arduino Uno R3 GND to TMC2209 stepper driver MS2
- Arduino Uno R3 5V to TMC2209 stepper driver VIO
- Arduino Uno R3 GND to TMC2209 stepper driver GND
- Arduino Uno R3 GND to TMC2209 stepper driver GNDM
- Power VCC to TMC2209 stepper driver VM
- TMC2209 stepper driver M2B to Stepper motor, NEMA 17 A1
- TMC2209 stepper driver M2A to Stepper motor, NEMA 17 A2
- TMC2209 stepper driver M1A to Stepper motor, NEMA 17 B1
- TMC2209 stepper driver M1B to Stepper motor, NEMA 17 B2
Common errors and how to fix them
test_connection() returns 1 or 2 on real hardware
The UART got no answer. TX needs a 1 k resistor to the PDN_UART pin with RX tied straight to it, the driver needs motor power on VM, and the address in the sketch must match MS1 and MS2. In Mokxi it always returns 2, since the UART is not modeled.
The motor does not move although setup ran
TMCStepper only configures the driver. Pull EN low, call toff() with a value above 0, and send STEP pulses yourself or through AccelStepper. Check also that VM has its 12 or 24 V supply.
The motor runs hot or loses steps
rms_current() is too high or too low for the motor, or R_SENSE is wrong for the board. Check the sense resistor value printed on the module and set the current from the motor’s datasheet.
Questions and answers
Do I need TMCStepper to use a TMC2209?
No. With the UART pin left alone, a TMC2209 runs like an A4988 from STEP and DIR, with current set by its potentiometer. The library is for changing settings in code.
Keep going
Try TMCStepper without installing anything
Open the example, change the sketch, and keep your version in a free account.