Stepper motor only turns reliably one direction

Stepper Details

Manufacturer Part Number 17HS15-1704S
Step Angle 1.8°
Step Accuracy 5%
Holding Torque 44Ncm(62.32oz.in)
Rated Current/phase 1.7A
Phase Resistance 1.86ohms
Driving Voltage 12-24VDC
Inductance 3.55mH±20%(1KHz)
Weight 280g

Hi, I'm building a display piece that has a rotating component. I need the motor to run as quietly as possible which is why I've selected a stepper motor for this application. I'm using a Nano connected to TMC2208 driver, NEMA 17 motor and a couple of push buttons. At the moment I am driving the Nano VIA USB and the TMC2208 via desktop power suppy at 5V however in the final version there will be a dedicated 5V power supply.

I've developed a circuit and code which I understand should incrementally increase and decrease the speed with each button press. One button increases speed in the CW direction whilst the other increases the speed in the CCW direction. From zero the motor will begin to spin either CW or CCW direction.

What I am experiencing is that the motor will spin at each speed increment up to the max speed limit. It will slow back down when the alternate button is pressed, however when attempting to spin in the opposite direction it will stutter and jitter. If enough speed is applied it eventually turns albiet roughly.

Video of the out put https://streamable.com/hffp8u

I've experimented with changing the wiring of the stepper motor, the only difference I find is that either CW or CCW runs smoothly and the opposite direction runs roughly.

I've tried driving the motors using simple digitalrights to the direction and step pins and get the same behaviour.

I've tried various stepper motors (all same make) and TMC2208 drivers to make sure I dont have faulty components and nothing changes the output.

Code is below. I understand that using AccelStepper library that speeds greater than 1000 are unreliable however dropping the speed below 1000 doesn't change the behaviour either.

Quick note, I dont have momentary switches, just push button so I've coded the input so the buttons only register once when pushed.

This is my first Arduino project so I'm a bit lost at the moment.

#include <AccelStepper.h>

const int UPBUTTON = 7; 
const int DOWNBUTTON = 9; 
int upButtonState = 0; 
int downButtonState = 0;
int speed = 0;
int maxSpeed = 8000;
int speedStepValue = 1000;
bool upButtonActive = false;
bool downButtonActive = false;

AccelStepper stepper1(1, 2, 5); // (Type of driver: with 2 pins, STEP, DIR)

void setup() {
  stepper1.setMaxSpeed(maxSpeed + 1);

  stepper1.setSpeed(0);
  pinMode (UPBUTTON, INPUT);
  pinMode (DOWNBUTTON, INPUT);
}

void loop() {
  stepper1.runSpeed();

  upButtonState = digitalRead(UPBUTTON);  // Reading button status / input
  if (upButtonState == HIGH && !upButtonActive)  // Condition to check button input
    {
      speed += speedStepValue;

      if  (speed > maxSpeed){
        speed = maxSpeed;
      }

      stepper1.setSpeed(speed);
      upButtonActive = true;
    }
    else if(upButtonState == LOW && upButtonActive)
    {
      upButtonActive = false;
    }

  downButtonState = digitalRead(DOWNBUTTON);  // Reading button status / input
  if (downButtonState == HIGH && !downButtonActive)  // Condition to check button input
    {
      speed -= speedStepValue;

      if  (speed < -maxSpeed){
        speed = -maxSpeed;
      }

      stepper1.setSpeed(speed);
      downButtonActive = true;
    }
    else if(downButtonState == LOW && downButtonActive)
    {
      downButtonActive = false;
    }
}

I've also trialed some simpler code using "moveTo" function but I get the same results:

#include <AccelStepper.h>

AccelStepper stepper1(1, 2, 5);
int target;

void setup() {
  target = -8000;

  stepper1.setMaxSpeed(1000);
  stepper1.setAcceleration(200);
  stepper1.setSpeed(1000);
  stepper1.moveTo(target);
}

void loop() {
    if (stepper1.distanceToGo() != 0) {
        stepper1.run();
    }
    else {
        // we have reached our target position.
        // pause 1 second and then reverse direction:
        delay(1000);
        target *= -1;
        stepper1.moveTo(target);
    }
}

Thanks for using code tags on your first post!

Please post images, links to the components and a schematic in your post, in line. Forum members do not like to go off site to find your stuff, and the off site stuff tends to disappear, making posts incomprehensible to later users.

Have you set the current limit on the motor drivers properly? Adequate power motor supply?

Thanks for the tip! I've edited my post.

I've set the current limiting on the driver to ~0.9A and voltage to both driver and nano are 5V independently.

I am connecting the driver to the motor via breadboard contacts however. I heard that may be a limiting factor but the motor turns fine in one direction.

You can add more posts with the required details in line.

Breadboards are for temporary experiments with low power logic circuitry and cannot handle motor currents. The tracks will burn. Solder all motor/driver connections, or use connectors rated for at least 2 Amperes.

One thing to note with Accelstepper, whenever you set the position to move to, it is going to recalculate the speed. If you are trying for constant speed, which it appears you are, you should call setSpeed after you call moveTo.

Also, your wiriing diagram is missing a couple of wires isn't it? You have VID conntected to 5v and the upper ground connected to ground, correct?

Also, the speed you are setting your stepper to, 8000, is unreliable in accelstepper. From the accelstepper library:

Speeds of more than 1000 steps per second are unreliable. Very slow speeds may be set (eg 0.00027777 for once per hour, approximately. Speed accuracy depends on the Arduino crystal. Jitter depends on how frequently you call the runSpeed() function.

8000 steps per second with your current wiring is 300 RPM. But if you modified your wiring your could get the same speed with much fewer steps. Since you have not set MS1 or MS2 by wiring them, they will be pulled to ground which will give you 1/8th microstepping on the TMC2208. If you pull MS1 to 5v, then you will get 1/2 microstepping which will reduce the number of steps required to make 1 full revolution of the motor.

Also, why are you only driving the Nema with 5v power? Nema 17 steppers are usually driven with 12 or 24v. I was confused by this at first too but the voltage rating that is written on them is not the voltage that you should deliver to them. The stepper is a function of current. The faster it gets up to the current that is necessary to move it to the next position, the faster it is going to be able to receive the next step.

Also, the TMC2208 can run with only 5v supplied to it but only if the chip is wired that way. If your board was sold as a 3d printer motor driver, then it is not going to be wired for 5v only mode. This is the way the chip has to be wired for 5v only mode:

And this is how it is wired for standard applications:

1 Like

5volt is on the (too) low end for this driver chip.

5volt on V-in is too low for the Nano to make a reliable 5volt for itself.
Absolute minimum for V-in is 6volt, and 7-9volt is recommended.
Leo..

The motor power supply may be current limiting, or cutting out. 5V is the absolute minimum for the stepper driver shown in the schematic (the A4988 won't work at all at 5V), and the motor/driver setup will work much, much better at 12 to 24 V.

Power supply current draw is dramatically reduced at higher voltages, because the stepper driver and motor windings act as a buck converter.

It is not a good idea to power the motor and the Arduino from the same power supply, unless you add appropriate power supply decoupling circuitry, or power the Arduino using a buck converter.

1 Like

Thanks for the replies everyone, sorry for the delay but I had to travel over the weekend. I have updated the circuit as follows:

This is the original tutorial I was trying to follow to get things running.

I'm no longer using the breadboard everything is connected using appropriate wires.

What was missing before on the original circuit, I had been driving the Nano via USB. Now the Nano is running off 8V via a buck convertor and the driver off 12V.

Unfortunately I've some how managed to kill the Nano. I plug in into the USB to upload new code and it gets extremely hot straight away. I think I accidently bridged the VID while moving things around. :person_facepalming:

Luckily I have a spare however I'd love to get comfirmation that I'm on the right track with my wiring before going any further. Could someone check this setup?

Am I even on the right track with this setup? I originally assumed that it would be a fairly simple matter of connecting the driver to the nano and with the right code, the stepper should behave as intended. I'm experienced with 3d Printing which is why I have gone down this path. I feel like I am missing something fundamental. Any help is appreciated.

the electrolytic cap across the driver's power input is missing too

100uF 50V across the VM/Gnd ( soldered on those pins ) will do

I've solved the problem and now have reliable motion, it boiled down to a couple of things.

The bipolar stepper motor I chose had incorrectly labeled outputs so my connection to the driver was incorrect. I had fixed this previously by experimenting with alternate layouts. I ended up checking for continuity between the loops on the stepper motor and ignoring the directions on the stepper motor.

The other problem was not having sufficient delay between the digitalwrites. I've experimented with this to find the fastest reliable speed I can achieve with the Nano and found a delay of 400 microseconds between raising and lowering the step pin voltage and 100 microseconds before attempting another raising of the step voltage. Code below spins the motor in alternating directions.

Thanks for everyones input. Every little bit helped.

#define EN_PIN    7 //enable (CFG6)
#define DIR_PIN   8 //direction
#define STEP_PIN  9 //step
#define WRITE_DELAY 400 //delay between raising and lowering step voltage
#define LOOP_DELAY  100 //delay before starting next loop


void setup()
{
  //set pin modes
  pinMode(EN_PIN, OUTPUT);
  digitalWrite(EN_PIN, HIGH); //deactivate driver (LOW active)
  pinMode(DIR_PIN, OUTPUT);

  pinMode(STEP_PIN, OUTPUT);
  digitalWrite(STEP_PIN, LOW);

  digitalWrite(EN_PIN, LOW); //activate driver

}

void loop()
{
  digitalWrite(DIR_PIN, LOW); //LOW to CCW
  //make steps
  for (int i = 0; i <= 5000; i++){
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(WRITE_DELAY);
      digitalWrite(STEP_PIN, LOW);
      delayMicroseconds(LOOP_DELAY);
  }
  
  digitalWrite(DIR_PIN, HIGH); //HIGH to CW

  for (int i = 0; i <= 5000; i++){
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(WRITE_DELAY);
      digitalWrite(STEP_PIN, LOW);
      delayMicroseconds(LOOP_DELAY);
  }
}

I've done some further experimenting with the slower delay values and can induce stuttering behaviour so there is still some knowledge I am missing however I'll mark this one as solved for now.

You might need to use a faster microcontroller. I am running a project with a stepper that is running at 200 RPM at 1600 steps per revolution. That works out to a step every 188 us. So, less than half of what you were getting. But I am using an ESP32 which has a much faster processor and is dual core.

As long as you don't mind the movement being blocking, you can also try to use runToPosition instead of the run. It is blocking, so you won't be able to do anything else until it reaches it's destination but for your application I don't know if that matters. You might get better results with that.

1 Like

I'll definitely check that out. I actually need to limit the speed somewhat so I'm not worried about the clockspeed being the bottleneck here. Thanks again.

1 Like

The Nano is not the bottleneck.
Try a stepper library with acceleration/deceleration.
Leo..

1 Like

Uhm........

Only looked at post#10

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