Running 2 Steppers Synchronously

So this may just be a misunderstanding on my part, but I am attempting to move 2 separate motors synchronously, at the same time.

I found the Arduino stepper library, and I looked into the function it provides and implemented the myStepper.step(##) (##=number of steps) function the library includes, but when I read the description of the line, it said it was "blocking", as in it will not give control to the next line until it finishes.

So the potential misunderstanding here is:

If i put two lines of the above mentioned function (myStepper.step(##)), 1 right after the other, will both motors run? or will 1 run then the other? If the latter is true, then how would I run both? Could I put both step commands on the same line?

Here is a snippet of the code I am trying to write:

#include<Stepper.h>
Stepper motor1=Stepper(48,4,5);
Stepper motor2=Stepper(48,6,7);
Stepper motor3=Stepper(48,8,9);
Stepper motor4=Stepper(48,10,11);
char val;
void setup()
{
motor1.setSpeed(30);
motor2.setSpeed(30);
motor3.setSpeed(30);
motor4.setSpeed(30);
Serial.begin(9600);
}

void loop()
{
val='Still';
if(Serial.available())
{
val=Serial.read();
}
if(val=='forward')
{
motor1.step(24); //Right here is where I am confused.
motor2.step(24);
}
if(val='backward')
{

}

{
    motor1.step(24); //Right here is where I am confused.
    motor2.step(24);
  }

becomes

{
  for ( int s=0; s<24; s++){
    motor1.step(1); 
    motor2.step(1);
    delay(10);    // yes! The dreaded DELAY - but justified here, perhaps
  }
 }

A few more points - the speed and step/revolution settings earlier on have no meaning when you do single step. It is effected immediatly. Thus you need to have a delay. As you can see the loop is "blocking" in the sense that we do not proceed further in the program until all 24 steps have been made. Rewriting this to non-blocking is more than a simple mail-replay

The AccelStepper library handles moving two or more steppers at the same time, in non-blocking fashion.

While the AccelStepper library does allow for non-blocking movement of the motors it does not guarantee synchronism of the sort that would be required, say, to move motorA 237 steps in the same time that motorB moves 83 steps. See this reference.

This simple stepper code (especially the second example) can be adapted to provide synchronised movement. See also stepper motor basics.

...R

I need only to have both motors move a roughly the same time for roughly the same time. If there is a slight delay between the two (like only a couple of steps) then that is fine. I intentionally decided on motors with high torque because of that acceleration issue (figured that something like that might exist). So I have accelstepper in my libraries now, but I am looking through and the description of its functions and such as rather difficult to understand. All I need is to move each of my motors forward and/or backward. (Forward/Backward is motors 1&2, Left/Right is 3&4, And the diagonal directions inbetween such as Forward-Right and Backward-Left are all 4 motors at the same time.

Sorry for the bit of wall of text, but I think I should explain my project here.

I need 4 motors (2 "paired" sets of 2) to move at certain times in order to position a weight held within a sphere at different points along the sphere, which will cause gravity to cause the sphere to move until the weight is "downwards" essentially meaning the 4 motors are rotating the sphere. The system is a little complex (not too bad) but the motors simply need to move on command from my arduino nano (I am using a sparkfun dual h-bridge tb661 motor driver) forwards or backwards based on what direction im moving the sphere.

I've figured out all the wiring, and I came very close to the code I needed, but that blocking step function has, well blocked me. And this AccelStepper library appears to be the solution but I cannot understand how it has been organized T.T Im too novice.

Also, I cannot single-step. The sphere has to move at a reasonable speed, and the single step you've placed would rotate my sphere approximately 13.5/217 notches every second, or about 23 degrees, I need at least 40 per second, or roughly 1 full sphere rotation every 9 seconds or roughly 241 rpm! Which i now realize is wayyy more than 30 XD. I'll have to edit the Driven/Driving gear ratio until 30RPM is what is needed, but the general idea remains the same.

We love to hear about "what the project is about", no need to applogize for that text.

It seems to me that both suggestions are appropiate, both the loop with single steps (you can reduce the delay, and it goes quicker) and the AccelStepper library, where you issue the move commands to two motors which then run close to synchronous. Have you tried, even with just the motors sitting on the desk?

And what is still not working the way you need to?

You have some codeing issues - even allowing for this is "a snippet" of the code.

if(val=='forward')

makes no sense to me. The single ' quote is for a character, ie

if(val=='f')

I just took the trouble to cut-n-paste your code, compile it and look at the generated machine code. Those invalid lines are simply ignored (at least in my older 1.0.5 IDE) - no code generated for them, no error messages.

Do not start using Strings. Keep your commands to single characters.

Dicerson:
the single step you've placed

WHO has placed?

None of the code I posted limits you to slow speeds.

If there is some accelStepper code that you don't understand you will have to tell us what it is if you want advice. Post your code.

...R

Sorry if it seems like im wasting anyone's time.

Msquare:
We love to hear about "what the project is about", no need to applogize for that text.

It seems to me that both suggestions are appropiate, both the loop with single steps (you can reduce the delay, and it goes quicker) and the AccelStepper library, where you issue the move commands to two motors which then run close to synchronous. Have you tried, even with just the motors sitting on the desk?

And what is still not working the way you need to?

You have some codeing issues - even allowing for this is "a snippet" of the code.

if(val=='forward')

makes no sense to me. The single ' quote is for a character, ie

if(val=='f')

I just took the trouble to cut-n-paste your code, compile it and look at the generated machine code. Those invalid lines are simply ignored (at least in my older 1.0.5 IDE) - no code generated for them, no error messages.

Do not start using Strings. Keep your commands to single characters.

The thing with that single step is each "pair" of motors is connected to the same driven gear, so if one moves without the other, or tries to do so, for even a single step, it'll jam and not move, or at most move very slowly. They need to at least move or be moving at the same time for an extended period of time, preferably one rotation per call of the if function. Also, thanks for pointing out that string thing (no rhyme intended!) I had no idea! I've figured out how to get my driven/driving gear ratio to be 30RPM a second for 10cm/second movement, so all I need is to figure out which of the functions within the AccelStepper library actually causes the motors to move. As it is I am having a hard time understanding each individual function, many of them seem to refer to the same thing about moving or running to some position, and I cannot tell which ones I need or what code I need to write to make each pair of motors move based on what character they receive from a bluetooth device that will be connected to my arduino.

I think you have most pieces of your project. Perhaps though you should test individual sub-systems and get them working before you start final assembly.

On a table put two of your stepper motors (no gear or anything mechanical). Hook up the motordriver chip and to the Arduino. Write or copy a simple program to move the motors to and fro, even without any commands. Just stepper.step() and a delay() in the loop, so it does the test over and over. Now you can experiment with the stepper library, accelstepper or the step(1) I outlined until you are confident you understand how the commands do move the motors.

Next a simple mechanical test if they move synchronously. With a bit of tape join the axis of the two motors (ie if one turns it will turn the other). Modify the program that tiny bit so they turn opposite, but still within your framework of moving together. If they turn at the same time they should just turn the axis. If they are not "in step" they will wiggle or flipflop wildly on your table.

At some point you can modify the program to include Serial.read() and read a single character which determines which motor moves and how mauch. You decide what character does which. A suggestion would be 'A' moves the first motor 24 steps, 'B' the second and so on. 'a' move the first motor backwards 24 step... and maybe the 'E'..'H' does it twice as far or fast. Or as you wantto move in pairs decide that 'A' moves 1&2 in pair forward. It is your protocol.

To test the above open the serial monitor. Make sure you set "line ending" to none. Better is to use a teminal emulator (like PuTTY) then every character is sent immediatly you touch the key.

Good luck. Yes, you are allowed to ask more questions.

Dicerson:
The thing with that single step is each "pair" of motors is connected to the same driven gear,

That sounds like a situation where you feed a single STEP instruction to two stepper drivers. That way they are guaranteed to stay in sync. As far as the code is concerned there would only be one motor.

...R

I bypassed the arduino stepper library - I don't like it, and the blocking aspect of it is a killer. What you actually have to do to drive the pins of a stepper properly just isn't that hard.

The function below is hard-coded to pins 4/5 for the first stepper, and 6/7 for the second.

// I assume that the stepper is already oriented as per the 'position' input. If it isn't - meh.
// I return position so that it becomes easy to write
//   position = move4567(position, 5, true, 100);

int move4567(int position, int nSteps, boolean forward, unsigned long msDelay ) {
  while(nSteps-- > 0) {
    if(forward) position ++;
    else position--;

    digitalWrite(4, (position>>1) & 1);
    digitalWrite(5, (position ^ (position>>1))  & 1);

    digitalWrite(6, (position>>1) & 1);
    digitalWrite(7, (position ^ (position>>1))  & 1);

    delay(msDelay);
  } 
  return position;
}

The key is taking advantage of how the pattern of bits in a number changes as you increment it.

00000
00001
00010
00011
00100
00101 -- etc

The only ones I am interested in are the leftmost two bits. One pin of the motor is driven by the '2s' bit of the number. The >> 1 shifts the bits over by one, and the &1 truncates everything except the last bit.

The second pin is trickier. It's driven off whether or not the 2s and the unit bit of the number are equal. As you can se, the "2s" bit, and the "1s bit==2s bit" move in quadrature, which is what we need.

So the >>1 shifts the bits over, the ^ operator performs a bitwise not-equal-to, and the &1 truncates everything except the last bit.

I bypassed the arduino stepper library - I don't like it, and the blocking aspect of it is a killer. What you actually have to do to drive the pins of a stepper properly just isn't that hard.

The function below is hard-coded to pins 4/5 for the first stepper, and 6/7 for the second.

// I assume that the stepper is already oriented as per the 'position' input. If it isn't - meh.
// I return position so that it becomes easy to write
//   position = move4567(position, 5, true, 100);

int move4567(int position, int nSteps, boolean forward, unsigned long msDelay ) {
  while(nSteps-- > 0) {
    if(forward) position ++;
    else position--;

    digitalWrite(4, (position>>1) & 1);
    digitalWrite(5, (position ^ (position>>1))  & 1);

    digitalWrite(6, (position>>1) & 1);
    digitalWrite(7, (position ^ (position>>1))  & 1);

    delay(msDelay);
  } 
  return position;
}

The key is taking advantage of how the pattern of bits in a number changes as you increment it.

00000
00001
00010
00011
00100
00101 -- etc

The only ones I am interested in are the rightmost two bits. One pin of the motor is driven by the '2s' bit of the number. The >> 1 shifts the bits over by one, and the &1 truncates everything except the last bit.

The second pin is trickier. It's driven off whether or not the 2s and the unit bit of the number are equal. As you can se, the "2s" bit, and the "1s bit==2s bit" move in quadrature, which is what we need.

So the >>1 shifts the bits over, the ^ operator performs a bitwise not-equal-to, and the &1 truncates everything except the last bit.

Thank all of you! I finally figured out what functions I need and how to synchronize my motors!

I will be doing a bit more testing under certain loads to make sure I can make my motors move as fast as I need them to, but it shouldn't take too long.

Thank you again!

My remote controlled sphere is a go!