Issues when replacing DRV8825 with TMC2209 on a CNC shield

Hey guys!

I am building a rather odd wall clock. It uses 4 stepper motors to control two scara arms as the minute and hour hands.

Hardware used:
Arduino Uno Rev3
CNC shield V3 (CNC Shield V3)
4 random DRV8825 - no idea where they come from..
4 Fysetc TMC2209 (Fysetc 2209 - Bought through their ALI store)
4 Small stepper motors (OMC-StepperOnline: 11HS12-0674S)
The cnc shield and arduino both runs on 12V
Hall sensors are used to detect the position of the arms - I am not counting steps.

The issue:
The drv8825 works perfectyl! But, they are LOUD...
So I bought 4 TMC2209 from Fysetc () hoping for a drop-in replacement to reduce noise. I thought they could run with simple STEP/DIR/EN signals in stealthchop mode and 1/16th microstepping by setting the MS1 and MS2 to 5V. Without using any fancy TX/RX/SPI signals.

However, when I run the exact same program that works perfectly with the DRV8825 the motors does not move but just makes a easily audible whining noise. They are energized (do not spin freely). If I switch back to the 8825, then it works as it should.

I measured all the pins on the driver when the program is running and I get what I would expect.

The Code:
The following is a simple version of the code. This is how I controlled the 8825 drivers without issues. I tried using values between 0 to 10, 100 microseconds and even up to 1 second for the "MinDelay". No succes.. (I left out a bunch of variable definitions for the MB, HA and HB motors in the beginning just to make it more readable).

//Including libaries
#include <Wire.h>           //Libary used for I2C communication.
#include <RTClib.h>         //Libary used to integrate the RTC.
RTC_DS3231 rtc;             //Defining the type of RTC used.

//Defining general variabes:
  int OldMinute = 0;        //Int used to store the old minute value.
  int MinDelay = 0;         //Int used to control the speed of the motors. When set to 0 mtors run at max speed limited by the code.
//General variables defined.

//Defining varables related to the MA Motor:
    //Coresponding Minute:   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59, Center.
  int MA_Target_Array[] = {515, 300, 308, 317, 325, 335, 316, 297, 278, 259, 240, 228, 216, 204, 192, 180, 178, 176, 174, 172, 170, 176, 182, 188, 194, 200, 210, 220, 230, 240, 250, 275, 300, 325, 350, 375, 431, 487, 543, 599, 655, 696, 737, 787, 819, 860, 851, 842, 833, 824, 815, 790, 765, 740, 715, 690, 655, 620, 585, 550,    505};
  int MA_Read = 0;          //Analog read value from MA encoder.
  int MA_Max = 1000;        //The encoder value at maximum mechanical travel - Closest to motor = 898 for MA.
  int MA_Min = 0;           //The encoder value at minimum mechanical travel - Closest to center rod = 106 for MA.
  int MA_Range_Upper = 0;   //The upper encoder limit for the current move. 
  int MA_Range_Lower = 0;   //The lower encoder limit for the current move.
  int MA_Target = 0;        //The encoder target for the current move. Based on the values in MA_Target_Array.
  bool MA_Dir;              //Direction specification. True = Encoder value is larger than target = Motor moves in.
  boolean MoveMA = false;   //Specifies if the motor should move.
//MA variables defined.

//Defining varables related to the MB Motor:
//MB variables defined.

//Defining varables related to the HA Motor:
//HA variables defined.

//Defining varables related to the HB Motor:
//HB variables defined.

//Defining shield pins:
  # define EN 8                 //Enable control for all steppers. Steppers are active when pin is low.
  # define MA_DIR 6             //MA stepper direction control - X label on CNC Shield.
  # define MA_STP 3             //MA stepper control - X label on CNC Shield.
  # define MB_DIR 5             //MB stepper direction control - Y label on CNC Shield.
  # define MB_STP 2             //MB stepper control - Y label on CNC Shield.
  # define HA_DIR 13             //HA stepper direction control - Z label on CNC Shield.
  # define HA_STP 12            //HA stepper control - Z label on CNC Shield.
  # define HB_DIR 7            //HB stepper direction control - A label on CNC Shield.
  # define HB_STP 4            //HB stepper control - A label on CNC Shield.
  # define motorInterfaceType 1 // Accel lib - must be 1 when using a stepper driver.
//Shield PINS defined.

//Defining encoder pins:
  #define MA  A2            //Analog pin used for the MA encoder.
  #define MB  A1            //Analog pin used for the MB encoder.
  #define HA  A3            //Analog pin used for the HA encoder.
  #define HB  A0            //Analog pin used for the HB encoder.
//Encoder pins defined.


