Stepper "wigs out" only at particular step rates (300 - 325 steps/s or so)

Greetings,

First post. Please be gentle.

I have some experience with electronics, software development, and robotics but have never programmed a stepper before.

Motor: Nema 17 2A Bipolar 59Ncm motor from STEPPERONLINE on Amazon.
Driver: DRV8825 module without heat sink.
Controller: Arduino Uno R3

Schematic:

Driver is configured for no micro-stepping.

Arduino libraries: None (I had various issues with some popular libraries so I decided to root cause by implementing my own very basic control code (below))

Issue: I can step the motor at various speeds in either direction. However, if I try to step at PARTICULAR rates, the motor "wigs out" and for a moment it changes direction by itself a few times before getting back on track going the right direction. Obviously this messes up repeatability.

The step rate range that seems to cause issues is around 300 steps/s. Slower than that works fine and faster than 325 steps/s or so works fine.

I took some videos of the issue but I don't know how to upload those.

I wrote a simple program to move the motor a number of steps that was input by the user over serial and the motor will accelerate from 0 steps/s up to a maximum rate (1000 steps/s) during the movement. Then, it waits for input again. In this code, the issue occurs if I set minVelStepsPerS = 0. But if I set minVelStepsPerS = 350, velocity starts at 350 and goes up from there and the issue does not occur.

Note that the code only sets the DIR pin once before the stepping loop starts. I have read that the DRV8825 can have issues if you change the direction pin and then too quickly pulse the step pin. That should not be the issue here. I also have a default wait of 1000 uS after changing the DIR pin.

Here is the code:

#include <Arduino.h>

#define stepPin 3
#define dirPin 2

static const int minVelStepsPerS = 0;

unsigned int stepsPerRevolution = 200;
unsigned int defaultDelayTimeMicroS = 1000;

unsigned int curStepPos = 0;
unsigned int accelRateStepsPerSPerS = 100;
float curVelStepsPerS = minVelStepsPerS;
float maxVelStepsPerS = 1000;

void setup() {
  Serial.begin(9600);

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  digitalWrite(dirPin, HIGH);
  digitalWrite(stepPin, LOW);
}

void stepNumStepsWithAccel(int relSteps)
{
  if (relSteps == 0)
  {
    return;
  }

  // Set direction
  if (relSteps > 0)
  {
    digitalWrite(dirPin, HIGH);
  }
  else
  {
    digitalWrite(dirPin, LOW);
  }

  // Wait for direction pin to be set
  delayMicroseconds(defaultDelayTimeMicroS);

  // Set a vel > 0
  if (curVelStepsPerS == 0)
  {
    curVelStepsPerS += accelRateStepsPerSPerS;
  }

  // Get the current timestamp
  unsigned long lastTimeUs = micros();
  unsigned long curTimeUs = lastTimeUs;

  for (int i = 0; i < abs(relSteps); i++)
  {
    // Compute delay timespan based on velocity
    unsigned int delayTimeUs = 1 / (curVelStepsPerS / 1000000);

    // Step once
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(delayTimeUs);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(delayTimeUs);

    // Update current timestamp
    curTimeUs = micros();

    // Compute delta timespan
    unsigned long deltaTimeUs = curTimeUs - lastTimeUs;

    // Update velocity
    if (curVelStepsPerS < maxVelStepsPerS)
    {
      curVelStepsPerS += accelRateStepsPerSPerS * (float)(deltaTimeUs / (float)1000000);
    }
    else
    {
      // Reached max velocity
      curVelStepsPerS = maxVelStepsPerS;
    }

    // Update last timestamp
    lastTimeUs = curTimeUs;
  }

  // Reset velocity
  curVelStepsPerS = minVelStepsPerS;
}

void loop() {
  // Listen for input
  if (Serial.available() > 0) 
  {
    // Read input
    String input = Serial.readString();
    int relSteps = input.toInt();

    // Step the motor as requested
    stepNumStepsWithAccel(relSteps);
  }
}

I added some debug output to the code to print out all of the computed delay values that it used for every iteration of the main loop. I plotted these values and they formed an expected exponential curve with no abnormalities. So, I think I am computing the delay correctly. It's something about using a delay in the range of 300 - 325 steps/s that causes the problem.

Reference voltage on the driver is set to about 0.58v so that should result in a current just over an amp which should be fine.

I also measured the heat coming off of the driver with a FLIR camera and during my testing it did not rise above around 53 degrees C without heat sink.

Any ideas?

Thanks!

Please post datasheet links for the stepper and its power supply. Until then, the result sounds fully normal.

Thanks for responding. Datasheets are:

Motor:

Driver:

PSU:
Random 12V DC 1.2A wall wart PSU from my garage.

Can you please point me in the right direction to resources to help me learn why this is normal? I'm pretty surprised by the result.

Thx!

What stepper current is the driver set for? That PSU might bottom out. 2 amp stepper and adriver versus 1.2 Amps.
Have You measured the 12 volt while trying to run the motor?

That sounds like a resonance phenomenon. To avoid the problem change the motor mount to change the resonant frequency, avoid using the step rates that cause it, or use microstepping.

1 Like

+1 for possible resonance. One technique that we've used to deal with it is to set the motor starting speed above the resonance speed. However, this requires a stepper controller that lets you set a non-zero starting speed.

Regarding the PSU, I increased to a 5A PSU but that did not help. I have not measured current yet because I don't have a good enough multimeter (yet).

Regarding resonance, I read a little bit about it but I'm not sure this is resonance. When the issue occurs, it is an extreme amount of error. The shaft will suddenly move to several dozens of steps off target, not just 1 or 2. For example, a single movement of one rotation will result in an error of up to about 90 degrees (~50 steps). Also, it happens regardless of the motor mount. Right now it's just taped to my desk but it also happens when I hold the motor in my hand.

I turned on 1/2 step micro-stepping and the problem went away. I would like to root cause it though as I'd like to be able to run the motor at "full" speed.

I uploaded some youtube videos demonstrating when the problem does and does not happen:

Starting at 350 steps/s, no issue:

Starting at 0 steps/s, issue occurs:

Thanks all.

I am, especially if microstepping solved the problem. Have fun!

Would resonance cause the amount of error in the video I linked? If so, oh well I guess.

Thanks!

Absolutely. The stepper isn't mounted on anything, and can react wildly at resonance.

The mounting plate is there for a good reason.

Gotcha. Thanks. Learn something new every day. :+1: