Poll
Question: 2 stepper motors running at SAME TIME - Arduino uno
2 stepper - 7 (70%)
Arduino uno - 3 (30%)
Total Voters: 10

Pages: [1]   Go Down
Author Topic: 2 stepper motors running at SAME TIME - Arduino uno  (Read 8647 times)
0 Members and 1 Guest are viewing this topic.
Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 43
Luv Life Live Life
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there,
Im trying to get two stepper motors to rotate at the same time. Im using two Sn754410NE drivers and an Uno Arduino. pins 2-5 go to stepper 1 and pins 8-11 goes to stepper 2. when i run the program (shown below) both steppers rotate but NOT AT THE SAME TIME:(. the first one rotates and then the second one rotates. is there a way to mod this program so BOTH STEPPERS RUN AT THE SAME TIME:). ANY HELP would be appreciated. thanks in advance. this is the code that im using (its basically from the samples, just modifies a bit):
CHEERS!!

#include <Stepper.h>

const int step_360 = 200;// 360 number of steps per/rev                              
// initialize the stepper library on pins 2-5 n 8-11
Stepper myStepper1(step_360,2,3,4,5);
Stepper myStepper2(step_360,8,9,10,11);      

void setup()
{
  // set the speed at 60 rpm:
  myStepper1.setSpeed(60);//left
  myStepper2.setSpeed(60);//right
  // initialize the serial port:
  Serial.begin(9600);
}
void loop()
{
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper1.step(step_360);
  myStepper2.step(step_360);
  delay(500);    
}
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46266
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
when i run the program (shown below) both steppers rotate but NOT AT THE SAME TIME
No need to shout. Of course they don't run at the same time. The step() method is a blocking function. It does not return until the motor has completed stepping the specified number of steps. The speed and number of steps defines how long that takes.

You can't really make them step at the same time. What you can do, though, is to make them step one at a time in much smaller steps, so that they appear to be moving at the same time.

Code:
for(int s=0; s<step_360; s++)
{
  myStepper1.step(1);
  myStepper2.step(1);
}

Depending on the driver and the stepper motor, you may be able to use half, quarter, or eighth step mode, and step in even smaller amounts, making the motors move more and more in sync,
Logged

West Des Moines, Iowa USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 428
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can in either of two ways: Firstly, you can connect one set of stepper control signals from the Arduino to both driver channels. This has the effect of running the steppers in lockstep. (I once built a CNC router with two steppers driving the x-axis, and this was how I ensured that the steppers stayed in sync.)

If that's not what you want, you can make sure that both sets of control signals are connected to pins on the same port, and then exercise control by doing 8-bit wide outputs to the port rather than to individual pins with digitalWrite().

Edit: clarification
« Last Edit: February 25, 2012, 08:39:17 am by Morris Dovey » Logged

There's always a better way!

Canada
Offline Offline
Newbie
*
Karma: 0
Posts: 43
Luv Life Live Life
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
when i run the program (shown below) both steppers rotate but NOT AT THE SAME TIME
No need to shout. Of course they don't run at the same time. The step() method is a blocking function. It does not return until the motor has completed stepping the specified number of steps. The speed and number of steps defines how long that takes.

You can't really make them step at the same time. What you can do, though, is to make them step one at a time in much smaller steps, so that they appear to be moving at the same time.

Code:
for(int s=0; s<step_360; s++)
{
  myStepper1.step(1);
  myStepper2.step(1);
}

Depending on the driver and the stepper motor, you may be able to use half, quarter, or eighth step mode, and step in even smaller amounts, making the motors move more and more in sync,

thanks sooo much!!! that for loop seems to do the trick. since u can tell my programing skills are next to nil, how would u modify the loop so one stepper does say 90 degrees and one does 360.? thanks again. greatly appreciated!:)
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46266
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
how would u modify the loop so one stepper does say 90 degrees and one does 360.?
Determine which position change is larger (360). Then, define the amount each motor needs to step on each pass through loop.
float step1Inc =  90.0/360.0;
float step2Inc = 360.0/360.0;

Then, loop for 360 steps. On each pass through loop, set the new position.
Code:
float step1Pos = 0.0;
float step2Pos = 0.0;

for(int i=0; i<360; i++)
{
  step1Pos += step1Inc;
  step2Pos += step2Inc;

  // Move stepper 1 to step1Pos
  // Move stepper 2 to step2Pos
}
Since the stepper expects to move in whole steps, step1Pos = 0.25, 0.50, and 0.75 will cause nothing to happen for stepper 1, while stepper 2 steps 3 times. Then when step1Pos gets to 1.0, it will step once.
Logged

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1023
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could try something like this - Speed might be an issue -

Dir1 and Dir2 control the direction the motor will step +1 and -1. Dir1 or Dir2 = 0 will result in no motion for that motor.
How often you call them controls the motor speed. Each time you call motor 1 or Motor 2 you will get 1 step.
You could use half stepping but that would require 8 patterns (0-7) and the necesary changes to Motor1 and Motor2