void MoveArms (int MinDelay)
  digitalWrite (EN, LOW); // Setting Enable pin low to enable steppers
  Serial.println("Motors enabled and movement begun"); 
  while(MoveMA == true || MoveMB == true || MoveHA == true || MoveHB == true){
    //Encoders are read
    MA_Read = analogRead(MA);
    MB_Read = analogRead(MB);
    HA_Read = analogRead(HA);
    HB_Read = analogRead(HB);
    if(MA_Read < MA_Range_Upper && MA_Read > MA_Range_Lower && MoveMA == true){ //If statement checks if the encoder is within range and the motor is supposed to move
      digitalWrite(MA_STP, HIGH);
      MoveMA = false; //The motor is turned off, if the encoder is not within range (when the arm have reached target position).
    if(MB_Read < MB_Range_Upper && MB_Read > MB_Range_Lower && MoveMB == true){
      digitalWrite(MB_STP, HIGH);
      MoveMB = false;
    if(HA_Read < HA_Range_Upper && HA_Read > HA_Range_Lower && MoveHA == true){
      digitalWrite(HA_STP, HIGH);
      MoveHA = false;
    if(HB_Read < HB_Range_Upper && HB_Read > HB_Range_Lower && MoveHB == true){
      digitalWrite(HB_STP, HIGH);
      MoveHB = false;
    digitalWrite(MA_STP, LOW);
    digitalWrite(MB_STP, LOW);
    digitalWrite(HA_STP, LOW);
    digitalWrite(HB_STP, LOW);
} //End of: MoveArms.

void setup ()//The setup function is run 1 time on power on. It initializes the Seral communication and RTC. It defines pin types and sets stepper speeds.
  //Serial setup:
  Serial.begin(9600);             //Starts the serial connection with a baud rate of 9600.
  delay(500);                     //Delay ensures that serial communication is running before continuing.
  //End of: Serial setup.

  //RTC Setup:
  if (! rtc.begin()) {            //If command chechs if RTC is communicating properly. 
    Serial.println("Couldn't find RTC");
    while (1);
  if (rtc.lostPower()) {
    Serial.println("RTC lost power");
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0)); // Sets the RTC with an explicit date & time of: January 27 2017 at 12:56. 
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Currently 5s behind on 12:30 01. aug. 
  // End of: RTC Setup.

  //Pin Setup:
    //Hall Pins
    pinMode(MA, INPUT);
    pinMode(MB, INPUT);
    pinMode(HA, INPUT);
    pinMode(HB, INPUT);
    //CNC Shield Pins
    pinMode (EN, OUTPUT); // Setting Enable pin as output type
  //End of: Pin setup.
} // End of: Viod Setup.


void loop () //Main Loop begins.
  DateTime now =; // Sets the current time to that of the RTC.
  if(OldMinute != now.minute()){  //This loops activates every time the minute has changed.
    MoveMA = true;
    MoveMB = true;

    if(now.minute() == 0 || now.minute() == 12 || now.minute() == 24  || now.minute() == 36 || now.minute() == 48){
      MoveHA = true;
      MoveHB = true;


    OldMinute = now.minute(); //Old minute is updated.
  } // End of: Minute action.
  delay(1000); // Delay controls loop time.
} // End of: Void Loop.

I have looked everywhere especially on this forum and youtube, and from what I can see it should just work, but it does not..
I hope some of you guys have had luck using the 2209 drivers in the simple STEP/DIR/EN application like mine and know what I am not doing corectly!

THANKS! :smiley:

Downloading the data sheet I wonder why You selected that driver. Only looking at the pins it looks like having a number of options. Do You need them?
Why not a 6650 or similar? They use EN, DIR, PUL only.

Always read the data sheet and the application note. Then decide for buying or not, depending on whether You've understood it all.

All steppers make sounds. Maybe different drivers contribute differently.

I've used A4988 on a Prootoner V3 board without problems.

Hey Railroader!

As mentioned I can make it work with DRV8825 drivers and I gues A4988 also work as these drivers both are what the cnc shield is made for. However, the A4988 is even louder than the DRV8825. If you wtach this video I hope it is clear why I wanted to use stealthchop2 for a wall clock in my leving room xD
A4988 VS TMC2208 Noise comparison
I choose the 2209 instead of 2208 because it semed to be a cheaper and newer version of the 2208 driver.

I do not know the 6650 drivers and cannot find them. Do you have a link?

I could have chosen the TMC2100 as they are STEP/DIR/EN only boards like the A4988 and DRV8825. However, they only use stealthcop and not stealtchop2 wich is even quieter. And it was my understanding from both the datasheet and variuos websides that the 2209 would also work in this "legacy" mode as seen here and on page 4 and more.

From 2209 datasheet

I may buy some TMC2100's, but its gonna take weeks before I get them. And I would really like to understand why the 2209's are not working. I really do not see why they wouldn't. It is most likely a simple stupid mistake somewhere as I am no electronics/software expert. I am just a mechanical engineer who likes to make things move..

But thanks for your input!

Sorry. It should have been TB6600....
I've never dug down in the theories You tell about.
Check the pins on Your driver. Is someone not connected the correct way? Does the circuit need some kind of soft setup? Check the application notes.

Aah okay, they are completely different drivers though. No way I can fit 4 of those in My clock. I do not know them but I doubt that they perform much different than the A4988 or Drv8825 regarding noise.

I did look in the datasheet and on the pinout. I am asking here because as far as I can see it should work but it does not.. So I was hoping another set of eyes could spot the error..

I use the TB6600 when a stepper needs more current, like 2 - 3 Amps.
I can't tell if they are quite or not.
Had too little of time to check the data sheet, of Your device, for application notes, setup etc.


I found the issue!

As expected it was me making a dump mistake... xD
I forgot to set the DIR and STEP pins as outputs in the code. Apparently the DRV8825 does not care, but the MC2209's did. So just remember to set the control pins as output and it works xD

I gotta say, these drivers impress me! The clock is litteraly silent now. Absolutely no motorsound what so ever, none!

Well done! As You had a running setup changing driver shouldn't call for inspecting the code. Quite a surprise. Let's hear what the other helpers say.

No I really didn't expect that either.. But really glad I found it!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.