-
Quentin Bolsee authoredQuentin Bolsee authored
TMC2209 Xiao RP2040 stepper
This is a stepper controller based on a xiao RP2040 communicating with a TMC2209 driver. One interesting application is using Stallguard for sensorless homing:
Design
Jake designed this board in EAGLE with the following in mind:
- The TMC2209 has an internal regulator that needs to be bypassed when feeding it only 5V. A resistor of 10R must be added for this.
- TX and RX pins are connected with a 10k resistor, with RX going to the PDN_UART pin of the TMC
The following schematic is designed for a SAMD21 Xiao board, the GPIO numbers are slightly different for a RP2040 variant:
Here is the completed board. This early prototype uses 4 layers to have a ground plane, VCC plane and signals in between:
The correct pinout for a RP2040 Xiao is:
Signal | GPIO |
---|---|
DIAG | P07 |
ENN | P06 |
DIR | P27 |
STEP | P28 |
TX | P0 |
RX | P29 |
Note that P29 is not the standard RX pin for Serial1
on the Xiao. This can be changed with Serial1.setRX(29)
in init()
.
Soldering
We soldered the prototypes using stencils + solder paste and reflow, but I had inconsistent communication to the TMC. This might have happened after incorrect settings on the VCC jumpers.
I decided to remove the driver with a hot air gun so I could inspect the solder underneath it:
After aligning a new chip, I manually reflow it with the hot air gun.
The final PCB is mounted on the back of a NEMA17 using long M3 screws. Note the VCC jumpers at the bottom.
Code
The library TMCStepper provides a good interface for reading/writing the registers of the TMC. Here's a code snippet for setting up and reading the Stallguard values:
#include <TMCStepper.h>
#define PIN_DIAG 7 // diagnostic
#define PIN_EN 6 // Enable (inverted)
#define PIN_DIR 27 // direction
#define PIN_STEP 28 // Step
#define PIN_RX 29 // RX
#define PIN_TX 0 // TX
#define SERIAL_PORT Serial1 // Serial1
#define DRIVER_ADDRESS 0b00 // MS1 and MS2 = address
#define STALL_VALUE 50 // [0...255]
#define MICROSTEPS 16
#define R_SENSE 0.1f // 100 mOhm
TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);
void setup() {
SERIAL_PORT.setTX(PIN_TX);
SERIAL_PORT.setRX(PIN_RX);
SERIAL_PORT.begin(115200);
pinMode(PIN_DIAG, INPUT);
pinMode(PIN_EN, OUTPUT);
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
driver.begin();
driver.toff(4);
driver.blank_time(24);
driver.rms_current(250); // in mA
driver.microsteps(MICROSTEPS);
driver.TCOOLTHRS(0xFFFFF); // 20bit max
driver.semin(5);
driver.semax(2);
driver.sedn(0b01);
driver.SGTHRS(STALL_VALUE); // Stallguard < threshold -> DIAG pin goes up
}
void loop() {
// make motor turn, needed for valid Stallguard readings
[...]
// 9-bit Stallguard reading
int value = driver.SG_RESULT();
}