Code:
int StepCt1 = 0;
int StepCt2 = 0;
int Dir1;
int Dir2;


void Motor1(int Direction){
   StepCt1=Stepct1+Direction;
   StepCt1=StepCt1 && 3;       / StpepCt1 ranges from 0 to 3,  -1 = B11111111 so B11111111 && B00000011 = B00000011
   switch (StepCt1)
      case 0:
          digitalWrite(2, HIGH);
          digitalWrite(3, LOW);
          digitalWrite(4, LOW);
          digitalWrite(5, LOW);
          break;
      case 1:
          digitalWrite(2, LOW);
          digitalWrite(3, HIGH);
          digitalWrite(4, LOW);
          digitalWrite(5, LOW);
          break;
      case 2:
          digitalWrite(2, LOW);
          digitalWrite(3, LOW);
          digitalWrite(4, HIGH);
          digitalWrite(5, LOW);
          break;
      case 3:
          digitalWrite(2, LOW);
          digitalWrite(3, LOW);
          digitalWrite(4, LOW);
          digitalWrite(5, HIGH);
          break;
    }
}
void Motor2(int Direction){
   StepCt2=Stepct2+Direction;
   StepCt2=StepCt2 && 3;       / StpepCt1 ranges from 0 to 3,  -1 = B11111111 so B11111111 && B00000011 = B00000011
   switch (StepCt2)
      case 0:
          digitalWrite(8, HIGH);
          digitalWrite(9, LOW);
          digitalWrite(10, LOW);
          digitalWrite(11, LOW);
          break;
      case 1:
          digitalWrite(8, LOW);
          digitalWrite(9, HIGH);
          digitalWrite(10, LOW);
          digitalWrite(11, LOW);
          break;
      case 2:
          digitalWrite(8, LOW);
          digitalWrite(9, LOW);
          digitalWrite(10, HIGH);
          digitalWrite(11, LOW);
          break;
      case 3:
          digitalWrite(8, LOW);
          digitalWrite(9, LOW);
          digitalWrite(10, LOW);
          digitalWrite(11, HIGH);
          break;
    }
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think following logic should do the trick

Say you have 2 Steppers A & B and you want it to rotate 90 & 270 deg at the same time and for the same time say Motor are of 60 PPR (PWM output rather than Digital will be good for this method). (this logic has nothing to do with the example provided with IDE) My simple logic is as you have individual driver for your motors you will only need "Clock Pulses" to run the motor. if your driver consist of any inbuilt clock then you can easily replace the inbuilt clock pulses with the Arduino generated pulses. this is applicable to Direction pulses as well.

The logic:
initial setup
set any 2 pins to output mode ( here consider pin 6 & 7 for Motor A & B respectively)
Determine which will take more steps to get to desire position (in this case B)
Declare an Array of String  for the max number of steps
now find the proportionate motion speed like here it is 1:3 so you should have to fire 1 A pulse for each third B pulse.
use following loop to fill the array
for (i = 0; i < StpB; i++){
   if ( i % 3 ==0) {
   AryTxt = "11" } else {
AryTxt = "01"
}
}

Now you have a set of pulses that to be fire on same interval ( at the same delay(time) )

you can differentiate the pulses individually  using charAt() String function (see http://arduino.cc/en/Tutorial/StringCharacters )

you only have to do this
separate the pulse data before you call delay

it will be some thing like this

for (i = 0; i < StpB; i++){
  char M = AryTxt.charAt(1);
 char N = AryTxt.charAt(2);
 if (M == 1) {
  digitalWrite(6, LOW);}
else {
 digitalWrite(6, HIGH);}
 
if (N == 1) {
  digitalWrite(7, LOW);}
else {
 digitalWrite(7, HIGH);}

delay(10)
}

you should have sync motor.
« Last Edit: February 22, 2014, 03:35:55 pm by aadityadengle » Logged

UK
Offline Offline
Faraday Member
**
Karma: 47
Posts: 3694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The technique proposed by @PaulS is very simple and easily extended to any number of motors. I have tried it successfully. The only extra I would suggest is to use long integers rather than floating point. For example if you want one to step 23 times and the other 360 times make the loop = 360 * 23 = 8280 and then one motor steps once every 23 iterations and the other (slower) motor steps once every 360 iterations.

...R
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

according to my last reply it may possible that you could ran out of memory  smiley-razz  smiley-mad
the solution is to avoid that array adding part and club the motor execution with pulse counting

for (i = 0; i < StpB; i++){
   if ( i % 3 ==0) {
   digitalWrite(6, HIGH);
   digitalWrite(7,HIGH);  
 }
else {
digitalWrite(6, LOW);
digitalWrite(7,HIGH);  
}
delay(10)
}

Short and Simple
 smiley

Logged

Pages: [1]   Go Up
Jump to: