Moba tools library controlling mutliple stepper motors and A4988

Hi,

Thanks to MicroBahner (for explaining how to use a stepper motor in a previous post), I can run stepper motors in two directions using the A4988 driver and the library MobaTools

However, I now want to implement this in more complex software and I need some help on how to structure the code for that.

I have 7 stepper motors with a driver for each one of them, I want to run these motors in different scenarios

1- Run all of them in a specific direction until the user inputs otherwise
2- Run only few of them while the remaining are off until an input says otherwise

So I understand that I will have to use an array and use the for loop to just switch on a particular motor in that array or say multiple.

However, what i'm finding hard is how to construct this array idea in the code? what should be in the array? and what about the other objects?

If anyone has an example to use this library with multiple stepper motors please let me know, I simply want to rotate the motors into a direction until an input asks to stop

This is the example code that I would like to implement which works perfectly with one motor only. I added equations near the areas that i'm not sure how to use

/* ====== minimumStepper =======================================
    Bare minimum to get a stepper with step/dir driver turning
*/
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.
const byte stepPin = 6;
//i assume I would need to do something like this const byte stepping[7]= {5, 7, 8, ...};

const byte dirPin = 5;
//i would use an array and define all the pins for 7 motors
//or can I actually connect all dir pins from the drivers to a single pin in Arduino?
//Note that I won't need to rotate two motors in different directions simultinusly

const int stepsPerRev = 200;    // Steps per revolution - may need to be adjusted

MoToStepper stepper1( stepsPerRev, STEPDIR );  // create a stepper instance
// will I need to define 7 of these?


void setup() {
  stepper1.attach( stepPin, dirPin );//how about this? how to deal with this when I have many motors?

  stepper1.setSpeed( 300 );
  //i want the same speed for all of them, so how to apply this to all of them
  stepper1.setRampLen( stepsPerRev / 2);
  // Ramp length is 1/2 revolution, same thing, how to apply this to all?
  stepper1.rotate(1);
  // start turning, 1=vorward, -1=backwards,  same thing.. how to apply this to all?
}

void loop() {
}

If you want to run multiple stepper-motors at the same time there is one question to clarify:

do the steppers have to run in sync step by step?
where step by step can also mean motor 1 has a rpm of 1000 motor 2 has a rpm of 500 motor 3 has a rpm of 250
which would mean
each second step of motor 1 motor 2 has a step
and
each 4th step of motor 1 motor 3 has a step
etc.
syncronising with that precision is not possible with the moba-tools
because the ramps need different times to speed up / speed down

If you would like to run multiple stepper-motors in step by step cync this requires the Bresenham-algorithm expanded from 2 motors to 7 motors.

To post a more detailed opinion you should describe what your 7 stepper-motors are doing in the end. = giving an overview about your project.
It depends strongly on your application if such a high precision in syncing the motors is nescessary or not.

best regards Stefan

1 Like

not at all, in fact I want a simple rotation application, the motors are connected to peristaltic pumps, and all I want from the motors is to keep rotating and letting the pumps work

The motors are used in peristaltic pumps which are basically separated in 7 channels, the project acts like a coffee dispenser, sometimes I want to fill 7 cups (the cups are placed under the pumps and under each cup is a load cell which is basically the input to decide when to stop rotating the pump), sometimes I want to fill 3 only, some other times I want to run all pumps in opposite direction to clean the pipes from any residuals.

Very doable with the mobaTools.
Me personal I haven't used arrays on the MotoStepper-object but it should work pretty straight forward as with any array.

The questions evolves to how to create an array of objects where the constructor has parameters
MoToStepper stepper[7] ( stepsPerRev, STEPDIR );

1 Like

Yes!
There are multiple objects as well, I'm just not sure on how to structure my arrays

This is new for me too.

I tried different variations. What I found that the code is compiling is this version

/* ====== minimumStepper =======================================
    Bare minimum to get a stepper with step/dir driver turning
*/
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.

const byte stepPin[6]= {2, 3,  4,  5,  6,  7};
const byte dirPin[6] = {8, 9, 10, 11, 12, 13};  

const int stepsPerRev = 200;    // Steps per revolution - may need to be adjusted

MoToStepper *stepper[6] = {
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR)
};


void setup() {
  for (byte i = 0; i < 6; i++) { // 0 to 5 is SIX elements
    stepper[i]->attach( stepPin[i], dirPin[i] );
    stepper[i]->setRampLen( stepsPerRev / 2);
  }

  stepper[3]->rotate(1);
  stepper[5]->rotate(0);
  stepper[2]->rotate(-1);
}

void loop() {
}

In this code a array of pointers to objects of type MoToStepper is defined
using pointers to the objects instead of the objects itselfs requires a different notation to access the functions of the object you need the arrow-operator
->
hence
stepper[i] -> attach( stepPin[i], dirPin[i] );

    stepper[i]->attach( stepPin[i], dirPin[i] );

This compiles. But I have no personal experience if this way of coding really works as expected.

EDIT of a typo

there was a typo which would have caused weird crashing of the code
the definition of the array has 6 elements. SIX
array-indexes start at 0. This means counting up starting from zero

  1. index zero
  2. indexone
  3. index two
  4. index three
  5. index four
  6. index five
for (byte i = 0; i < 7; i++)   // <== counting up to 6 is one too far !!

it must be

for (byte i = 0; i < 6; i++)   // smaller than 6 count 0...5

best regards Stefan

1 Like

Thanks, i will give this a try and let you know afterwards

just to make sure you re-read my post above.
There was a typo about array-indexes that would cause weird and hard to debug crashes

best regards Stefan

1 Like

Thank you for your help, i did re-read.

The code didn't work, unfortunately, and then I compared it to single motor code and the single code worked nicely.

So this did not work:

/* ====== minimumStepper =======================================
    Bare minimum to get a stepper with step/dir driver turning
*/
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.

const byte stepPin[6]= {2, 3,  4,  5,  6,  7};
const byte dirPin[6] = {8, 9, 10, 11, 12, 13};  

const int stepsPerRev = 200;    // Steps per revolution - may need to be adjusted

MoToStepper *stepper[6] = {
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR), 
  (stepsPerRev, STEPDIR)
};


void setup() {
  for (byte i = 0; i < 6; i++) { // 0 to 5 is SIX elements
    stepper[i]->attach( stepPin[i], dirPin[i] );
    stepper[i]->setSpeed ( 1400 );
    stepper[i]->setRampLen( stepsPerRev / 2);
  }

  stepper[3]->rotate(1);
 // stepper[5]->rotate(0);
//  stepper[2]->rotate(1);
}

void loop() {
}

but this worked:

/* ====== minimumStepper =======================================
 *  Bare minimum to get a stepper with step/dir driver turning
 */
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.
const byte stepPin = 5;
const byte dirPin = 11;

const int stepsPerRev = 200;    // Steps per revolution - may need to be adjusted

MoToStepper stepper1( stepsPerRev, STEPDIR );  // create a stepper instance

void setup() {
  stepper1.attach( stepPin, dirPin );
  stepper1.setSpeed( 1400 );              // 30 rev/min (if stepsPerRev is set correctly)
  stepper1.setRampLen( stepsPerRev ); // Ramp length is 1/2 revolution
  stepper1.rotate(1);                    // start turning, 1=vorward, -1=backwards                    
}

void loop() {
}

Although it did work, the motor was so noisy for some reason, but it did work

And then i used a simple code like this, the noise has gone, but anyway I'm not here to discuss noise, I just want to figure out how to control multiple motors

// 14 direction purple
// 15 step brown


const int dirpin = 11;
const int steppin = 5;
const int steppin2 = 6;

const int SPR = 200;


void setup() {
  pinMode(dirpin, OUTPUT);
  pinMode(steppin, OUTPUT);
}

void loop() {


  digitalWrite(dirpin, LOW);
  for (int j = 0; j < 20; j++) {
    for (int i = 0; i < SPR * 2; i++) {
      digitalWrite(steppin, HIGH);
      digitalWrite(steppin2, HIGH);
      delayMicroseconds(700);
      digitalWrite(steppin, LOW);
      digitalWrite(steppin2, LOW);
      delayMicroseconds(700);
    }

  }



}

also, this code doesn't let the motor keep running, it just runs for 40 full rotations only

do you understand what these lines of code mean?
They define which IO-pins are used for creating direction-signal and step-pulses
stepper 1

  • steppin 2
  • direction pin 8

etc.
it is about time that you provide more information:
What exact type of microcontroller do you use?
at which IO-pins did you connect the stepper-drivers?

If you are using an ESP8266 or ESP32 some of the io-pins have limititaions in its use which must be checked

best regards Stefan

1 Like

I'm using Arduino Mega 2560

Yes, and I understood that stepper[3] is supposed to be the location number 4 (since the count starts from 0) which corresponds to pins 5 for step and 11 for dir, is that correct?

the digital pins on the mega with the same numbers

EDIT: I tried changing stepper[3] to setepper[4], still same nothing happened

Use this to create an array of e.g. 3 MoToStepper objects:

MoToStepper mySteppers[] { {200,STEPDIR }, {200,STEPDIR}, {200,STEPDIR} };

You can access an element of the array like this:

mySteppers[i].attach(stepPin[i],dirPin[i]);
...
mySteppers[i].doSteps(400);


1 Like

I did exactly this, no response from the motor, no rotation at all

/* ====== minimumStepper =======================================
    Bare minimum to get a stepper with step/dir driver turning
*/
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.

const byte stepPin[6]= {2, 3,  4,  5,  6,  7};
const byte dirPin[6] = {8, 9, 10, 11, 12, 13};  

const int stepsPerRev = 400;    // Steps per revolution - may need to be adjusted

MoToStepper *mysteppers[6] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR),  (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR),  (stepsPerRev, STEPDIR)};


void setup() {
  for (byte i = 0; i < 6; i++) { // 0 to 5 is SIX elements
    mysteppers[i]->attach( stepPin[i], dirPin[i] );
    mysteppers[i]->setSpeed ( 1400 );
    mysteppers[i]->setRampLen( stepsPerRev / 2);
  }

  mysteppers[3]->rotate(1); //rotate the element number 3, which corresponds to pins 5 and 11
  mysteppers[4]->rotate(1);
}

void loop() {
}

But then the single motor code works so no problem with wiring/hardware

/* ====== minimumStepper =======================================
 *  Bare minimum to get a stepper with step/dir driver turning
 */
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.
const byte stepPin = 5;
const byte dirPin = 11;

const int stepsPerRev = 400;    // Steps per revolution - may need to be adjusted

MoToStepper stepper1( stepsPerRev, STEPDIR );  // create a stepper instance

void setup() {

  stepper1.attach( stepPin, dirPin );
  stepper1.setSpeed( 1400 );              // 30 rev/min (if stepsPerRev is set correctly)
  stepper1.setRampLen( stepsPerRev ); // Ramp length is 1/2 revolution
  stepper1.rotate(1);                    // start turning, 1=vorward, -1=backwards                    
}

void loop() {
}

even when using this

no response

/* ====== minimumStepper =======================================
    Bare minimum to get a stepper with step/dir driver turning
*/
#include <MobaTools.h>
// Stepper connections - Please adapt to your own needs.

const byte stepPin[6]= {2, 3,  4,  5,  6,  7};
const byte dirPin[6] = {8, 9, 10, 11, 12, 13};  

const int stepsPerRev = 400;    // Steps per revolution - may need to be adjusted

MoToStepper *mysteppers[6] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR),  (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR),  (stepsPerRev, STEPDIR)};


void setup() {
  for (byte i = 0; i < 6; i++) { // 0 to 5 is SIX elements
    mysteppers[i]->attach( stepPin[i], dirPin[i] );
    mysteppers[i]->setSpeed ( 1400 );
    mysteppers[i]->setRampLen( stepsPerRev / 2);
  }

  mysteppers[3]->doSteps(400); //rotate the element number 3, which corresponds to pins 5 and 11
  mysteppers[4]->doSteps(400);
}

void loop() {
}

What

type of microcontroller

are you using?
it is very likely that the physical connections and/or pin-definitions do not fit to the

type of microcontroller

you are using!

1 Like

Please compare your line:

EXACTLY with mine:

Thats really a big difference!

1 Like

I am using Arduino Mega 2560, I'm sorry I posted the code from the example in the library without changing it, I just edited my main post, you may look at it again

check this one out

It doesn't compile though,

When i write it like this

I get this error:
use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'

and the error points to the line of code..

only when I include the * sign it compiles

and even when I write 200 instead of stepsPerRev, it doesn't work unless I use the *

and even when I include the array like this [6] or like this [], it won't work, I will get the same error

here is the full error message:

sketch_nov16a:12:173: error: use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'
MoToStepper mysteppers[] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR)};
^
In file included from C:\arduino-nightly\libraries\MobaTools-master\src/MobaTools.h:170:0,
from C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino:4:
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:142:5: note: declared here
MoToStepper (MoToStepper && ) =delete;
^~~~~~~~~~~
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:145:5: note: after user-defined conversion: MoToStepper::MoToStepper(long int)
MoToStepper(long steps); // steps per 360 degree in HALFSTEP mode or A4988 Mode on ESP
^~~~~~~~~~~
sketch_nov16a:12:173: error: use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'
MoToStepper mysteppers[] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR)};
^
In file included from C:\arduino-nightly\libraries\MobaTools-master\src/MobaTools.h:170:0,
from C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino:4:
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:142:5: note: declared here
MoToStepper (MoToStepper && ) =delete;
^~~~~~~~~~~
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:145:5: note: after user-defined conversion: MoToStepper::MoToStepper(long int)
MoToStepper(long steps); // steps per 360 degree in HALFSTEP mode or A4988 Mode on ESP
^~~~~~~~~~~
sketch_nov16a:12:173: error: use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'
MoToStepper mysteppers[] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR)};
^
In file included from C:\arduino-nightly\libraries\MobaTools-master\src/MobaTools.h:170:0,
from C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino:4:
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:142:5: note: declared here
MoToStepper (MoToStepper && ) =delete;
^~~~~~~~~~~
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:145:5: note: after user-defined conversion: MoToStepper::MoToStepper(long int)
MoToStepper(long steps); // steps per 360 degree in HALFSTEP mode or A4988 Mode on ESP
^~~~~~~~~~~
sketch_nov16a:12:173: error: use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'
MoToStepper mysteppers[] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR)};
^
In file included from C:\arduino-nightly\libraries\MobaTools-master\src/MobaTools.h:170:0,
from C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino:4:
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:142:5: note: declared here
MoToStepper (MoToStepper && ) =delete;
^~~~~~~~~~~
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:145:5: note: after user-defined conversion: MoToStepper::MoToStepper(long int)
MoToStepper(long steps); // steps per 360 degree in HALFSTEP mode or A4988 Mode on ESP
^~~~~~~~~~~
sketch_nov16a:12:173: error: use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'
MoToStepper mysteppers[] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR)};
^
In file included from C:\arduino-nightly\libraries\MobaTools-master\src/MobaTools.h:170:0,
from C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino:4:
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:142:5: note: declared here
MoToStepper (MoToStepper && ) =delete;
^~~~~~~~~~~
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:145:5: note: after user-defined conversion: MoToStepper::MoToStepper(long int)
MoToStepper(long steps); // steps per 360 degree in HALFSTEP mode or A4988 Mode on ESP
^~~~~~~~~~~
sketch_nov16a:12:173: error: use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'
MoToStepper mysteppers[] = {(stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR), (stepsPerRev, STEPDIR)};
^
In file included from C:\arduino-nightly\libraries\MobaTools-master\src/MobaTools.h:170:0,
from C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino:4:
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:142:5: note: declared here
MoToStepper (MoToStepper && ) =delete;
^~~~~~~~~~~
C:\arduino-nightly\libraries\MobaTools-master\src/utilities/MoToStepper.h:145:5: note: after user-defined conversion: MoToStepper::MoToStepper(long int)
MoToStepper(long steps); // steps per 360 degree in HALFSTEP mode or A4988 Mode on ESP
^~~~~~~~~~~
C:\Users\A-A-F\AppData\Local\Temp\arduino_modified_sketch_133755\sketch_nov16a.ino: In function 'void setup()':
sketch_nov16a:17:18: error: base operand of '->' has non-pointer type 'MoToStepper'
mysteppers[i]->attach( stepPin[i], dirPin[i] );
^~
sketch_nov16a:18:18: error: base operand of '->' has non-pointer type 'MoToStepper'
mysteppers[i]->setSpeed ( 1400 );
^~
sketch_nov16a:19:18: error: base operand of '->' has non-pointer type 'MoToStepper'
mysteppers[i]->setRampLen( stepsPerRev / 2);
^~
sketch_nov16a:22:16: error: base operand of '->' has non-pointer type 'MoToStepper'
mysteppers[3]->doSteps(400); //rotate the element number 3, which corresponds to pins 5 and 11
^~
sketch_nov16a:23:16: error: base operand of '->' has non-pointer type 'MoToStepper'
mysteppers[4]->doSteps(400);
^~
Using library MobaTools-master at version 2.4.3 in folder: C:\arduino-nightly\libraries\MobaTools-master
exit status 1
use of deleted function 'MoToStepper::MoToStepper(MoToStepper&&)'

You did not do it exactly as in my suggestion. You must only use curly braces!

1 Like