I'm using a stepper motor to rotate office-blinds for an art installation. For that the motor needs to rotate the chain in both directions. It should turn first clockwise until it reaches the one limit switch and then turn counter clockwise until it reaches the other limit switch.
My problem so far is that the stepper motor only turns in one direction and in the other one it's blocked and vibrates slightly. I tested the resistance and the motor is fine and I bought a new driver but the problem is still there and I can't figure out what's wrong. I swapped all the possible motor wire connections but it will still end up just turning in one direction.
Highly appreciate any hints what to change or where the problem could be!
My setup is:
Nema 17 Stepper Motor (17HS19-2004S1)
TMC2209 V1.2 Stepper Motor Driver
Arduino UNO R3
The pins on the driver:
LEFT SIDE:
EN -> to Arduino GND
MS1 -> Empty
MS2 -> Empty
PDN -> Empty
STEP -> to Arduino PIN2
DIR -> to Arduino PIN3
TOP:
INDEX -> Empty
DIAG -> Empty
RIGHT SIDE:
VM -> 12V positiv (positiv leg of 35V 100 Capacitor)
GND -> 12V negative (negative leg of 35V 100 Capacitor)
A2 -> Black (A+)
A1 -> Green (A-)
B1 -> Red (B+)
B2 -> Blue (B-)
VDD -> Empty
GND -> to Arduino GND
Limit Switches are connected to Arduino PIN 7 and 8 and share a GND on the Arduino board
If "the other direction" is UP (raising the blind against gravity), the motor may not have enough torque. How do you have the TMC2209 current limit set?
I'm planning only to turn the blinds 180degrees, (it's the kind with long stripes) so the pressure on the chain is in both directions the same. But at the moment I don't have the motor connected so the blocking happens even with no pressure on.
The limit is set at 1,3 at the moment
What are the interesting parameters you are missing? I don't miss any from this datasheet.
May be you miss the max step speed from standstill?. But because this also depends on the driver this is often not mentioned in the datasheet.
You are right. If I remember the name was “Run in/Run out”. Old sickness from a special job making a stepper accelerate as fast as possible and custom designing a driver some 40 years ago.
“Test and try” of course makes things work testing some numbers.
I found a solution! Maybe it's helpful for other people as well:
I installed the AccelStepper library and then updated this code and now it works!
(Don't really know why it's not working otherwise as I tried multiple drivers and they all have the same problem.)
#include <AccelStepper.h>
// Pin definitions
#define STEP_PIN 2
#define DIR_PIN 3
#define LEFT_LIMIT_PIN 7
#define RIGHT_LIMIT_PIN 8
// Create stepper object
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
// Motor settings - adjust these for your needs
int motorSpeed = 700; // Steps per second (increase for faster)
int motorAcceleration = 1000; // Acceleration rate
// Debounce
unsigned long lastSwitchTime = 0;
const unsigned long debounceDelay = 500;
void setup() {
Serial.begin(9600);
Serial.println("=== Curtain Control System ===");
// Configure limit switches
pinMode(LEFT_LIMIT_PIN, INPUT_PULLUP);
pinMode(RIGHT_LIMIT_PIN, INPUT_PULLUP);
// Configure stepper
stepper.setMaxSpeed(motorSpeed);
stepper.setAcceleration(motorAcceleration);
Serial.println("System ready!");
// Start moving right
stepper.moveTo(1000000);
Serial.println("Moving RIGHT\n");
}
void loop() {
// Read limit switches
bool leftPressed = !digitalRead(LEFT_LIMIT_PIN);
bool rightPressed = !digitalRead(RIGHT_LIMIT_PIN);
// Handle limit switches
if ((leftPressed || rightPressed) && (millis() - lastSwitchTime > debounceDelay)) {
if (leftPressed) {
Serial.println("\n>>> LEFT LIMIT HIT <<<");
stepper.stop();
delay(1000);
// Move right
stepper.moveTo(stepper.currentPosition() + 1000000);
Serial.println("Moving RIGHT\n");
}
if (rightPressed) {
Serial.println("\n>>> RIGHT LIMIT HIT <<<");
stepper.stop();
delay(1000);
// Move left
stepper.moveTo(stepper.currentPosition() - 1000000);
Serial.println("Moving LEFT\n");
}
lastSwitchTime = millis();
}
// Keep motor running
stepper.run();
}