I am new to using stepper motors and micropython. I am having trouble getting my stepper motor to turn. I am using a raspberry pi pico and a tmc 2208 driver to control my stepper motor. I can hear the coils being powered on and off, but I get no motion.

Here is a a wiring diagram enter image description here

Here is my script

from machine import Pin
import utime

direction = Pin(14, Pin.OUT)
step = Pin(15, Pin.OUT)
enable = Pin(13, Pin.OUT)



def stepOne():

while True:
  • 2
    how much time is utime.sleep(0.001)?
    – jsotola
    Dec 27 '21 at 0:23
  • 1
    Nice picture but it does not help me much. A schematic showing all connections including power, power source, etc would help a lot. Post a link to the hardware items that has technical information. I will guess and it sounds like you are short on power, voltage and or current. This can be confirmed with more information.
    – Gil
    Dec 27 '21 at 1:32
  • (1) First thing first, the TMC2208datasheet: trinamic.com/fileadmin/assets/Products/ICs_Documents/…
    – tlfong01
    Dec 27 '21 at 4:42
  • (2) Next, a quick and dirty summary: 2-phase stepper, 32 uSteps, 36VDC, internal current sensing, hard/soft(uart) config, ...
    – tlfong01
    Dec 27 '21 at 4:50
  • 1
    Need a clear photo showing the connections.
    – joan
    Dec 27 '21 at 10:15

Short Answer

(1) How to check if the driver is damaged?

The driver does not work or stopped working. What should I do? On problems, check at first the wiring and power supply (voltages and protection against voltage spikes on power up).

If this is okay, check the resistance (when the driver is not connected) of the logic supply VIO against GND, the digital pins EN, DIR, STEP against GND + VIO and the motor pins M1A, M1B, M2A, M2B against GND + VM.

When the resistance of the logic supply or a digital input is very low (<10k Ohm), then in general there is a problem with the power-up or power-down sequence.

Or if the resistance of a motor pin is very low (<100k Ohm) then there could be a problem with the motor wiring (loose connection) or the motor power supply was removed during operation (moving).

Because of induction voltages from the back electromotive force (EMF) the motor output drivers can get defective, when the motor power supply or the motor is removed during operation.

Reference: SilentStepStick FAQ - Watterott

(2) Why the driver IC gets damaged if not properly shut off?

What to consider when turning the power supply on or off?

If the motor is running/moving, then it is not allowed to switch off the power supply.

Always make sure that the motor stands still and the motor outputs are deativated on shutting down, otherwise the driver IC can get damaged (because of back EMF).

An emergency stop can be realized, when the EN pin is set to VIO (high). This will switch off all motor output drivers and will put the motor into freewheeling.

Long TLDR Answer

(1) First thing first, the TMC2208datasheet: trinamic.com/fileadmin/assets/Products/ICs_Documents/… – tlfong01

(2) Next, a quick and dirty summary: 2-phase stepper, 32 uSteps, 36VDC, internal current sensing, hard/soft(uart) config, ... –

(3) Get a couple of assembled modules: pt.aliexpress.com/item/… –

(4) I am too lazy to upload pics in Imrur and link them here. So I cheat by using my answer space.

(5) Skim the module user guide.




(6) Show the Pico + TMC2208 Wiring/Schematic.


(7) Compare and contrast the wiring with a similar and already debugged project, say the very popular A4899, to make sure no important wiring is missing.

A4899 Microstepping Motor Driver Troubleshooting - EESE Q&A 2021apr14

(8) Manual testing, using (a) Manaul jumper wiring, (b) manual configurable PWM sig gen.

A4899 Stepping Motor Driver Test


/ to continue, ...

(9) Software testing, using Pico.

For software testing and evaluation, I would recommend the updated version TMC2209, with uart interface.

(Ref 21) TMC2209 stepper Motor Driver Module - TaoBao ¥18


(10) TMC2209 Programming Notes


The OP's original program

Now I am looking at the OP's program, thinking that perhaps I can repeat running his program in my Pico.

from machine import Pin
import utime

direction = Pin(14, Pin.OUT)
step = Pin(15, Pin.OUT)
enable = Pin(13, Pin.OUT)



def stepOne():

while True:

My program v0.1

I am adding comments to make my version 1.

# *** TMC2209 Test Program v0.1  tlfong01  2022jan02hkt1126 ***

# *** Import ***
from machine import Pin
import utime

direction = Pin(14, Pin.OUT)
step = Pin(15, Pin.OUT)
enable = Pin(13, Pin.OUT)



