Multiple steppers, speed decreasing with number of motors in operation.

Hi
I have 7 belt driven linear actuators ,connected to NEMA 17 stepper motors (1.8° - 1702HS133A - 44oz - 1.33A) driven by easydrivers, which are powered (in parallel) by a 24V 15A power supply and controlled by an arduino MEGA.

I am running the code below, what I am observing is that the running speeds of the individual motors seems to be inversely proportional to the number of motors running. This is having the effect that when all 7 are running its too slow for the intended purpose (it will be a horse racing type game)

I wondered if it was power supply related so I have connected one of the motors to a seperate power supply, however that motor still operates at the same speed as the others.

Any suggestions on how to speed these up?
Thanks

#include <AccelStepper.h>

AccelStepper stepper1(AccelStepper::DRIVER, 26, 27);// pin 26 = step, pin 27 = direction Stepper 1 
AccelStepper stepper2(AccelStepper::DRIVER, 28, 29);// pin 28 = step, pin 29 = direction Stepper 2 
AccelStepper stepper3(AccelStepper::DRIVER, 30, 31);// pin 30 = step, pin 31 = direction Stepper 3 
AccelStepper stepper4(AccelStepper::DRIVER, 32, 33);// pin 32 = step, pin 33 = direction Stepper 4 
AccelStepper stepper5(AccelStepper::DRIVER, 34, 35);// pin 34 = step, pin 35 = direction Stepper 5 
AccelStepper stepper6(AccelStepper::DRIVER, 36, 37);// pin 36 = step, pin 37 = direction Stepper 6 
AccelStepper stepper7(AccelStepper::DRIVER, 38, 39);// pin 38 = step, pin 39 = direction Stepper 7 

// Define End and Start Switches
int ENDswtch1=15;int ENDswtch2=14;int ENDswtch3=2;int ENDswtch4=3;int ENDswtch5=4;int ENDswtch6=5;int ENDswtch7=6;
int STswtch1=7;int STswtch2=8;int STswtch3=9;int STswtch4=10;int STswtch5=11;int STswtch6=12;int STswtch7=13;
int StepperSleep=40; // Define Easydriver sleep pin

int StpprMAX=2000;
int StpprACC=9000;


void setup() {
  // put your setup code here, to run once:
  pinMode(ENDswtch1,INPUT);  pinMode(ENDswtch2,INPUT); pinMode(ENDswtch3,INPUT); pinMode(ENDswtch4,INPUT);  pinMode(ENDswtch5,INPUT); pinMode(ENDswtch6,INPUT); pinMode(ENDswtch7,INPUT);  
  pinMode(STswtch1,INPUT);  pinMode(STswtch2,INPUT); pinMode(STswtch3,INPUT); pinMode(STswtch4,INPUT);  pinMode(STswtch5,INPUT); pinMode(STswtch6,INPUT); pinMode(STswtch7,INPUT);  
  pinMode(StepperSleep, OUTPUT);
stepper1.setMaxSpeed(StpprMAX);  stepper1.setAcceleration(StpprACC);stepper2.setMaxSpeed(StpprMAX);  stepper2.setAcceleration(StpprACC);stepper3.setMaxSpeed(StpprMAX);  stepper3.setAcceleration(StpprACC);stepper4.setMaxSpeed(StpprMAX);  stepper4.setAcceleration(StpprACC);stepper5.setMaxSpeed(StpprMAX);  stepper5.setAcceleration(StpprACC);stepper6.setMaxSpeed(StpprMAX);  stepper6.setAcceleration(StpprACC);stepper7.setMaxSpeed(StpprMAX);  stepper7.setAcceleration(StpprACC);  
  
}

void loop() {
  // put your main code here, to run repeatedly:
//digitalWrite(StepperSleep, LOW);

if (digitalRead(STswtch1)==LOW || digitalRead(STswtch2)==LOW || digitalRead(STswtch3)==LOW || digitalRead(STswtch4)==LOW || digitalRead(STswtch5)==LOW ||digitalRead(STswtch6)==LOW || digitalRead(STswtch7)==LOW) // Checks if any of the Swans Aren't Home 
{digitalWrite(StepperSleep, HIGH);} // if these still a swan out there keep the drivers energised

if (digitalRead(STswtch1)==LOW) // Sends Swan 1 Home
 { stepper1.move(70000);stepper1.run();}
if (digitalRead(STswtch2)==LOW) // Sends Swan 2 Home
 { stepper2.move(70000);stepper2.run();}
if (digitalRead(STswtch3)==LOW) // Sends Swan 3 Home
 { stepper3.move(70000);stepper3.run();}
if (digitalRead(STswtch4)==LOW) // Sends Swan 4 Home
 { stepper4.move(70000);stepper4.run();}
if (digitalRead(STswtch5)==LOW) // Sends Swan 5 Home
 { stepper5.move(70000);stepper5.run();}
if (digitalRead(STswtch6)==LOW) // Sends Swan 6 Home
 { stepper6.move(70000);stepper6.run();}
if (digitalRead(STswtch7)==LOW) // Sends Swan 7 Home
 { stepper7.move(70000);stepper7.run();}

if (digitalRead(STswtch1)==HIGH && digitalRead(STswtch2)==HIGH && digitalRead(STswtch3)==HIGH && digitalRead(STswtch4)==HIGH && digitalRead(STswtch5)==HIGH &&digitalRead(STswtch6)==HIGH && digitalRead(STswtch7)==HIGH) // Checks if all the Swans Are Home 
{digitalWrite(StepperSleep, LOW);} // if all swans are home set drivers to sleep

  }

