2 steppers with easy drivers

Hi,
I’m looking to make a code to use 2 steppers at the same time, so for instance move left then go up after half a second as it still moves left, there will be a sequence of things working and the 2 steppers will activate part way through, so no button or anything to activate them, wired the way it is in the pic,


Has anyone done this before?
Can anyone help,
Thankyou all,
Phil.

I didn't really understand what you were trying to do. Do you already have a sketch to control the steppers? And please post links to the components used.
You could use MobaTools to control the steppers. It is quite easy to control multiple steppers at the same time with this library, since you don't have to worry about step generation in your sketch. Just start both as you need it and they will turn independently.

Sorry, this is a video of my progress so far, I want a second stepper to tilt the claw slightly but I’m unsure how to do it, I’ll upload the code shortly when I get home

I’m creating the back to the future scene :slight_smile:

Look at the examples in the Accel Stepper library. It has a several multiple stepper examples.

This is my code

#define step_pin 3
#define dir_pin 2

const byte button1 = 8;
const byte button2 = 9;
 int relay1 = 12;
 int dir;
 int steps = 4500;
 int solenoide = 10;
 int led =13;
 int buzzer = 11;
 
void setup() {
   pinMode(relay1, OUTPUT);
   digitalWrite(relay1, HIGH);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT);
   digitalWrite(step_pin, LOW);
   digitalWrite(dir_pin, LOW);
   pinMode(button1, INPUT_PULLUP);
   pinMode(button2, INPUT_PULLUP);
   pinMode(solenoide, OUTPUT);
   pinMode(led, OUTPUT);
}

void loop() {
  while (digitalRead(button1) == HIGH)
   {
   }
   delay(1000);
   
  int i=0;

 do{
  i++;
  tone(buzzer, 455);
  delay(320);
  noTone(buzzer);
  delay(500);
 }while(i<=0);
 
  digitalWrite(solenoide,HIGH);
  digitalWrite(led, HIGH);
  delay(250);
  digitalWrite(solenoide,LOW);
  digitalWrite(led, LOW);

  while (digitalRead(button2) == HIGH) 
  {
  }
  
  digitalWrite(relay1, LOW);
  delay(1000);
  digitalWrite(relay1, HIGH);
  delay(500);
  
  while(steps>=0) {       
  digitalWrite(dir_pin,LOW);
  digitalWrite(step_pin, HIGH);
  delayMicrosecons(400);
  digitalWrite(step_pin, LOW);
  delayMicroseconds(400);
  steps--;
  
  }
}

I’ll look at the example tomorrow but you see what I mean, I need to add another stepper motor move whilst the first stepper is moving,
Thanks,
Phil.

First off, get rid of all those delay()'s. You can't do several things at a time while delay() is blocking your code until it finishes. Look at the Blink Without Delay in the IDE (File->examples->02.digital->BlinkWithoutDelay) and it will guide you into using elapsed time to do things....

1 Like

As already mentioned you should get rid of your delays.
And include a few comments to explain what the sketch is supposed to do at each point. That makes helping very much easier.

The next step would be to use a library for your stepper. My favourite is MobaTools :wink: ( can be installed be means of the library manager). Because MobaTools creates the steps in the background, you could your sketch with two steppers even get running with your delays. But I would not recommend to do so. A finite state machine is a much better approach. You can type 'finite state machine arduino' in the search engine of your choice and you will get many results showing how to create one on the arduino

Although not recommended, here is a variant how your program with delays() can be extended by a 2nd stepper. It maybe a starting point. You may need to adjust the pin numbers to your needs.

#include <MobaTools.h>
const byte step_pin = 3;
const byte dir_pin = 2;

const byte step2Pin = 5;
const byte dir2Pin = 6;

const byte button1 = 8;
const byte button2 = 9;

MoToStepper stepper1( 800, STEPDIR ); // 800 steps per revolution
MoToStepper stepper2( 800, STEPDIR );


int relay1 = 12;
int dir;
int steps = 4500;
int solenoide = 10;
int led = 13;
int buzzer = 11;

void setup() {
  pinMode(relay1, OUTPUT);
  digitalWrite(relay1, HIGH);
  /*pinMode(dir_pin, OUTPUT);
  pinMode(step_pin, OUTPUT);
  digitalWrite(step_pin, LOW);
  digitalWrite(dir_pin, LOW);*/
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(solenoide, OUTPUT);
  pinMode(led, OUTPUT);

  //Setting up the steppers
  stepper1.attach( step_pin, dir_pin );
  stepper1.setSpeedSteps( 12500 );    // = 1250 Steps/sec
  stepper1.setRampLen( 50 );          // acceleration and deceleration
  stepper2.attach( step2Pin, dir2Pin );
  stepper2.setSpeedSteps( 12500 );
  stepper2.setRampLen( 50 );
}

void loop() {
  while (digitalRead(button1) == HIGH)
  {
  }
  delay(1000);

  int i = 0;

  do {
    i++;
    tone(buzzer, 455);
    delay(320);
    noTone(buzzer);
    delay(500);
  } while (i <= 0);

  digitalWrite(solenoide, HIGH);
  digitalWrite(led, HIGH);
  delay(250);
  digitalWrite(solenoide, LOW);
  digitalWrite(led, LOW);

  while (digitalRead(button2) == HIGH)
  {
  }
  digitalWrite(relay1, LOW);
  delay(1000);
  digitalWrite(relay1, HIGH);
  delay(500);
  stepper1.writeSteps( steps );  // starting first stepper. 
                                 // Direction depends from motor wiring and mechanics. Change to -steps to invert direction.
  delay(500);
  stepper2.writeSteps( 1000 );    // starting second stepper. Steps may need to be adjusted
  while ( stepper1.moving() || stepper2.moving() ); // wait until both steppers have reached their target position

}

As suggested above remove the delays. Also go to a task based approach
See my tutorials on How to write Timers and Delays in Arduino and
Multi-tasking in Arduino which has a complete stepper example using the AccelStepper library

Thank you very much for the replies and the time spent on the code, I’ll start by looking into how to add the mobatools to the library and go from there, I’ll update once I know what I’m doing :smiley:
Thanks very much again,
Phil.

Ok update is, that excellent bit af help got the 2 steppers to work at the same time but every stepper movement after isnt working on its own, I want it to do single movements after the 1 and only double stepper move,
Here’s what I mean:-

  1. Move stepper1 -4370 steps
  2. after 1.5 seconds move stepper2 400 steps (while stepper 1 is moving)
    (This is where it goes wrong)
  3. Move stepper1 1000 steps
  4. Move stepper2 -5000 steps
  5. Move stepper2 5400 steps
  6. Move stepper1 3370 steps

Is there something I need to add so 3,4,5 and 6 steps don’t work at the same time?
Thanks again,
Phil.

This is how I’ve added the last bit on

#include <MobaTools.h>
const byte step_pin = 3;
const byte dir_pin = 2;

const byte step2Pin = 5;
const byte dir2Pin = 6;

const byte button1 = 8;
const byte button2 = 9;

MoToStepper stepper1( 800, STEPDIR ); // 800 steps per revolution
MoToStepper stepper2( 800, STEPDIR );


int relay1 = 12;
int dir;
int steps = 4370;
int solenoide = 10;
int led = 13;
int buzzer = 11;

void setup() {
  pinMode(relay1, OUTPUT);
  digitalWrite(relay1, HIGH);
  /*pinMode(dir_pin, OUTPUT);
  pinMode(step_pin, OUTPUT);
  digitalWrite(step_pin, LOW);
  digitalWrite(dir_pin, LOW);*/
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(solenoide, OUTPUT);
  pinMode(led, OUTPUT);

  //Setting up the steppers
  stepper1.attach( step_pin, dir_pin );
  stepper1.setSpeedSteps( 12500 );    // = 1250 Steps/sec
  stepper1.setRampLen( 50 );          // acceleration and deceleration
  stepper2.attach( step2Pin, dir2Pin );
  stepper2.setSpeedSteps( 12500 );
  stepper2.setRampLen( 50 );
}

void loop() {
  while (digitalRead(button1) == HIGH)
  {
  }
  delay(1000);

  int i = 0;

  do {
    i++;
    tone(buzzer, 455);
    delay(320);
    noTone(buzzer);
    delay(500);
  } while (i <= 0);

  digitalWrite(solenoide, HIGH);
  digitalWrite(led, HIGH);
  delay(250);
  digitalWrite(solenoide, LOW);
  digitalWrite(led, LOW);

  while (digitalRead(button2) == HIGH)
  {
  }
  digitalWrite(relay1, LOW);
  delay(1000);
  digitalWrite(relay1, HIGH);
  delay(500);
  stepper1.writeSteps( -steps );  // starting first stepper. 
                                 // Direction depends from motor wiring and mechanics. Change to -steps to invert direction.
  delay(1500);
  stepper2.writeSteps( -400 );    // starting second stepper. Steps may need to be adjusted
  while ( stepper1.moving() || stepper2.moving() ); // wait until both steppers have reached their target position
delay(7000);
stepper1.writeSteps( 1000 );
stepper2.writeSteps( -5000 );

}

the end 2 commands move at the same time and I want them to be single movement,
Thanks again,
Phil.

Hello Phil,
there are some things to consider when using MobaTools :wink:

  • All calls are non blocking. Even if you start a stepper: it will start moving, but your sketch will go on too. That's why the last two commands lead to moving the two steppers in parallel.
  • The Parameter of the 'writeSteps' call is not the number of steps to do. It is a target position where the stepper should got to, measured in steps from the starting point. If you want to go back to the starting point, then call writeSteps(0). ( It's similar to the write call for a servo )
  • The starting point is where the stepper is positioned, when the program starts. But you can set the starting point at any time to the actual position of the stepper.
  • If you want the stepper to go a fixed number of steps, no matter where it is positioned at the moment, then use doSteps in stead of writeSteps. ( the library will still know where it is, therefore you can mix doSteps and writeSteps at your needs)
  • You can ask wether the stepper is still moving, to wait until it has reached its target position. This is the method 'moving()'. If you want the last two moves to happen one after the other, insert a
    while ( stepper1.moving() );
    in between.
  • The return value of moving() is the remaining distance in %. For example you could start the 2nd stepper also when the first one has covered half of the distance with:
    while( stepper1.moving() > 50 );

Regards, Franz-Peter

WOW thank you, thanks you, thank you so much MicroBahner it’s working great now and the program looks so much cleaner from the way I was doing it before, I need to wait for parts for a small hydraulic ram I’m making on the can opener for that to work but I am moooooooore than happy with it now,

Yeah it hit on the way back but later when the 4 relay board comes I can drop the can on the way back to the starting point,
Thank you to all that helped :smiley:
Phil.

You are welcome :wink: .
Looks good :sunglasses:

Well I’m back and very close to completion, as you’ve seen in the last video, it is nearly there, I’ve had to wait for parts and fitting them but it now has a pneumatic ram to push the tin opener up, I’m having an issue where I can’t get the dc motor for the claw to open while the pneumatic ram pushes up for 9 seconds, I want the ram and the dc motor (for the claw) to work at the same time,
Here’s my code so far;-


#include <MobaTools.h>
const byte step_pin = 3;
const byte dir_pin = 2;

const byte step2Pin = 5;
const byte dir2Pin = 4;

const byte button1 = 8;
const byte button2 = 9;
const byte button3 = 37;

MoToStepper stepper1( 800, STEPDIR ); 
MoToStepper stepper2( 800, STEPDIR );

int signal_pin = 53;
int relay1 = 49;
int relay2 = 47;
int relay3 = 43;
int relay4 = 41;
int dir;
int solenoide = 10;
int led = 13;
int buzzer = 11;
int steps = 4400;

void setup() {
  pinMode(signal_pin, OUTPUT);  
  pinMode(button3, INPUT_PULLUP);  
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
  pinMode(dir_pin, OUTPUT);
  pinMode(step_pin, OUTPUT);
  digitalWrite(step_pin, LOW);
  digitalWrite(dir_pin, LOW);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(solenoide, OUTPUT);
  pinMode(led, OUTPUT);

  //Setting up the steppers
  stepper1.attach( step_pin, dir_pin );
  stepper1.setSpeedSteps( 12000 );
  stepper1.setRampLen( 10 ); 
  stepper2.attach( step2Pin, dir2Pin );
  stepper2.setSpeedSteps( 12000 );
  stepper2.setRampLen( 10 );
}

void loop() {
  while (digitalRead(button1) == HIGH)
  {
  }
  delay(1000);

  int i = 0;

  do {
    i++;
    tone(buzzer, 455);
    delay(320);
    noTone(buzzer);
    delay(500);
  } while (i <= 0);

  digitalWrite(solenoide, HIGH);
  digitalWrite(led, HIGH);
  delay(250);
  digitalWrite(solenoide, LOW);
  digitalWrite(led, LOW);

  while (digitalRead(button2) == HIGH)
  {
  }
  digitalWrite(relay1, LOW);  
  digitalWrite(relay2, LOW);
  delay(650);
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);  
  
  stepper1.writeSteps( -steps ); 

  delay(1650);
  
  stepper2.writeSteps( -300 ); 
  while ( stepper1.moving() || stepper2.moving() ); 

  digitalWrite(signal_pin, HIGH);  // I need relays 1,2,3,4 to work at the same time as this delay
  delay(9000);
  digitalWrite(signal_pin, LOW);
  delay(1500);
 
  stepper1.doSteps( 1800 ); 
  while ( stepper1.moving()  );
  
  stepper2.doSteps( -4000 );
  while ( stepper2.moving() );
  delay(400);

  stepper2.doSteps( 4300 );
  while ( stepper2.moving() );  

  stepper1.writeSteps( 0 ); 
  while ( stepper1.moving()  );  

  digitalWrite(relay3, LOW);  
  digitalWrite(relay4, LOW);
  delay(600);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);

}