def stepOne():

while True:

/ to continue, ...


(11) A4988 Datasheet - Allergo

(12) A4988 Stepper Motor Driver Module - AliExpress US$0.6

(13) Fake microstepping in A4899 and LV8729 stepper-drivers? - @GnuReligion, EESE, Asked 2021apr14

(14) What could be the reasons for a stepper motor stuttering with an A4988 driver? [Locked] EESE, Asked 2021apr05

(15) What is better for precision? Stepper motor VS DC Motor [Closed] - EESE 2021apr13

(16) AliExpress HK42BYG250-001 Stepper Motor NEMA17 | High torque 1.2A 38mm stepper motor for 3D printer 42 with speed feedback

(17) Youtube video of A4988 Full Step Performance - tlfong01 2021apr18

(18) RpiMotorLib python library to drive NEMA 17 stepper for A4988 - DiyProjects 2021feb09

(21) TMC2209 stepper Motor Driver Module - TaoBao ¥18

(22) TMC2209 Stepper Motor Driver Module User Guide - Components101

(23) TMC2209 Stepper Motor Driver Datasheet - Trinamic

(24) Pico PWM Primer - TK Hareendran, codrey 2021sep21

(25) TMC2209 v1.2 Manual - BigTreeTech


Appendix A - Pico PWM as a clock to TMC2208/2209 Stepper Motor Driver

(Ref 24) Pico PWM Primer - TK Hareendran, codrey 2021sep21

pico pwm 1

pico pwm 2

TMC2209 PWM Pin Assignment

Pico p26/G20 ~ p35/Aref 
pin assignment v0.1 
tlfong01  2021dec29hkt1526
ylw G20  p26 PWM[A2]
grn G21  p27 PWM[B2]
blk Gnd  p28 Gnd 
org Run  p29 Run
org G22  p30 PWM[A3]
ylw G26  p31 PWM[A5]
grn G27  p32 PWM[B5]
gry Agnd p33 AGnd
blu G28  p34 PWM[A6]
brn Aref p35 Aref

pico pwm 3

TMC2209 Setup Notes Part 1

tmc2209 setup 1

tmc2209 pot

tmc2209 routing

Using XY-LPWM3 sig gen to do manual (offline, no Pico yet) TMC2209 testing

(Ref) XY-LPWM3 PWM Module Test & Review! Pulse Width Modulation Generator, Cheap & Powerfull 1,093 viewsMar 4, 2021

xy-lpwm3 wiring

Bipolar Stepper Motor Driver for refreshing memory

(Ref) Bipolar Stepper Motors: What is it? (Circuit And Sequence) - Electrical4U 2020dec27

(Ref) How does a Stepper Motor work? - 3,752,110 views Oct 19, 2016, 57k like, Lesics, 4.97M subscribers

Bipolar stepper motor

Reading summary

(1) The DC current in a winding needs to be reversed to reverse a magnetic pole and allow the motor to function. Typically a H-bridge arrangement is used. The most common H Bridge IC used in most Bipolar stepper interfacing projects is L293D.

(2) A bipolar stepper motor has one winding per stator phase. A two phase bipolar stepper motor will have 4 leads.

(3) There are three different ways in which we can drive the bipolar stepper motor:

(a) Only one of the phase winding is energized at a time. That is, either AB or CD is energized.

(b) Both the phases are activated at the same time. The rotor will align itself between two poles. This arrangement will give higher holding torque than the previous method.

(c) Half stepping, used generally to improve the stepping angle. Here,

step 1, only 1 phase is ON, then in 

step 2, 2 phases are ON, 

then again, only one phase is ON, 

and the sequence continues.

TMC2209 Stepper Motor Driver Driving NEMA17 Motor Notes

Now I am using the following NEMA17 42BYG 3D printer stepper motor (Ref 1)to do the testing.

Ref 1: HK42BYG250-001 NEMA17 Stepper Motor, High torque 1.2A 38mm for 3D printer with speed feedback - AliExpress

Ref 2: A4899 Microstepping Driver Testing - 2021apr14

stepper motor

Testing TMC2209 with HK42BYG250-001 NEMA17 Stepper Motor OK

Youtube Video of HK42BYG250-001 NEMA17 Stepper Motor Testing Results

tmc2203 test

Schematic of TMC2209 Testing: Step 1 - Offline/No Pico, Step 2 On Line/with Pico

tmc2209 schematic

Step 1 - Offline/No Pico testing setup

offline testing

Step 2 - Online/Pico Micropython Software Testing

So the time has come to start Pico MicroPython Programming. The first step is to assign Pico GP pins for controlling the TMC2209 Step motor controller.

We will need to use

(1) Pico uart0 to talk to the TMC2209 Tx, Rx,

(2) 6 GP pins (GP 20, 21, 22, 26, 27, 28) to talk to TMC2209 and the Motor rotary encoder. (Note - This is temporary pin assignment. Later we will use IO expanders such a MCP23x17 to create more GPIO pins (for multiple motor controllers etc, to avoid runing out of Pcio GP pins sooner or later)

tmc2209 pico pins

TMC2209 Test Program V0.8 - Blink Control Pins

Now I have written a little microPython program to blink all the TMC2209 Control Pins.

# *** tmc2209test08.py tlfong01 2022jan02hkt2116 ***
programName = 'tmc2209test07.py'

Note: program snipped because forum limit of 30k words reached - tlfong01 2022jan08.

Testing Pico PWM 1 kHz 50% dutyCycle perofrmance

I replace the XY-LPWM3 1kHz control signal by the Pico PWM signal and found that the motor turns slightly jerking. I also found that motor turns fro PWM signal range in 500Hz to kKHz. Too low frequency motor jerks, too high frequency, eg, at 10kHz, motor trembles and does not move.

pico pwm test

Testing TMC2209 Control Pins OK

I have debugged the functions to set High/Low the TMC2209 control pins.

# *** tmc2209test12.py tlfong01 2022jan04hkt2138 ***
programName = 'tmc2209test12.py'

# ========= ========= ========= ========= ========= ========= ========= ========= 
# Contents
# 1. System Config
# 2. Import Modules
# 3. System Utility Functions/Constants
# 4. Pico
#    4.1 Pico GPConfig (GPIO, PWM, UART)
#    4.2 Pico GP Functions
# 5. TMC2209
#    5.1 TMC2209 Config
#    5.2 TMC2209 Functions

# ========= ========= ========= ========= ========= ========= ========= ========= 
# 1. System Config
#   Thonny 3.3.13, Windows 10 (64-bit),  Python 3.7.9, Tk 8.6.9, MicropPython
#     (Raspberry Pi Pico), USB Port (COM3)

# ========= ========= ========= ========= ========= ========= ========= =========  
# 2. Import Modules 
from machine import Pin, PWM, UART
import utime

# ========= ========= ========= ========= ========= ========= ========= =========
# 3. System Functions/Constants

# Repeat Times
oneTime         =  1
twice           =  2
fourTimes       =  4
tenTimes        = 10
tenMillionTimes = 10000000

# Seconds Constants
halfMilliSecond = 0.0005
oneMilliSecond  = 0.001
oneTenthSecond  = 0.1
quarterSecond   = 0.25
halfSecond      = 0.5
oneSecond       = 1

# Calander Time
monthNameDict = \
    {'Month' : {'1': 'Jan', '11': 'nov', '12': 'dec',},

timeNow = utime.localtime()
timeNowShort = str(timeNow[0]) + monthNameDict['Month'][str(timeNow[1])] + str(timeNow[2]) + 'hkt' + str(timeNow[3]) + ':' + str(timeNow[4])

def printProgramNameTimeNow():
    print('Program Name =', programName, 'Time Now =', timeNowShort)

# Time Functions ***
def pause(pauseTime):

# ========= ========= ========= ========= ========= ========= ========= ========= 
# 3. Pico

# *** Pico Config ***

# *** Pico GP Output Pin Assignment ***

gpOutPin20 = Pin(20, Pin.OUT)
gpOutPin21 = Pin(21, Pin.OUT)
gpOutPin22 = Pin(22, Pin.OUT)
gpOutPin26 = Pin(26, Pin.OUT)
gpOutPin27 = Pin(27, Pin.OUT)

# *** Pico GP PWM Pin Assignment ***

#gpPwmPin28 = PWM(Pin(28))
#gpPwmPin28.freq(1000) # 10kHz jerking, 1~5kHz slight jerking
#gpPwmPin28.duty_u16(int(65535/2)) #dutyCycle 50%
gpOutPin28 = Pin(28, Pin.OUT)

# *** Pico UART Config ***

uart0 = UART(0, baudrate = 9600, tx=Pin(0), rx=Pin(1))

# ========= ========= ========= ========= ========= ========= ========= ========= 
# *** Pico GP Out/PWM Pin Functions ***

def setGpOutPinHigh(gpOutPin):

def setGpOutPinLow(gpOutPin):

def toggleGpOutPin(gpOutPin, highSeconds, lowSeconds, toggleCount):
    for count in range(toggleCount):
        #print('  count =', count)

def toggleGpOutPinList(gpOutPinList, highSeconds, lowSeconds, toggleCount):
    for gpOutPin in gpOutPinList:
        toggleGpOutPin(gpOutPin, highSeconds, lowSeconds, toggleCount)        

def testToggleGpOutPinV01(gpOutPin):
    #print('Begin testToggleGpOutPin(), ...')
    toggleGpOutPin(gpOutPin20, oneSecond, oneSecond, tenTimes)
    #print('End   testToggleGpOutPin().')

def testToggleGpOutPinV02(gpOutPin):
    #print('Begin testToggleGpOutPin(), ...')
    toggleGpOutPin(gpOutPin21, oneMilliSecond, oneMilliSecond, tenMillionTimes)
    #toggleGpOutPin(gpOutPin21, halfSecond, halfSecond, tenMillionTimes)    
    #print('End   testToggleGpOutPin().')

def testToggleGpOutPinV03(gpOutPin):
    print('Begin testToggleGpOutPin(), ...')
    toggleGpOutPin(gpOutPin20, halfSecond, halfSecond, tenMillionTimes)
    print('End   testToggleGpOutPin().')

def testToggleGpOutPinList(gpOutPinList):
    print('    Begin testToggleGpOutPinList(), ...')
    toggleGpOutPinList(gpOutPinList, quarterSecond, quarterSecond, twice)
    print('    End   testToggleGpOutPinList().')

# *** Sample Test ***
#testToggleGpOutPinList([gpOutPin20, gpOutPin21, gpOutPin26])

# ========= ========= ========= ========= ========= ========= ========= ========= 
# 4. TMC2209 Config/Functions 

tmc2209EnblPin = gpOutPin20
tmc2209DirPin  = gpOutPin21
tmc2209StepPin = gpOutPin22
tmc2209Ms1Pin  = gpOutPin26
tmc2209Ms2Pin  = gpOutPin27

#tmc2209PwmPin  = gpPwmPin28

def testBlinkTmc2209ControlPins():
    print('  Begin testBlinkTmx2209ControlPins(), ...')
    testToggleGpOutPinList([tmc2209EnblPin, tmc2209DirPin, tmc2209StepPin, tmc2209Ms1Pin, tmc2209Ms2Pin])
    print('  End   testBlinkTmx2209ControlPins(), ...')    

# ========= ========= ========= ========= ========= ========= ========= =========
# *** Old Main Test Programs ***
#testToggleGpOutPinList([gpOutPin20, gpOutPin21, gpOutPin26])
#testToggleGpOutPinList([tmc2209EnblPin, tmc2209DirPin, tmc2209StepPin, tmc2209Ms1Pin, tmc2209Ms2Pin])

# ========= ========= ========= ========= ========= ========= ========= =========
# *** Main ***

# *** End ***

Sample Output
Program Name = tmc2209test11.py Time Now = 2022Jan4hkt21:42

  Begin testBlinkTmx2209ControlPins(), ...
    Begin testToggleGpOutPinList(), ...
    End   testToggleGpOutPinList().
  End   testBlinkTmx2209ControlPins(), ...

Next step is to write functions to control the motor start, stop, step, direction, clock, microstep setting etc. The last step is to use UART to control the TMC2209 driver. I searched the SO/SE forums and found useful references, but sadly on Arduino based libraries. So I need to write/DIY Pico MicroPython TMC2209 library on my own.

I found the following references useful:

(1) TMC2208 Stepper driver replacement with A4988 Trouble (Using software UART) - SO, Asked 7 months ago Active 6 months ago Viewed 230 times

(2) TMC2209 Arduino communication with TMC2209 (Using software UART) - SO, Asked 8 months ago Active 8 months ago Viewed 1k times

(3) How do I wire a TMC2130 stepper motor driver to an Arduino UNO in order to control it? Asked 3 years, 5 months ago Active 1 year, 4 months ago Viewed 11k times

(4) How to drive a stepper motor closed loop with Arduino using a TMC4361A-Eval + TMC2130 - TrinamicBlog 2017Sep28

(5) Upgrading RAMPS 1.4 With TMC2130 Stepper Drivers - Core3D in Workshop3D Printing, 71,591 views

(6) TMC2209 stepper motor module datasheet - GitHub

(7) TMC2209 stepper-motor-driver-for-3d-printer-board module Product sheet - BiQu

(8) TMC2209 Stepper Motor Driver ICdatasheet - Trinamic

(9) AccelStepper library for Arduino - AirSpayce

(10) Generate stepper-motor speed profiles in real time - David Austin

Shortening my TLDR Answer

My answer is getting TLDR and editing it s very this TLDR answer very slow. So I am thinking of using GitHub, GitFile or Penzu to speed up my answer editing job. Stay tuned,. :)

tmc2209test14.py complete program listing with sample output

tmc2209test14.py sample run YouTube video

tmc2209 video

Now I can move motor fast or slow, CCW or CW, any numbers of steps, with this function:

def testTmc2209V02():
    print('Begin testTmc2209V02(), ...')
    initTmc2209V02() # init motor  
    tmcStartMotor(enblPin) # start motor
    tmcSendStepsPause(stepPin, oneMilliSecond,  oneThousandTimes, halfSecond) # move CCW fast, 1000 steps, pause half second
    tmcSendStepsPause(stepPin, oneMilliSecond,  fiveHundredTimes, halfSecond) # move CCW fast,  500 steps, pause half second
    tmcSendStepsPause(stepPin, oneMilliSecond,  oneThousandTimes, halfSecond) # move CCW fast, 1000 steps, pause half second
    tmcCwMotor(dirPin)                                                        # change direction to CW  
    tmcSendStepsPause(stepPin, twoMilliSeconds, oneThousandTimes, halfSecond) # move CW  slow, 1000 steps, pause half second
    tmcOneSixteenthStep(ms1Pin, ms2Pin)                                       # change to 1/16 microstep
    tmcSendStepsPause(stepPin, twoMilliSeconds, oneThousandTimes, halfSecond) # move CW  slow, half step, 1000 steps, pause half second   
    print('End   testTmc2209TestV02().')

tmc2209test19 - The complete program listing

The YouTube Video

tmc2209 test video

Configuring and Testing TMC2209 using UART interface

Now that I found it OK to use the couple of control lines to test the TMC2209, next step is to replace the messy control line by UART interface. The first thing to do is to setup and test the uart0 and uart1 for loopback, to make sure uart hardware and software setup are OK. The debugged test program is listed below.

tmctestv21.py (uart0, uart1 loopback with sample output)

Next step is to read/write tmc2209 control/status registers.

tmc2209 uart interface

Pico UART to TMC2209 UART wiring Diagram

Note - Using Pin 4 (UDN) of the TMC2209 Module for Read/Write Operation

tmc2209 uart wiring

TMC2209 UART Diagonistic Programming - Datagram Summary


TMC2209 Read Register Testing Plan

  1. Use Pico program to read a TMC2209 read/write general config register (address 0x00 ~0x0f).

  2. Repeatedly (every 10ms) read a general config register and use a scope to display the read datagram and byte returned (TMC2209 is autobaud, so can use 9600N81).

TMC2209 UDN_UART Read/Write mode wiring diagram (Using Pin 4

UDN_UART wiring

Note: 2022jan08

This TLDR answer has just reached the forum's 30k words limit, so I am stopping here, thinking what to do next, ... :)

Update: 2022jan12

  1. To make this answer shorter, I am moving the lengthy program listing to my penzu journal, to reclaim hopefully more than 2k words.

  2. I found that I have been mixing up TMC2208 and TMC2209 discussions so far. So Another way is to merge the tmc2208 comments into tmc2209.

So I have updated my testing functions to do the following:

  1. Config and setup pico gpio pins.
  2. Blinking GPIO connected LEDs.
  3. GP pins assignments to tmc2209
  4. Testing toggling tmc2209 control pins
  5. Setting up pico uart0, uart1
  6. Testing loopback of the pico uarts
  7. Read/Write tmc2209 registers.

Reference: Mastering Trinamic Stepper Motor Drivers with Arduino (also ESP32 wirelessly over WiFi) - uDemy, 2021Apr

tmc2209 uart 01


/ to continue, ...

  • 1
    Thanks for the detailed help! Dec 31 '21 at 2:48
  • Thanks a lot for your kindness and support, I am hoping to keep up my newbie friendly problem based learning (PBL) on smart stepper motor, steadily though slowly. Stay tuned. :) Cheers.
    – tlfong01
    Dec 31 '21 at 4:11
  • 1
    Really awesome answer!
    – guidoism
    Dec 31 '21 at 17:59
  • @guidoism, Thanks you for your nice words. Cheers.
    – tlfong01
    Jan 1 at 7:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.