Stepper motor very loud using tmc2209, esp32S dev board, and tmcstepper

Hi, i'm trying to use an MKS TMC2209 V2 (the v2 is of the MKS board, the tmc2209 is a v1.2) together with an ESP32S to control a NEMA 17 1.5A stepper motor (17HS4401).

I'm have a couple of issues currently, that i haven't been able to get my head around. Firstly is that the stepper is quite loud and vibrates a good deal when turning. It also heats up quite a bit, slightly past what i would consider the too hot to keep fingers on for an extended period of time. I don't have much experience with them, so i'm not sure what settings to change to improve this behavior

Second issue is that I'm pretty sure I'm not using the UART connection correctly as the serial monitor is not report the microsteps the code is setting and instead outs 256. I don't know if this is because I'm not reading it right or maybe not controlling the driver correctly.

Lastly, in between the serial prints, my serial monitor is filled with hundreds of
"E (687692) gpio: gpio_set_level(226): GPIO output gpio_num error"
and i've got no idea why.

My code is shown below, as is a drawing of my wiring, plus a few photos of the actual setup
The code is sourced mostly from this forum post: Using a TMC2209 silent stepper motor driver with an arduino - #14 by monkeyfist

I think i covered everything and provided the right stuff, but if anyone needs other info I'd be happy to provide.
Any help on the specific problems i listed or just general knowledge is very appreciated, thanks!

#include <SpeedyStepper.h> //Simple & good stepper library, get it.

#include <TMCStepper.h>

#define DIR_PIN          34 // Direction
#define STEP_PIN         35 // Step
#define SERIAL_PORT Serial2 // HardwareSerial port 
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2

#define R_SENSE 0.11 // Match to your driver
// SilentStepStick series use 0.11
// UltiMachine Einsy and Archim2 boards use 0.2
// Panucatt BSD2660 uses 0.1
// Watterott TMC5160 uses 0.075

bool shaft = false;  // ONLY NEEDED FOR CHANGING DIRECTION VIA UART, NO NEED FOR DIR PIN FOR THIS


TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);

SpeedyStepper stepper;

void setup() {

  stepper.connectToPins(STEP_PIN, DIR_PIN); // INITIALIZE SpeedyStepper

  SERIAL_PORT.begin(115200);      // INITIALIZE UART TMC2209
  Serial.begin(115200);
  delay(500);
  Serial.println(F("Serial Initialized"));

  driver.begin();                // Initialize driver

  driver.toff(5);                 // Enables driver in software

  driver.rms_current(600);       // Set motor RMS current
  driver.microsteps(2);           // Set microsteps to 1/2

  driver.pwm_autoscale(true);   // Needed for stealthChop
  // driver.en_spreadCycle(true);   // Toggle spreadCycle for smooth & silent operation

  stepper.setCurrentPositionInSteps(0);                   // Set zero position
  stepper.setSpeedInStepsPerSecond(400);                 //Set Speed
  stepper.setAccelerationInStepsPerSecondPerSecond(400);   //Set acceleration, smaller value for super smooth direction changing

}

void loop() {

  uint16_t msread = driver.microsteps();
  Serial.print(F("Read microsteps via UART to test UART receive : "));    Serial.println(msread);

  Serial.println(F("Move 6400 steps forward at 600ma"));
  driver.rms_current(1000);
  stepper.moveToPositionInSteps(6400);

  Serial.println(F("Wait 3sec and turn current low so you can turn the motor shaft"));
  driver.rms_current(10);
  delay(3000);

  Serial.println(F("Move back to 0 position at 300ma"));
  driver.rms_current(300);
  stepper.moveToPositionInSteps(0);

  //MOVE MOTOR VIA UART AND CHANGE DIRECTION VIA SOFTWARE, IT RUNS AS LONG AS YOU LET IT... PROBABLY ONLY USEFUL WITH ENCODER. THE VALUE SETS ONLY THE SPEED.

  // driver.VACTUAL(16000); //SET SPEED OF MOTOR
  // delay(2000); // MOTOR MOVES 2 SEC THEN STOPS
  // driver.VACTUAL(0); //STOP MOTOR BY SETTING SPEED TO 0
  // shaft = !shaft; // REVERSE DIRECTION
  // driver.shaft(shaft); // SET DIRECTION

}



Heat is related to your current, the more current the more heat.

The versions are version of the manufacturers boards, not TMC drivers. So they are completely irrelevant. But they do sell boards, as higher number sounds better :slight_smile:

When it comes to the noise, that's a tuning issue and relates to the particular motor & current.

You can see that it the example code it sets first the current to 1000ma then to 10ma and then to 300ma. This is done so that you get how to change current, as its really usefull.

This sets the driver to 1000ma:
driver.rms_current(1000);

It also has the start value, if you dont change it later.. this will define the current:
driver.rms_current(600); // Set motor RMS current

usually your motor comes with an current rating, you can go abowe it for extra torque. But it will result in more heat.

There is then also settings for current level when the motor is at standstill, and more advanced "coolstep" settings that only draw the necessary amount of current.

These settings are really helpful when you want to really push your motor, by driving it with higher currents and then give it time to cool down by using low hold current.

You can set the hold current directly via the rms_current, like this:
AMPS = CURRENT
driver.rms_current(AMPS,0.01);

This sets your hold current to basically 0. Higher value = higher hold current percentage.

"rms_current will by default set ihold to 50% of irun but you can set your own ratio with additional second argument; rms_current(1000, 0.3)."

About the sound, try this:

driver.en_spreadCycle(false);

True is spreadcycle, it has usually more torque. False is stealthChop that is the silent mode. There is also settings about at what speeds to turn stealthChop on etc.

And one thing that seems to have a big effect on the sound, is interpolation:

driver.intpol(true); // interpolate to 256 microsteps

This interpolates your steps to 256 microsteps in the driver, it does not reduce torque. But seems to really make motors silent.

Of course your actual microstep setting also has an effect on the sound.

BTW you want to run your driver via the 3.3v output on your ESP32 board. You can also just ground the ENABLE pin directly to the drivers ground. As you can enable & disable the driver via software.

Overall, i recommend checking out the github page and reading the datasheet. The example is there to get your basic config working. That you get your motor moving & UART communicating. After that, its up to you to fiddle all the settings.

https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2209_Datasheet_V103.pdf

Thanks much, the combination of driver.en_spreadCycle(false); and driver.intpol(true); got the sound down quite a bit, and reducing the current made the heat manageable.
Do you have any ideas for why my UART might not be reading correctly? I forgot to mention it in my original post, but before the edits you suggested, the serial monitor was reading the microsteps always as 256, even if i had set the mircosteps to 2, or anything else for that matter.

So they UART works now?

If you switched to using the 3.3v from the ESP32, that could explain it. Those stepper drivers need to be powered in the right order. They need the motor power first, and then the logic power. So if you previously were powering the driver first, and the the motor power. That could explain it, if you did not change any other wiring.

Or that you did not have a ground connection to the ESP32, as you were only connecting the EN pin to ground. I think UART needs a shared ground, but i'm not 100% on this.

If the UART was not working previously, then your currents were set by the potentiometer and could have been basically anything.

I put the microstep reading in to the code, exactly as its the easiest way to check it the UART works. It reads 256 when its not working.

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