Multiple Steppers running simultaneously at different speeds

Hi,

I have done a bit of research but am still having some difficulty with this. I am new to arduinos and programming.

I Need to build a test fixture for work and don’t have a ton of time to figure everything out on my own.

What I need is to run 8 stepper motors at the same time, however at different speeds, I also need to be able to stop any one particular motor at any point (other motors can also be stopped at this point)

The items at my disposal are:
Arduino Uno
Arduino Mega
Several A3967 microstepping drivers
Several L298N Motor Control Modules
Nema 17 Stepper motors: http://cncsuperstore.com/index.php?route=product/product&product_id=60

Ideally I would like to use one Arduino Uno, and 8 Drivers

I would also like to be able to set the speed in RPM for each motor

The motors would need to be run indefinitely

This is the bit of code that I found to be the close to my application, however I cant make much of it out, especially because it refers to the accelstepper library. I do not need to vary the acceleration, I do not need to constantly switch rotation, and I need to be able to input my speed as RPM

CODE #1

#include <AccelStepper.h>

// Define two steppers and the pins they will use
AccelStepper stepper1(1, 9, 8);
AccelStepper stepper2(1, 7, 6);

int pos1 = 3600;
int pos2 = 5678;

void setup()
{  
 stepper1.setMaxSpeed(3000);
 stepper1.setAcceleration(1000);
 stepper2.setMaxSpeed(2000);
 stepper2.setAcceleration(800);
}

void loop()
{
 if (stepper1.distanceToGo() == 0)
 {
       pos1 = -pos1;
   stepper1.moveTo(pos1);
 }
 if (stepper2.distanceToGo() == 0)
 {
   pos2 = -pos2;
   stepper2.moveTo(pos2);
 }
 stepper1.run();
 stepper2.run();
}

This is another bit of code that is close to what I need to do. However I also do not need the acceleration variable, or the reverse, and I need to set the speed to a constant RPM variable for each motor.
CODE #2
<

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper1 (1,3,2); // Defaults to 4 pins on 2, 3, 4, 5
AccelStepper stepper2 (1,5,4); // Defaults to 4 pins on 2, 3, 4, 5

void setup()
{ 
}

void checkStepper(AccelStepper &astepper)
{ if (astepper.distanceToGo() == 0) {
// Random change to speed, position and acceleration
// Make sure we dont get 0 speed or accelerations

astepper.moveTo(rand() % 12800);
astepper.setMaxSpeed((rand() % 3200) + 1);
astepper.setAcceleration((rand() % 6400) + 1); }


}

void loop()
{
checkStepper(stepper1) ;
checkStepper(stepper2) ;
stepper1.run();
stepper2.run(); 
}

The bit of code that I do understand is the basic stepper example from the arduino library. However the A3967 drivers only use two pins (this code worked with the L298N driver, because it uses 4 pins) However it is obviously for one stepper only, and my understanding that in order to drive two steppers I need to use the AccelStepper linbrary.

CODE #3
<

#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;         // number of steps the motor has taken

void setup() {
 // initialize the serial port:
 Serial.begin(9600);
}

void loop() {
 // step one step:
 myStepper.step(100);
 Serial.print("steps:");
 Serial.println(stepCount);
 stepCount++;
 delay(500);
}

I will continue to work on this and will update if I make any progress, however I would really appreciate any input

Thanks

Peter

Your motors require 1.4 amps and the A3967 cannot provide that. A better choice would be the Pololu DRV8825.

If you want to control 8 motors it would not really be practical with L298 drivers. They need 4 connections to the Arduino for each motor and they also impose a higher computation load on the Arduino.

The specialized stepper drivers can also limit the current to protect the motor and can therefore use higher voltages for better performance.

You don't need to use the acceleration features of the AccelStepper library if you don't need them

With a Pololu DRV8825 or equivalent you could use the code in the second example in this Simple Stepper Code to run several motors without any library.

One thing you have not said is whether there is a need for careful coordination between the moves - for example stepperA move 237 steps in the same time that stepperB moves 113 steps. The AccelStepper library is not intended for that.