Please repost your code properly. Use ctrl-T in the editor to format it, copy and paste.

sorted the code formatting. thanks for the tip

You should continuously be calling stepper.run() in the loop, not just while a switch is pressed. You should also check the return value, as that tells you whether the motor has finished the move.

I don't think the easydriver can handle 1.3A/winding without overheating. To what value did you set the current limit?

You can save a lot of repeated code by using arrays:

#include <AccelStepper.h>


const byte StepperCount = 7;


AccelStepper Steppers[StepperCount] =
{
  {AccelStepper::DRIVER, 26, 27}, // pin 26 = step, pin 27 = direction Stepper 1
  {AccelStepper::DRIVER, 28, 29}, // pin 28 = step, pin 29 = direction Stepper 2
  {AccelStepper::DRIVER, 30, 31}, // pin 30 = step, pin 31 = direction Stepper 3
  {AccelStepper::DRIVER, 32, 33}, // pin 32 = step, pin 33 = direction Stepper 4
  {AccelStepper::DRIVER, 34, 35}, // pin 34 = step, pin 35 = direction Stepper 5
  {AccelStepper::DRIVER, 36, 37}, // pin 36 = step, pin 37 = direction Stepper 6
  {AccelStepper::DRIVER, 38, 39}  // pin 38 = step, pin 39 = direction Stepper 7
};


// Define End and Start Switches
const byte ENDswtches[StepperCount] = {15, 14, 2, 3, 4, 5, 6};
const byte STswtches[StepperCount] = {7, 8, 9, 10, 11, 12, 13};


int StepperSleep = 40; // Define Easydriver sleep pin


int StpprMAX = 2000;
int StpprACC = 9000;


void setup()
{
  // put your setup code here, to run once:
  for (byte i = 0; i < StepperCount; i++)
  {
    pinMode(ENDswtches[i], INPUT);
    pinMode(STswtches[i], INPUT);
    Steppers[i].setMaxSpeed(StpprMAX);
    Steppers[i].setAcceleration(StpprACC);
  }


  pinMode(StepperSleep, OUTPUT);
}


void loop()
{
  // put your main code here, to run repeatedly:


  // Give each stepper a chance to move
  for (byte i = 0; i < StepperCount; i++)
  {
    Steppers[i].run();
  }


  // If any aren't home, enable the drivers
  for (byte i = 0; i < StepperCount; i++)
  {
    if (digitalRead(STswtches[i]) == LOW) // Checks if any of the Swans Aren't Home
    {
      digitalWrite(StepperSleep, HIGH); // if these still a swan out there keep the drivers energised
      break; // Skip the rest of the loop
    }
  }


  // For any that ARE home, move them forward 7000 steps
  for (byte i = 0; i < StepperCount; i++)
  {
    if (digitalRead(STswtches[i]) == LOW) // Sends Swan 1 Home
    {
      Steppers[i].move(70000);
    }
  }


  // Checks if all the Swans Are Home
  for (byte i = 0; i < StepperCount; i++)
  {
    if (digitalRead(STswtches[i]) == LOW) // Checks if all the Swans Are Home
    {
      digitalWrite(StepperSleep, LOW); // if all swans are home set drivers to sleep
      break;
    }
  }
}

This style of code

void loop() {

   if (digitalRead(STswtch1)==LOW) // Sends Swan 1 Home
       { stepper1.move(70000);stepper1.run();}

}

means that the move position is being updated all the time. It only needs to be updated once for every button press. Maybe something like this. Note how the run() is called all the time

void loop() {

   if (digitalRead(STswtch1)==LOW) {
       if (stepper1.distanceToGo() == 0) { // only update position of stepper is stopped
            stepper1.move(70000);
       }
   }

   stepper1.run();
}

...R

a standard Arduino Uno is pretty limited for the use with multiple steppers. Creating step-dir-pulses for stepper-motors needs high-speed and tight timing.An Arduino Uno has "only" 16 MHz.
A teensy 3.5 has 120 MHz. A Teensy 4.0 has 600 MHz

