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.
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);
}
}