At the moment it can get to 160RPM without starting to stall with the load attached. Is there likely to be a way to get this motor to run happily at 500RPM, maybe with a controller change if needed?
Or, is it likely we need to more to a DC brushless style motor?
Possibly, but most likely not with that motor driver.
Stepper speed and response is greatly improved by using as high a supply voltage as possible (e.g. 36 to 48V). The stepper driver you have cannot tolerate that, and can't supply the continuous rated motor current (1.68 A) either.
Recently stepper speed was tested here. AxelStepper library was use as well as a TB6600 driver but at 12 volt. The maximum speed was reached at 4000 pulses per second. The acceleration could be set to any value without trouble. The stepper was running without load. Common steppers use 200 steps per rev at singlestep. 4000 pulses / 200 steps per rev gave me some 20 RPM...
Using a for loop, puls, short delay and next pulse will give more speed but at some point the acceleration becomes too high.
stepper-motor-drivers have a current-limiting which is adjusted to the stepper-motors current.
A to high current is what a stepper-motor would make the motor overheat.
If the current is limited to the correct value everything is good.
using the stepper-motor-driver with a higher voltage increases torque.
Each coil is an inductivity which slows down rising of the current.
Higher voltages have the effect of rising the current faster.
The stepper-motor switches off the voltage at the right time so the current stays in the adjusted range.
Driving this stepper-motor from 2,8V as the specs say results in a low torque.
You should use a stepper-motor-driver which is rated for a maximum of at least 2A better 3A or more to stay away from the maximum-limit of the stepper-motor-driver. And then adjust the current-limiting of the stepper-motor-driver to 1,6A to stay a little bit below the max-current of the stepper-motor
Larry raises an important question. Do you need a stepper for high precision positioning, or is it just what you have? Steppers can be run fast but as other replies have mentioned you need a high voltage and a good driver. You might be better off using a digital driver such as the DM542
On the other hand if speed is your main requirement then a stepper is a poor choice, a DC motor would work better, brushed or brushless.
Correct. Thanks. Rev per second or rev per minute.... That's a big difference. A factor 60...
Note that micro stepping eats pulses but produces less RPM.....
Hey, sorry for the delay. The current code doesn't have any acceleration on it.
// ARDUINO PINS
#define STEP_PIN 8
#define DIRECTION_PIN 9
#define M0 4
#define M1 5
#define ENB 6
#define RST_PIN 12
// SPEED UPPER THRESHOLD (CHANGE IF NEEDED)
#define MAXthreshold 500 // upper threshold for allowed speed (RPM)
// PROGRAM VARIABLES (DO NOT CHANGE)
unsigned long LastStepTime = 0;
unsigned long CurrentTime = 0;
bool MotorState = false;
float MicroStepTime;
float StepsPerRev = 400.0; // ONLY CHANGE IF USING DIFFERENT STEPPER MOTOR - 0.9 deg step angle = 200 steps
float MicroSteps;
bool Direction = false;
void setup(){
Serial.begin(9600);
while (!Serial); // wait for serial connection
pinMode(STEP_PIN, OUTPUT);
pinMode(DIRECTION_PIN, OUTPUT);
pinMode(M0, OUTPUT);
pinMode(M1, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(RST_PIN, INPUT_PULLUP);
digitalWrite(ENB, HIGH); // enable the stepper driver
digitalWrite(STEP_PIN, LOW);
digitalWrite(DIRECTION_PIN, Direction); // CHANGE IF WRONG DIRECTION
/* M0 M1 Res
* L L Full step
* H L Half step
* Float L 1/4 step
* L H 1/8 step
* H H 1/16 step
* Float H 1/32 step
*/
digitalWrite(M0, HIGH);
digitalWrite(M1, LOW);
Serial.println("--------------------------");
Serial.println("Enter desired speed in RPM");
Serial.println("--------------------------");
while(!Serial.available()); // wait for initial serial input
}
void loop(){
if (Serial.available()){ // if input to change motor speed break out of loop
serial_handler();
}
run_motor(MicroStepTime);
}
// Serial input handler
void serial_handler(){
float input = Serial.parseInt();
//Serial.println(input);
// check if input is within preset threshold (update "MAXthreshold" at top if needed)
if (input == -1){
Serial.println("Motor direction changed");
Direction = !Direction; // flip the direction
digitalWrite(DIRECTION_PIN, Direction);
}
else if (input < 0 || input > MAXthreshold){
// print Error MSG
Serial.print(input);
Serial.print(" is out of threshold, adjust code 'MAXthreshold' variable or enter speed between 0-");
Serial.println(MAXthreshold);
}
else if (input == 0){
MotorState = false;
Serial.println("Turning motor off");
}
else if(input > 0 && input < MAXthreshold){
/* M0 M1 Res
* L L Full step
* H L Half step
* Float L 1/4 step
* L H 1/8 step
* H H 1/16 step
* Float H 1/32 step
*/
if (input <= 60){
MicroSteps = 8;
digitalWrite(M0, LOW);
digitalWrite(M1, HIGH);
}
else if (input <= 120){
MicroSteps = 2;
digitalWrite(M0, HIGH);
digitalWrite(M1, LOW);
}
else if (input <= 240){
MicroSteps = 1;
digitalWrite(M0, LOW);
digitalWrite(M1, LOW);
}
MicroSteps = 1;
digitalWrite(M0, LOW);
digitalWrite(M1, LOW);
MicroStepTime = (1000000/(StepsPerRev * MicroSteps)/(input / 60));
MicroStepTime = MicroStepTime / 2;
Serial.print("Changing speed to ");
Serial.print(input);
Serial.print(" RPM, with delay of ");
Serial.print(MicroStepTime);
Serial.println("(micro seconds)");
MotorState = true;
//run_motor_debug();
}
}
// run stepper motor at set speed
void run_motor(float step_time){
while(MotorState){
CurrentTime = micros();
if ((CurrentTime - LastStepTime) > step_time){
LastStepTime = CurrentTime; // update timers
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds((step_time * 0.9)/2); // 0.9 to factor in 0.1us processing time
digitalWrite(STEP_PIN, LOW);
delayMicroseconds((step_time * 0.9)/2);
}
if (Serial.available()){ // if input to change motor speed break out of loop
break;
}
}
}
// debug function to time one full revolution
void run_motor_debug(float step_time){
unsigned long steps = StepsPerRev * MicroSteps;
Serial.print("Micro steps per revolution: ");
Serial.println(steps);
unsigned long StartTime = micros();
for (unsigned long i = 0; i <= steps; i++){ // iterate through one revolution
CurrentTime = micros();
if ((CurrentTime - LastStepTime) > step_time){
LastStepTime = CurrentTime; // update timers
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds((step_time * 0.9)/2); // 0.9 to factor in 0.1us processing time
digitalWrite(STEP_PIN, LOW);
delayMicroseconds((step_time * 0.9)/2);
}
}
unsigned long EndTime = micros();
Serial.print("Time in microseconds for one revolution: ");
Serial.println(EndTime - StartTime);
}
Using slow calculating float type varibles for stepping timing is not worth analyzing in my opinion. It might work for some short time after start but later microseconds will be lost. Use unsigned long for millis and micros.