Issue: Two motors at close but different speeds using AccelStepper library

Hi,

I’m trying to control the speed of two motors at constant speeds that are very close to one another. For example I’ve set one motor to be 500 pps and the other to be 503 pps. The two motors would rotate synchronously and not skip a beat. I only begin to see a drift in speeds when their respective speeds are 500 and 505 pps. This seems kind of odd, am I missing something obvious here?

Thanks!
Kellso

kellso: am I missing something obvious here?

I don't know about you, but we are. Your program code.

I suspect that if you want the motors to stay firmly in sync the AccelStepper library is not suitable.

Try making a counter that counts 500 * 503 = 251500 times per second (about once every 4 microsecs) and step one motor every 500 counts and step the other motor every 503 steps.

...R

No, this is a consequence of quantization of the step period to a whole number of timer counts.

Steppers are designed for position control, not accurate speed control, so this isn't normally a consideration.

Sounds like you need to use Bressenham's algorithm or something similar, or if this is a steering robot application, move your control loops to the position domain from the speed domain.

Steppers are designed for position control, not accurate speed control,

Huh?

What if I told you that the exact same property that makes steppers great for position control also makes steppers great for speed control?

If you feed a stepper motor with a 200hz clock, it will run at exactly 1.000 rpm, up to the precision of the crystal (or resonator) on your Arduino.

(to clarify for Europeans, 1.000 means one, not 1000)

Don't you mean 1,000 RPS? :)

Yes!

You are correct. 1,000 RPS, or 1.000 RPS depending on if you are in Europe or the USA.

Or 60 rpm, in both places. :)

(Assuming a 1.8-degree motor being driven full-step, of course)

Thanks for the help guys. And heres my code below.

#include <AccelStepper.h>

// Define some steppers and the pins the will use
AccelStepper motorX(1, 2, 5); //INTERFACE = 1 (DRIVER), STEP = pin 2, DIR = pin 5
AccelStepper motorY(1, 3, 6); //INTERFACE = 1 (DRIVER), STEP = pin 3, DIR = pin 6
AccelStepper motorZ(1, 4, 7); //INTERFACE = 1 (DRIVER), STEP = pin 4, DIR = pin 7
int max_speed = 1000;
float speed2_ratio = 1.01;
float speed3_ratio = .15;

// motor speed measured in counts per revolution
// stepper motor is
float motor1_speed = 500.0;

// set motor 2 speed
// int motor2_speed = motor1_speed * speed2_ratio;
float motor2_speed = 502.0;

// set motor 3
// int motor3_speed = motor1_speed * speed3_ratio;
int motor3_speed = 5;

void setup()
{
motorX.setMaxSpeed(max_speed);
motorX.setSpeed(motor1_speed);

motorY.setMaxSpeed(max_speed);
motorY.setSpeed(motor2_speed);

motorZ.setMaxSpeed(max_speed);
motorZ.setSpeed(motor3_speed);
}

void loop()
{
motorX.runSpeed();
motorY.runSpeed();
//motorZ.runSpeed();
Serial.print(motorX.speed());
}

kellso: Thanks for the help guys. And heres my code below.

Good to see you have a solution,

...R

Daenerys:

Steppers are designed for position control, not accurate speed control,

Huh?

What if I told you that the exact same property that makes steppers great for position control also makes steppers great for speed control?

Well yes, but most steppers are in 3D printers, CNC machines and the like where no position drift can be tolerated but a few percent of speed inaccuracy is neither here hor there. Given the system clock on many Arduinos is only 0.5% accurate anyway, speed accuracy isn't really a major priority.

If you want coordinated movement, programs like GRBL do the Bressenham's thing to keep multiple motors in strict lock-step. Alas AccelStepper library doesn't support that.

If you feed a stepper motor with a 200hz clock, it will run at exactly 1.000 rpm, up to the precision of the crystal (or resonator) on your Arduino.

(to clarify for Europeans, 1.000 means one, not 1000)