For independent control of several motors it is absolutely essential that the delay() function is never used.

One thing that might be a limiting factor is the maximum combined number of steps per second - maybe a 16MHz Arduino cannot work fast enough.

...R
Stepper Motor Basics

First, please use the “</>” button three times to encapsulate each your three sketches.

Q1) How big a power supply, ? volts & ? amps, do you have?

Q2) Do you know how to wire the Steppers → to the Motor Board → to the Arduino?

Q3) How are you going to “set the speed” for each Stepper?

Q4) How many Digital I/O Pins will you need to control 8 Stepper Motors?

Pete123:
I also do not need the acceleration variable, or the reverse, and I need to set the speed to a constant RPM variable for each motor.

Do you know if your steppers will run at the speed you need without acceleration?

I've found it's important to accelerate stepper motors unless they're used at low speeds.

Robin2:
Your motors require 1.4 amps and the A3967 cannot provide that. A better choice would be the Pololu DRV8825.

If you want to control 8 motors it would not really be practical with L298 drivers. They need 4 connections to the Arduino for each motor and they also impose a higher computation load on the Arduino.

The specialized stepper drivers can also limit the current to protect the motor and can therefore use higher voltages for better performance.

You don't need to use the acceleration features of the AccelStepper library if you don't need them

With a Pololu DRV8825 or equivalent you could use the code in the second example in this Simple Stepper Code to run several motors without any library.

One thing you have not said is whether there is a need for careful coordination between the moves - for example stepperA move 237 steps in the same time that stepperB moves 113 steps. The AccelStepper library is not intended for that.

For independent control of several motors it is absolutely essential that the delay() function is never used.

One thing that might be a limiting factor is the maximum combined number of steps per second - maybe a 16MHz Arduino cannot work fast enough.

...R
Stepper Motor Basics

Hi, thank you for the reply.

I may be misunderstanding the motor specs, however the motors do run well with the A3967 drivers however the drivers get a bit hot... so maybe not?

Also there is absolutely no need for the careful coordination between motors, all they have to do is run at roughly 20 RPM, (roughly being a relative term, if I can physically count that all the motors run at 20rpm thats good enough)

Sorry, the power supply I am using is:

E3631A 80W Triple Output Power Supply, 6V, 5A & ±25V, 1A

mrsummitville:
First, please use the “</>” button three times to encapsulate each your three sketches.

Q1) How big a power supply, ? volts & ? amps, do you have?

Q2) Do you know how to wire the Steppers → to the Motor Board → to the Arduino?

Q3) How are you going to “set the speed” for each Stepper?

Q4) How many Digital I/O Pins will you need to control 8 Stepper Motors?

mrsummitville:
First, please use the “</>” button three times to encapsulate each your three sketches.

Q1) How big a power supply, ? volts & ? amps, do you have?

Q2) Do you know how to wire the Steppers → to the Motor Board → to the Arduino?

Q3) How are you going to “set the speed” for each Stepper?

Q4) How many Digital I/O Pins will you need to control 8 Stepper Motors?

  1. This is the power supply: E3631A 80W Triple Output Power Supply, 6V, 5A & ±25V, 1A

  2. This is the example I followed for wiring : Easy Driver Examples

  3. No idea, but I need to input the speed for each motor in RPM

  4. 16 pins total (2 per driver?) I will use all the digital pins and some of the analog pins (as digital out, if that is possible?)

Pete123:
I may be misunderstanding the motor specs, however the motors do run well with the A3967 drivers however the drivers get a bit hot... so maybe not?

If you have set the current limit within the range allowed by the A3967 and if the motors perform OK keep going. It is normal for stepper drivers and stepper motors to run hot - uncomfortable to touch.

...R

Hi,

Robin I have tried modifying your code to include a second stepper. I took out the button function and tried to simplify it as much as possible however I am still having trouble grasping the millis() concept.

At this point neither one of my motors is moving. I think that I am not following the correct loop structure in order to correctly toggle the output pins between HIGH and LOW for the specified motor.