Here is a demo of a teensy 3.5 running two stepper-motors at 160.000 steps / second

https://www.pjrc.com/teensystep-fast-stepper-control-library/

best regards Stefan

I've done some calcs on what RPMs I need to make this viable and I need a range between 26RPM and 80RPM
Is it possible that this would be unachievable with stepper motors?
Does anyone have any recommendations for using DC motors connected to belt driven actuators?

for stepper-motors specifiying rpm is not enough.
You also half to specify steps per revolution

80 rpm in fullstep-mode is 80 * 200 / 60 = 267 steps per second peace of cake

80 rpm in 1/32 step-mode is 80 * 200 * 32 / 60 = 267 steps per second peace of cake 8533 steps per second

with 7 stepper-motors = 59731 steps / second

unchewable for an arduino. Still a piece of cake for a teensy

best regards Stefan

johnwasser:
You can save a lot of repeated code by using arrays:

#include <AccelStepper.h>

const byte StepperCount = 7;

AccelStepper Steppers[StepperCount] =
{
 {AccelStepper::DRIVER, 26, 27}, // pin 26 = step, pin 27 = direction Stepper 1
 {AccelStepper::DRIVER, 28, 29}, // pin 28 = step, pin 29 = direction Stepper 2
 {AccelStepper::DRIVER, 30, 31}, // pin 30 = step, pin 31 = direction Stepper 3
 {AccelStepper::DRIVER, 32, 33}, // pin 32 = step, pin 33 = direction Stepper 4
 {AccelStepper::DRIVER, 34, 35}, // pin 34 = step, pin 35 = direction Stepper 5
 {AccelStepper::DRIVER, 36, 37}, // pin 36 = step, pin 37 = direction Stepper 6
 {AccelStepper::DRIVER, 38, 39}  // pin 38 = step, pin 39 = direction Stepper 7
};

// Define End and Start Switches
const byte ENDswtches[StepperCount] = {15, 14, 2, 3, 4, 5, 6};
const byte STswtches[StepperCount] = {7, 8, 9, 10, 11, 12, 13};

int StepperSleep = 40; // Define Easydriver sleep pin

int StpprMAX = 2000;
int StpprACC = 9000;

void setup()
{
 // put your setup code here, to run once:
 for (byte i = 0; i < StepperCount; i++)
 {
   pinMode(ENDswtches[i], INPUT);
   pinMode(STswtches[i], INPUT);
   Steppers[i].setMaxSpeed(StpprMAX);
   Steppers[i].setAcceleration(StpprACC);
 }

pinMode(StepperSleep, OUTPUT);
}

void loop()
{
 // put your main code here, to run repeatedly:

// Give each stepper a chance to move
 for (byte i = 0; i < StepperCount; i++)
 {
   Steppers[i].run();
 }

// If any aren't home, enable the drivers
 for (byte i = 0; i < StepperCount; i++)
 {
   if (digitalRead(STswtches[i]) == LOW) // Checks if any of the Swans Aren't Home
   {
     digitalWrite(StepperSleep, HIGH); // if these still a swan out there keep the drivers energised
     break; // Skip the rest of the loop
   }
 }

// For any that ARE home, move them forward 7000 steps
 for (byte i = 0; i < StepperCount; i++)
 {
   if (digitalRead(STswtches[i]) == LOW) // Sends Swan 1 Home
   {
     Steppers[i].move(70000);
   }
 }

// Checks if all the Swans Are Home
 for (byte i = 0; i < StepperCount; i++)
 {
   if (digitalRead(STswtches[i]) == LOW) // Checks if all the Swans Are Home
   {
     digitalWrite(StepperSleep, LOW); // if all swans are home set drivers to sleep
     break;
   }
 }
}

Thanks for this, but it doesn't seem to like it, all motors just go into a high frequency buzzing without moving. A note is that all the drivers are connected to the same sleep pin, but I cant decipher if thats whats causing the issue?

I guess the too high starting-frequency of the steps. Setup a longer accerelation or a lower acceleration

StefanL38:
for stepper-motors specifiying rpm is not enough.
You also half to specify steps per revolution

80 rpm in fullstep-mode is 80 * 200 / 60 = 267 steps per second peace of cake

80 rpm in 1/32 step-mode is 80 * 200 * 32 / 60 = 267 steps per second peace of cake 8533 steps per second

with 7 stepper-motors = 59731 steps / second

unchewable for an arduino. Still a piece of cake for a teensy

best regards Stefan

Thanks for this, I just realised Easydriver defaults to 1/8th stepping, so I've set one to full step and now it races along. Just need to wire up the others and I'll see if it works nicer.
Thanks ]