Setting the speed of a stepper motor with Arduino Uno and TMC2209

Hi All

I am using a TMC2209 Stepper Driver with an Arduino Uno, 2 Endstops and 2 smart relays as inputs to control the stepper motor.

I have everything working by modifying code that was posted by @mrExplore however the only issue I have is I cannot control the speed, my Stepper Motor runs about 1 revolution in 30 seconds and I am not sure how to speed it up. Please see code below, thanks in advance for any help or insight.

#include <TMCStepper.h>

#define DIR_PIN           3     // Direction pin
#define STEP_PIN          4     // Step pin
#define FORWARD_RELAY_PIN 5     // Digital pin for forward direction relay input
#define REVERSE_RELAY_PIN 6     // Digital pin for reverse direction relay input
#define FORWARD_ENDSTOP_PIN 7   // Digital pin for forward endstop switch input
#define REVERSE_ENDSTOP_PIN 8   // Digital pin for reverse endstop switch input
#define SERIAL_PORT       Serial
#define DRIVER_ADDRESS    0b00   // TMC2209 Driver address according to MS1 and MS2

#define R_SENSE 0.11f // Match to your driver

TMC2209Stepper driver(&SERIAL_PORT, R_SENSE, DRIVER_ADDRESS);

void setup() {
  pinMode(DIR_PIN, OUTPUT);
  pinMode(STEP_PIN, OUTPUT);
  pinMode(FORWARD_RELAY_PIN, INPUT_PULLUP);
  pinMode(REVERSE_RELAY_PIN, INPUT_PULLUP);
  pinMode(FORWARD_ENDSTOP_PIN, INPUT_PULLUP);
  pinMode(REVERSE_ENDSTOP_PIN, INPUT_PULLUP);

  SERIAL_PORT.begin(115200);
  delay(500);
  SERIAL_PORT.println(F("Serial Initialized"));

  driver.begin();
  driver.toff(5);
  driver.rms_current(600);
  driver.microsteps(2);
  driver.pwm_autoscale(true);
  driver.en_spreadCycle(true);
}

void loop() {
  // Read the relay states
  bool forwardRelayState = digitalRead(FORWARD_RELAY_PIN) == HIGH;
  bool reverseRelayState = digitalRead(REVERSE_RELAY_PIN) == HIGH;

  // Read endstop state
  if (digitalRead(FORWARD_ENDSTOP_PIN) == LOW || digitalRead(REVERSE_ENDSTOP_PIN) == LOW) {
    driver.VACTUAL(0);
    return; // Exit the loop
  }

  // Set stepper direction
  if (forwardRelayState && !reverseRelayState) {
    // Forward direction
    digitalWrite(DIR_PIN, LOW);
  } else if (!forwardRelayState && reverseRelayState) {
    // Reverse direction
    digitalWrite(DIR_PIN, HIGH);
  } else {
    // stop stepper
    driver.VACTUAL(0);
    return; // Exit the loop
  }

  // Run Stepper
  driver.VACTUAL(32000); 
  digitalWrite(STEP_PIN, HIGH);
  delayMicroseconds(500); 
  digitalWrite(STEP_PIN, LOW);
  delayMicroseconds(500); 
}

I have tried setting VACTUAL to different sppends and tried controlling speed using delays.

Cheers

DJ

The motor steps on the low to high transition (rising edge) of the step signal. The speed is contolled by the duration the the pulse low part. The high part needs only to meet the minimum high time which is probably on the order of a microsecond (consult the driver data sheet).

 digitalWrite(STEP_PIN, HIGH);
 delayMicroseconds(2);   // only needs to be high for a short time
 digitalWrite(STEP_PIN, LOW);
 delayMicroseconds(500);  // this time controls the stepper speed

You will not be able to reach high speeds without using acceleration. The AccelStepper, MobaTools stepper or other libraries use acceleration. I prefer the MobaTools library.

Here is a demo code for the TMC2209 using the MobaTools stepper library to enable using acceleration to get to higher speeds. Also shows how to connect to the UART to SoftwareSerial to control TMC2209 parameters.

Code tested with real hardware.

// TMC2209 test code by groundFungus aka c.goulding
// stepper bounce with speed and distance controlled by pot

#include <TMCStepper.h>
#include <SoftwareSerial.h>
#include <MobaTools.h>

const byte EN_PIN = 8; // Enable
const byte DIR_PIN = 4; // Direction
const byte STEP_PIN = 5; // Step
const byte speedPotPin = A0;
const byte distancePotPin = A1;

const byte SW_RX = 6; // TMC2208/TMC2224 SoftwareSerial receive pin
const byte SW_TX = 7; // TMC2208/TMC2224 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

const int stepperPulsePerRev = 200;
int microstepping = 4;
int stepsPerRev = stepperPulsePerRev * microstepping;

TMC2209Stepper driver(SW_RX, SW_TX, R_SENSE, DRIVER_ADDRESS);
SoftwareSerial ss(SW_RX, SW_TX);
MoToStepper myStepper( stepsPerRev, STEPDIR );

void setup()
{
   Serial.begin(115200);
   ss.begin(38400);  // highest reliable speed for SoftwareSerial

   pinMode(EN_PIN, OUTPUT);
   pinMode(STEP_PIN, OUTPUT);
   pinMode(DIR_PIN, OUTPUT);
   digitalWrite(EN_PIN, LOW);      // Enable driver in hardware

   myStepper.attach( STEP_PIN, DIR_PIN );
   myStepper.attachEnable(EN_PIN, 0, 0);  // pin, delay, active state
   myStepper.setSpeed(1000);  // rpm /10
   myStepper.setRampLen(20); // set acceleration
   myStepper.setZero(); // home position

   driver.begin();
   driver.toff(4);                 // Enables driver in software
   driver.rms_current(1000);        // Set motor RMS current
   driver.microsteps(microstepping); // Set microsteps

   //driver.en_spreadCycle(false);   // Toggle spreadCycle on TMC2208/2209/2224
   driver.pwm_autoscale(true);     // Needed for stealthChop
}

void loop()
{
   static int sign = 1;
   int stepperSpeed = analogRead(speedPotPin) * 2.5;
   int stepperDistance = analogRead(distancePotPin) * 4;

   if(stepperSpeed < 10)
   {
      stepperSpeed = 10;
   }

   myStepper.setSpeed(stepperSpeed);

   if (myStepper.moving() == 0)
   {
      sign = sign * -1;
      myStepper.move(stepperDistance * sign);
   }
}

image

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