At one point I did get the motors to turn at different speeds by messing with the code, but I could never get it to where I could set the speed of one motor without effecting the speed of the other motor.

byte directionPin_1 = 3;
byte stepPin_1 = 4;

byte directionPin_2 = 8;
byte stepPin_2 = 9;



unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps_1 = 25; 
unsigned long millisBetweenSteps_2 = 25; 

void setup() { 

  Serial.begin(9600);

  pinMode(directionPin_1, OUTPUT);
  pinMode(stepPin_1, OUTPUT);
  
  pinMode(directionPin_2, OUTPUT);
  pinMode(stepPin_2, OUTPUT);


  
}

void loop() { 
	  digitalWrite(directionPin_1, HIGH);
          digitalWrite(directionPin_2, HIGH);
	  
          curMillis = millis();

}	
void Step_1() {
  
  if (curMillis - prevStepMillis >= millisBetweenSteps_1) {
		prevStepMillis += millisBetweenSteps_1;
		digitalWrite(stepPin_1, HIGH);
		
  }
  if (curMillis - prevStepMillis >= millisBetweenSteps_2) {
		prevStepMillis += millisBetweenSteps_2;
		digitalWrite(stepPin_1, LOW);
		
	}
}
void Step_2() {
  
  if (curMillis - prevStepMillis >= millisBetweenSteps_1) {
		prevStepMillis += millisBetweenSteps_1;
		digitalWrite(stepPin_2, HIGH);
		
  }
  if (curMillis - prevStepMillis >= millisBetweenSteps_2) {
		prevStepMillis += millisBetweenSteps_2;
		digitalWrite(stepPin_2, LOW);
		
	}
}

I won't be able to deal with this until tomorrow - I have bookmarked it.

...R

As far as pins go, a Mega 2650 would fill the bill.

You really need to specify your requirement. What is the maximum RPM for the motor, and how many steps per revolution? Multiply the two and see how many steps per second to determine how practical this will be.

Paul__B:
As far as pins go, a Mega 2650 would fill the bill.

You really need to specify your requirement. What is the maximum RPM for the motor, and how many steps per revolution? Multiply the two and see how many steps per second to determine how practical this will be.

Hi,

The motor is 1.8 step angle, so 200 steps/revolution, that said I know that I can write an equation that will convert the specified RPM to the mS time between steps (I have not included that in the code yet) The max rated RPM in in the hundreds, the RPM I am looking to run is only from 10 to 60. I am also currently writing the code for only 3 steppers for the sake of simplicity, 8 steppers is how many I will actually need to run. The only thing I am currently looking to do is run 3 steppers at the same time, each at a different speed. I am hoping it will not be too difficult to modify it to include 8 steppers.

I can use the Mega however I do believe that there are in fact 16 output pins on the arduino UNO that can be used as digital out, I could be wrong?

Pete123:
Robin I have tried modifying your code to include a second stepper.

The code in Reply #8 is nearly correct. You need to add these two lines to loop() so that it calls yoour step functions

Step_1();
Step_2();

and you need to have a separate value of prevStepMillis for each motor.

...R

OK, so 60 RPM is of course, one revolution per second, so 200 steps, 5 ms per step.

If you can allow for even numbers of milliseconds, my state machine code for that is quite straightforward.

I mentioned the mega 2560 on the basis of requiring four pins per stepper. If you use a proper controller with only STEP and DIR pins, 16 would be fine!

(Do you need DIR anyway?)

Paul__B:
OK, so 60 RPM is of course, one revolution per second, so 200 steps, 5 ms per step.

If you can allow for even numbers of milliseconds, my state machine code for that is quite straightforward.

I mentioned the mega 2560 on the basis of requiring four pins per stepper. If you use a proper controller with only STEP and DIR pins, 16 would be fine!

(Do you need DIR anyway?)

oh Yah, sorry I forgot to mention that I would need to be able to switch directions if necessary. By even number of seconds do you mean whole numbers? So I would not be able to change "unsigned long" to a float then?