10 Stepper Motor System

Hi, I’m building an automated winch system with stepper motors. I’m waiting on the last of the hardware for the winches coming in later this week but I tested it hooking one motor in as the Trav1 motor and it wasn’t quite working properly. It would boot up, wait about 10 seconds, twitch, twitch again after a few seconds, then after about 20 seconds or so would start rotating at approximately 15 rpm. I’m just curious what’s causing this. This is my first time using arduino so I apologize if my code is sloppy. I have in my code multiple acceleration, max speed, and target positions and I’m not quite sure that’s how the library works. If you see me doing something stupid in my code, please let me know. I considered putting a variable in for the moveTo() command and just assigning different variable for each cue. Maybe the dumb, I don’t know. The system essentials runs max travels and lifts, the ends in a position. Then once each toggle button is pressed (cue 1, cue 2, cue 3, cue 4) the motors either go to a target position or run a repeating sequence. Currently I can’t even get 1 motor to run the setup sequence correctly.

10 Adafruit Nema 17 Stepper Motors
5 Adafruit Motorshield V2.3
Ardunino Uno

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_MotorShield DualDrive_1(0x60); //DS Axes
Adafruit_MotorShield DualDrive_2(0x61); //MDS Axes
Adafruit_MotorShield DualDrive_3(0x62); //MS Axes
Adafruit_MotorShield DualDrive_4(0x63); //MUS Axes
Adafruit_MotorShield DualDrive_5(0x64); //US Axes

//Motor Assignment

Adafruit_StepperMotor *Trav_1 = DualDrive_1.getStepper(200, 1);
Adafruit_StepperMotor *Lift_1 = DualDrive_1.getStepper(200, 2);
Adafruit_StepperMotor *Trav_2 = DualDrive_2.getStepper(200, 1);
Adafruit_StepperMotor *Lift_2 = DualDrive_2.getStepper(200, 2);
Adafruit_StepperMotor *Trav_3 = DualDrive_3.getStepper(200, 1);
Adafruit_StepperMotor *Lift_3 = DualDrive_3.getStepper(200, 2);
Adafruit_StepperMotor *Trav_4 = DualDrive_4.getStepper(200, 1);
Adafruit_StepperMotor *Lift_4 = DualDrive_4.getStepper(200, 2);
Adafruit_StepperMotor *Trav_5 = DualDrive_5.getStepper(200, 1);
Adafruit_StepperMotor *Lift_5 = DualDrive_5.getStepper(200, 2);

//Motor Step Parameters

