Stepper Motor Trouble w/ AccelStepper Library

Hi All,

I am having trouble getting my stepper to run smoothly at "low speeds" (details below) using AccelStepper library. When running the stepper simply through my BigEasyDriver (at similar speeds) it runs very smooth. Appreciate any input.

My setup:
-Nema 17 stepper
-Arduino Uno Rev3
-30V Power Supply
-Big EasyDriver

Please see my video HERE. It shows how the motor is running with INPUT=3 (see code below), this is using a half-step loop through EasyDriver. The 2nd half of the video shows INPUT=1, using AccelStepper. The motor becomes very noisy and vibrates heavily (see the screw fly off the motor in the video).

I am supplying the EasyDriver 30V, and my power supply reads ~0.3A when the motor runs. When I try to go much higher with the current pot on the EasyDriver (at 30V) the motor spins out of control. I can get closer to the 2A spec of the motor when turning down the input Voltage. (but I get the same response as in the video)

Any ideas?

Code:

#include <AccelStepper.h>
#define stp 2
#define dir 3
#define MS1 4
#define MS2 5
#define MS3 6
#define EN  7
AccelStepper stepper(AccelStepper::DRIVER, 2, 3);

//Declare variables for functions
char user_input;
int x;
int y;
int state;
int Input;
int pos = 100;

void setup() {
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(MS3, OUTPUT);
  pinMode(EN, OUTPUT);
  resetEDPins(); 

  Serial.begin(9600); //Open Serial connection for debugging
  Serial.println("Begin motor control");
  Serial.println();
  stepper.setMaxSpeed(200);
  stepper.setAcceleration(2000);
  digitalWrite(MS1, LOW);
  digitalWrite(MS2, LOW);
  digitalWrite(MS3, LOW);
  
}

//Main loop
void loop() {
  while(Serial.available()){
      stepper.setCurrentPosition(0);
      
      user_input = Serial.read(); //Read user input and trigger appropriate function
      digitalWrite(EN, LOW); //Pull enable pin low to allow motor control
      if (user_input =='1')
      {
         StepForwardDefault();
      }
      else if(user_input =='2')
      {
        ReverseStepDefault();
      }
      else if(user_input =='3')
      {
        SmallStepMode();
      }
      else if(user_input =='4')
      {
        ForwardBackwardStep();
      }
      else if(user_input =='5')
      {
        CallInputMode();
      }
      else
      {
        Serial.println("Invalid option entered.");
      }
      resetEDPins();
  }
}

//Reset Easy Driver pins to default states
void resetEDPins()
{
  digitalWrite(stp, LOW);
  digitalWrite(dir, LOW);
  digitalWrite(MS1, LOW);
  digitalWrite(MS2, LOW);
  digitalWrite(MS3, LOW);
  digitalWrite(EN, HIGH);
}


void StepForwardDefault()
{
stepper.runToNewPosition(pos);
  Serial.println("Enter new option");
  Serial.println();
}

//Reverse default microstep mode function
void ReverseStepDefault()
{
 digitalWrite(dir, HIGH); //Pull direction pin low to move "forward"

stepper.runToNewPosition(-pos);

  Serial.println("Enter new option");
  Serial.println();
}

void SmallStepMode()
{
  digitalWrite(dir, HIGH); //Pull direction pin low to move "forward"
  digitalWrite(MS1, HIGH); 
  digitalWrite(MS2, LOW);
  digitalWrite(MS3, LOW);
  for(x= 1; x<300; x++)  //Loop the forward stepping enough times for motion to be visible
  {
    digitalWrite(stp,HIGH); //Trigger one step forward
    delay(1);
    digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
    delay(1);
  }
  Serial.println("Enter new option");
  Serial.println();
}
  1. Please edit your post to use code tags.
  2. I can't watch the video right now, so I don't have any specific advice for you.
  3. Your question seems to be "If I run in full step mode, I get a different result to 1/8 step mode?" My answer to this is "Yes. You do get a different result."

MorganS:

  1. Please edit your post to use code tags.
  2. I can't watch the video right now, so I don't have any specific advice for you.
  3. Your question seems to be "If I run in full step mode, I get a different result to 1/8 step mode?" My answer to this is "Yes. You do get a different result."
  1. Fair enough
  2. Okay..?
  3. That is not my question... Please see the "The motor becomes very noisy and vibrates heavily (see the screw fly off the motor in the video)." The video explains best.

Are you using micro-stepping for both tests?

What happens if you use runSpeedToPosition() (i.e. without acceleration).

If that does not help then you need to post the code that causes the smooth running.

...R
Stepper Motor Basics
Simple Stepper Code

Robin2:
Are you using micro-stepping for both tests?

What happens if you use runSpeedToPosition() (i.e. without acceleration).

If that does not help then you need to post the code that causes the smooth running.

...R
Stepper Motor Basics
Simple Stepper Code

Hi Robin,

Good point. In my video I was running with a full-step for the AccelStepper while half-step without. Running again with half-step for both, I still get heavy vibrations out of the motor running with AccelStepper. Although it is slightly less extreme than it was with the full-step setting. Still enough to send the screw flying off the motor...

There is no noticeable difference between runSpeedToPosition() and runToNewPosition(), so the acceleration component does not seem to be the issue. Thanks for that suggestion though.

The smooth operation is when I'm just looping the step pins on the driver. Code below

void SmoothStepping()
{
  digitalWrite(dir, HIGH);
  digitalWrite(MS1, HIGH); 
  digitalWrite(MS2, LOW);
  digitalWrite(MS3, LOW);
  for(x= 1; x<300; x++) 
  {
    digitalWrite(stp,HIGH);
    delay(1);
    digitalWrite(stp,LOW);
    delay(1);
  }
  Serial.println("Enter new option");
  Serial.println();
}

I can't think why the AccelStepper code would behave differently.

If I was writing your SmoothStepping() function I would change it a little - like this

for(x= 1; x<300; x++)
  {
    digitalWrite(stp,HIGH);
    delayMicroseconds(10);
    digitalWrite(stp,LOW);
    delay(2);
  }

In other words, a very short HIGH pulse. I suspect AccelStepper works like that - but you would need to study the source code.

What happens if you try the above?

...R

Robin2:
In other words, a very short HIGH pulse. I suspect AccelStepper works like that - but you would need to study the source code.

What happens if you try the above?

Thanks. So the motor continues to run great with the delays you suggested. But I then tried adjusting the LOW step delay, and have found that as I move that out towards 400ms+ (delay(4)) the motor starts to act very much like AccelStepper.

That gives me something to chase down. I'm not too familiar with AccelStepper, but maybe there is a setting I'm missing that will let me define the LOW pin delay.

marshallworrall:
But I then tried adjusting the LOW step delay,

It much more meaningful to describe that delay as the interval between steps

It may be that you are coming across a resonance in the motor. Stepper motors are noted for that - especially when they have no load.

...R

Robin2:
It much more meaningful to describe that delay as the interval between steps

It may be that you are coming across a resonance in the motor. Stepper motors are noted for that - especially when they have no load.

...R

Noted on the terminology, thanks.

I do find that even under load I get the same response in this case.

Looking at the AccelStepper library I don't see any functions to allow me to define delay between step intervals. But I guess that is variable so it can hit a target Speed? Which leads me to think that at these lower speeds, I may just be out of luck with this library (and my motor)?

My application is driving a camera lens focus ring. My goal with AccelStepper was to soften the hard stops/starts with acceleration/deceleration. Might there be another path to this same goal?

marshallworrall:

  1. Fair enough
  2. Okay..?
  3. That is not my question... Please see the "The motor becomes very noisy and vibrates heavily (see the screw fly off the motor in the video)." The video explains best.

Yes, full step mode is awful, no-one uses it in a high performance system. You also have an undamped
setup in that video, so you may be hitting mid-band resonance, which is a killer - some sort of mechnical
damping is really good to have in a stepper system (belt drive is very good at this as the belt acts
as a damper).

Try 1/8 or 1/16 microstepping in the first instance - much less chance of miss-stepping and lower vibration
and noise. Higher microstepping ratios mean having to generate higher pulse rates which can be troublesome.

MarkT:
Try 1/8 or 1/16 microstepping in the first instance - much less chance of miss-stepping and lower vibration
and noise. Higher microstepping ratios mean having to generate higher pulse rates which can be troublesome.

Thanks for the input. Even at 1/16 stepping, I'm seeing the same behavior from the motor when running w/ AccelStepper library, but not when looping the step pins myself. When increasing my step interval delay to 400ms+, I can emulate a similar motor performance as with AccelStepper. Which tells me AccelStepper is choosing a "bad" step interval delay (at least for this particular motor) when I target speeds ~400 or lower?

I was actually looking for a belt that would work with the camera gear ratio (0.8 ), but I haven't found a source yet :frowning:

marshallworrall:
Looking at the AccelStepper library I don't see any functions to allow me to define delay between step intervals.

That does not surprise me. The whole purpose of the library is to do that for you :slight_smile:

You specify the speed and it takes care of the details.

However, as I said earlier, I can't think why the AccelStepper library should cause your motor to run roughly when your/my simple code does not. Maybe @MarkT could apply his more extensive knowledge to that issue?

...R