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!