// Trav 1
void forwardstep1() {  
  Trav_1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {  
  Trav_1->onestep(BACKWARD, SINGLE);
}

// Lift 1
void forwardstep2() {  
  Lift_1->onestep(FORWARD, SINGLE);
}
void backwardstep2() {  
  Lift_1->onestep(BACKWARD, SINGLE);
}

// Trav 2
void forwardstep3() {  
  Trav_2->onestep(FORWARD, SINGLE);
}
void backwardstep3() {  
  Trav_2->onestep(BACKWARD, SINGLE);
}

// Lift 2
void forwardstep4() {  
  Lift_2->onestep(FORWARD, SINGLE);
}
void backwardstep4() {  
  Lift_2->onestep(BACKWARD, SINGLE);
}

// Trav 3
void forwardstep5() {  
  Trav_3->onestep(FORWARD, SINGLE);
}
void backwardstep5() {  
  Trav_3->onestep(BACKWARD, SINGLE);
}

// Lift 3
void forwardstep6() {  
  Lift_3->onestep(FORWARD, SINGLE);
}
void backwardstep6() {  
  Lift_3->onestep(BACKWARD, SINGLE);
}

// Trav 4
void forwardstep7() {  
  Trav_4->onestep(FORWARD, SINGLE);
}
void backwardstep7() {  
  Trav_4->onestep(BACKWARD, SINGLE);
}

// Lift 4
void forwardstep8() {  
  Lift_4->onestep(FORWARD, SINGLE);
}
void backwardstep8() {  
  Lift_4->onestep(BACKWARD, SINGLE);
}

// Trav 5
void forwardstep9() {  
  Trav_5->onestep(FORWARD, SINGLE);
}
void backwardstep9() {  
  Trav_5->onestep(BACKWARD, SINGLE);
}

// Lift 5
void forwardstep10() {  
  Lift_5->onestep(FORWARD, SINGLE);
}
void backwardstep10() {  
  Lift_5->onestep(BACKWARD, SINGLE);
}

// AccelStepper Parameters

AccelStepper Trav1(forwardstep1, backwardstep1);
AccelStepper Lift1(forwardstep2, backwardstep2);
AccelStepper Trav2(forwardstep3, backwardstep3);
AccelStepper Lift2(forwardstep4, backwardstep4);
AccelStepper Trav3(forwardstep5, backwardstep5);
AccelStepper Lift3(forwardstep6, backwardstep6);
AccelStepper Trav4(forwardstep7, backwardstep7);
AccelStepper Lift4(forwardstep8, backwardstep8);
AccelStepper Trav5(forwardstep9, backwardstep9);
AccelStepper Lift5(forwardstep10, backwardstep10);

// Button Pin Assignments

const int Button1=2;
const int Button2=3;
const int Button3=4;
const int Button4=5;
const int Button5=6;
const int Button1LED=7;
const int Button2LED=8;
const int Button3LED=9;
const int Button4LED=10;
const int Button5LED=11;
const int JoyButton=12;
const int JoyX=A2;
const int JoyY=A3;

//Variables

int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;

void setup()
{
  DualDrive_1.begin();
  DualDrive_2.begin();
  DualDrive_3.begin();
  DualDrive_4.begin();
  DualDrive_5.begin();

  delay(50);

// Buttion I/O Assignment

  pinMode(Button1,INPUT_PULLUP);
  pinMode(Button2,INPUT_PULLUP);
  pinMode(Button3,INPUT_PULLUP);
  pinMode(Button4,INPUT_PULLUP);
  pinMode(Button5,INPUT_PULLUP);
  pinMode(JoyButton,INPUT_PULLUP);
  pinMode(JoyX,INPUT);
  pinMode(JoyY,INPUT);

// Button LED Assignment
  pinMode(Button1LED,OUTPUT);
  pinMode(Button2LED,OUTPUT);
  pinMode(Button3LED,OUTPUT);
  pinMode(Button4LED,OUTPUT);
  pinMode(Button5LED,OUTPUT);
  
  Serial.begin(9600);

//Turn All Buttons Red

  digitalWrite(Button1LED,LOW);
  digitalWrite(Button2LED,LOW);
  digitalWrite(Button3LED,LOW);
  digitalWrite(Button4LED,LOW);

  delay(50);

// Set Zeroes

  Trav1.setCurrentPosition(0);
  Lift1.setCurrentPosition(0);
  Trav2.setCurrentPosition(0);
  Lift2.setCurrentPosition(0);
  Trav3.setCurrentPosition(0);
  Lift3.setCurrentPosition(0);
  Trav4.setCurrentPosition(0);
  Lift4.setCurrentPosition(0);
  Trav5.setCurrentPosition(0);
  Lift5.setCurrentPosition(0);

  delay(50);

// Traverse Positive Extents

  Trav1.setMaxSpeed(75.0);
  Trav1.setAcceleration(50.0);
  Trav1.moveTo(2400);

  Trav2.setMaxSpeed(75.0);
  Trav2.setAcceleration(50.0);
  Trav2.moveTo(2400);

  Trav3.setMaxSpeed(75.0);
  Trav3.setAcceleration(50.0);
  Trav3.moveTo(2400);

  Trav4.setMaxSpeed(75.0);
  Trav4.setAcceleration(50.0);
  Trav4.moveTo(2400);

  Trav5.setMaxSpeed(75.0);
  Trav5.setAcceleration(50.0);
  Trav5.moveTo(2400);

// Run Traverse Positive Extents

  Trav1.run();
  Trav2.run();
  Trav3.run();
  Trav4.run();
  Trav5.run();
  
  delay(12000);

//Send Traverse to CL

  Trav1.setMaxSpeed(75.0);
  Trav1.setAcceleration(50.0);
  Trav1.moveTo(1200);

  Trav2.setMaxSpeed(75.0);
  Trav2.setAcceleration(50.0);
  Trav2.moveTo(1200);

  Trav3.setMaxSpeed(75.0);
  Trav3.setAcceleration(50.0);
  Trav3.moveTo(1200);

  Trav4.setMaxSpeed(75.0);
  Trav4.setAcceleration(50.0);
  Trav4.moveTo(1200);

  Trav5.setMaxSpeed(75.0);
  Trav5.setAcceleration(50.0);
  Trav5.moveTo(1200);

// Run Traverse to CL

  Trav1.run();
  Trav2.run();
  Trav3.run();
  Trav4.run();
  Trav5.run();

  delay(6000);

// Check Lift Positive Extents

  Lift1.setMaxSpeed(75.0);
  Lift1.setAcceleration(50.0);
  Lift1.moveTo(1450);
  
  Lift2.setMaxSpeed(75.0);
  Lift2.setAcceleration(50.0);
  Lift2.moveTo(1450);

  Lift3.setMaxSpeed(75.0);
  Lift3.setAcceleration(50.0);
  Lift3.moveTo(1450);

  Lift4.setMaxSpeed(75.0);
  Lift4.setAcceleration(50.0);
  Lift4.moveTo(1450);

  Lift5.setMaxSpeed(75.0);
  Lift5.setAcceleration(50.0);
  Lift5.moveTo(1450);

// Run Lift Positive Extents

  Lift1.run();
  Lift2.run();
  Lift3.run();
  Lift4.run();
  Lift5.run();

  delay(8000);

// Send Lifts to Zero

  Lift1.setMaxSpeed(75.0);
  Lift1.setAcceleration(50.0);
  Lift1.moveTo(0);
  
  Lift2.setMaxSpeed(75.0);
  Lift2.setAcceleration(50.0);
  Lift2.moveTo(0);

  Lift3.setMaxSpeed(75.0);
  Lift3.setAcceleration(50.0);
  Lift3.moveTo(0);

  Lift4.setMaxSpeed(75.0);
  Lift4.setAcceleration(50.0);
  Lift4.moveTo(0);

  Lift5.setMaxSpeed(75.0);
  Lift5.setAcceleration(50.0);
  Lift5.moveTo(0);

// Run Lifts to Zero

  Lift1.run();
  Lift2.run();
  Lift3.run();
  Lift4.run();
  Lift5.run();

  delay(8000);

// Send Traverse Spread

  Trav1.setMaxSpeed(75.0);
  Trav1.setAcceleration(50.0);
  Trav1.moveTo(0);

  Trav2.setMaxSpeed(75.0);
  Trav2.setAcceleration(50.0);
  Trav2.moveTo(2400);

  Trav3.setMaxSpeed(75.0);
  Trav3.setAcceleration(50.0);
  Trav3.moveTo(600);

  Trav4.setMaxSpeed(75.0);
  Trav4.setAcceleration(50.0);
  Trav4.moveTo(1800);

  Trav5.setMaxSpeed(75.0);
  Trav5.setAcceleration(50.0);
  Trav5.moveTo(1200);

// Run Traverse to Spread

  Trav1.run();
  Trav2.run();
  Trav3.run();
  Trav4.run();
  Trav5.run();

  delay(8000);
}

Without a schematic I can only guess but I think you are overloading the power supply. If you have more then one power supply are the grounds connected. I hope you are not using the 5 Volts from the arduino for this many motors, When those motors operate they create EMI. This forces you to keep the motor wires as far away from the ICs as possible. It is also possible the I2C is giving you problems, are you using 4.7K pull up resistors, best check. This response is to help you get started in finding the problem, not solve it for you. Good Luck & Have Fun! Gil

Please post a link to the datasheet for your stepper motors. I suspect the Adafruit motor shield is a poor choice for controlling a stepper motor as it is just a collection of H-bridges.

A specialized stepper motor driver can limit the current to protect the motor and thus can use a higher voltage motor power supply for better performance. It also significantly reduces the computational load on the Arduino which could be especially important if you want to control 10 motors.

What is the maximum number of stepper pulses per second that you will require when you add the requirements of all motors together?

...R Stepper Motor Basics Simple Stepper Code

also look up the AccelStepper library

You are calling delay(), so AccelStepper cannot do anything.

The AccelStepper library requires you to call the run() methods for all motors everytime round loop so each motor can progress. You'd need to do something similar in setup(), with while loops.

All run methods need to be called frequently with multiple motors moving.

I'm not quite sure on the pulses per second. Adafruit says that their Nema 17 works perfectly fine with the motorshield v2.3 with a max speed of 75rpm. So I doubt I'm overloading anything. I'm running the arduino off of a 12v power supply and the shields off a separate 20watt power supply. I see how the delay could cause issues. I'll put in while loops until the target position is reached instead of using delays. Unfortunately I don't schematics write down. I'm sort of building it as I go. I know that sounds bad, but it's relatively simple. Once I can get the motor to run the setup sequence correctly I'll move forward from there. But yeah, I'll try changing the delays sequences to whiles and post the results.

Thanks!

mattbrown2012: I'll put in while loops until the target position is reached instead of using delays.

WHILE loops are likely to have exactly the same effect as delay()

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

Adafruit says that their Nema 17 works perfectly fine with the motorshield v2.3 with a max speed of 75rpm.

But have you asked them if it can do that for 10 motors?

...R

I would like to recommend using PES-2605 stepper motor controller. You can stack up to 14 the controller on a single Arduino Uno. It supports various functions and very easy to use

That motorshield isn't a stepper driver. It can drive some types of stepper slowly, but DRV8825 boards are much more compact and cost-effective and can drive standard low-impedance steppers (which are usually the cheapest).

DC motor shields are only able to drive high impedance steppers (40 ohms or so). Low impedance steppers are designed only for chopper drivers like the DRV8825.