I also need the last part with relays 1,2,3,4 to work at the same time as stepper1 moving to zero,
As always I am great full for all the help,
Thanks,
Phil.

Hi,
I don't know if it helps in your project, but I developed this sketch that allows the simultaneous use of several steps motors.
Modify it to fit your project.

RV mineirin

The problem seems to me, that your sketch is realized with very much blocking stucture. MobaTools itself does not block, but you always wait until one action ist done before proceeding to the next.

  stepper1.writeSteps( 0 ); 
  while ( stepper1.moving()  );  

You don't need to wait for the stepper to reach zero. Delete the while statement, and your relais will be switched while the stepper moves. You could also wait for part of the movement if you don't want the relays to switch immediately. With

  stepper1.writeSteps( 0 ); 
  while ( stepper1.moving() > 50  );  

the relais will start switching in the middle of the movement.

The same is true with the other stepper movements. You don't need to wait until the steppers have reached their target positions if you want to do something else while they move.

But the best solution would be to change the sketch to non-blocking programming. For this you would have to deal with the principle of the finite state machine. However, that would be a major rebuild of the sketch.

I was actually in my shed and thought that removing the “while” would sort this, then I forgot about it, well the last part with the relays is working correctly, thanks very much once again MicroBahner :slight_smile:
I’m looking at the 4 relays to work (for the claw to open) at the same time as the ram pushes up, how can I do this?
Thanks again MicroBahner.

Could I put an “if” in there? So if stepper1 == -4400 steps work the ram and relays, would that work? And how would it be wrote?
Thanks,
Phil.