While loop questions.

I am curious about whether or not it is possible for two while loops to run at once. I have a command I have created that I think should move two motors at once, but now I'm not 100% sure that it's doing what I want it to do. It appears that the first motor moves before the second, so I'm curious if there's a way to make it run both motors at once. (both motor objects are declared earlier along with the applicable library)

 void doublestep (int steps1, int steps2, int dir1, int dir2, int style1, int style2) {
   while (steps1--) {
     motor1.step(1, dir1, style1); 
   }
   while (steps2--) {
     motor2.step(1, dir2, style2); 
   }
 }

No, those loops run consecutively, not "at once" (aka simultaneously).
Yes, you can make them appear to run simultaneously.

If the number of steps in each loop is different, you need to actually create 3 while loops - one for all common values, 1 if loop one is longer, and the third is loop 2 is longer. Of course, you only run two of the 3 loops.

This should do it.

void doublestep (int steps1, int steps2, int dir1, int dir2, int style1, int style2) {
	while (steps1 || steps2) {
		if (steps1--) {
			motor1.step(1, dir1, style1); 
		}
		if (steps2--) {
			motor2.step(1, dir2, style2); 
		}
	}
}

wdl1908: I believe negative int's evaluate to true in c/c++, so your code would not work. I have not tested this, though. I think this would fix it...

void doublestep (int steps1, int steps2, int dir1, int dir2, int style1, int style2) {
	while (steps1 || steps2) {
		if (steps1--) {
			motor1.step(1, dir1, style1); 
		}
                else{ 
                        steps1++;
                }
		if (steps2--) {
			motor2.step(1, dir2, style2); 
		}
                else{
                       steps2++;
                }
	}
}

wdl1908:
This should do it.

No, it won't. If the value of steps1 is not equal to the value of steps2, it's an infinite loop. (Why not test it?)

Maybe something along the lines of

void setup()
{
    Serial.begin(9600);
}
void loop()
{
    int steps1 = random(1,10);
    int steps2 = random(1,10);
    Serial.print("Calling doublestep(");
    Serial.print(steps1);
    Serial.print(",");
    Serial.print(steps2);
    Serial.println(")");
    doublestep(steps1, steps2);
    delay(10000);
    Serial.println();
}

void doublestep (int steps1, int steps2)
{
    while (steps1 || steps2) {
        if (steps1) {
            Serial.print("steps1 = ");
            Serial.println(steps1);
            --steps1;
        }
        if (steps2) {
            Serial.print("steps2 = ");
            Serial.println(steps2);
            --steps2;
        }
    }
}

Where for test purposes I just printed out the steps. (And I gave enough delay between passes that you might be able to count them each time.)

Regards,

Dave

Footnote:
This would move motors 1 and 2 together until one of them had moved far enough, and the other would continue moving until it was finished.

A more interesting programming problem (and, maybe a more elegant and better-behaved machine) might be to distribute the moves as equally as possible between the two motors. A recent thread mentioned one possible approach, but I haven't tried it. (I think I could brute-force it with simple integer arithmetic rather than lisp-like lists, but...)

For all of you folks who think you wish the developers had chosen something other than C++ as the base language for Arduino, look at the example given in one of the references and rejoice (or not) that they didn't choose Lisp!

A more interesting programming problem (and, maybe a more elegant and better-behaved machine) might be to distribute the moves as equally as possible between the two motors. A recent thread mentioned one possible approach, but I haven't tried it. (I think I could brute-force it with simple integer arithmetic rather than lisp-like lists, but...)

Bresenham's Line Algorithm will do the work for you. http://en.wikipedia.org/wiki/Bresenham's_line_algorithm

In the Wikipedia article, make the x-axis the motor that has to move the furthest (motor 1), and y the other one (motor 2). Each time through the loop step Motor 1 and only step Motor 2 when you see "y = y + 1".

tedcook:
wdl1908: I believe negative int's evaluate to true in c/c++, so your code would not work. I have not tested this, though. I think this would fix it...

void doublestep (int steps1, int steps2, int dir1, int dir2, int style1, int style2) {
while (steps1 || steps2) {
	if (steps1) {
		steps1--;
		motor1.step(1, dir1, style1); 
	}
	if (steps2) {
		steps2--;
		motor2.step(1, dir2, style2); 
	}
}

}

Yeah sorry it was late. That is the problem with using statements like step1-- you always forget the side effects until you start thinking about it.

The above code should work.

In my opinion, if it is not a comparison with NULL or a Boolean comparison (true or false), for the numbers is best == 0 or != 0 ... (even if you've written in C as it works too)

I prefer this anyway:

while (steps1 > 0 && steps2-- > 0) {
	motor1.step(1, dir1, style1); 
	motor2.step(1, dir2, style2);
	step1--;
}
while (steps1-- > 0)
	motor1.step(1, dir1, style1); 
while (steps2-- > 0)
	motor2.step(1, dir2, style2);

Thanks to everyone for the help! After looking over what some of the ideas are, I finally used this as the function I made. I am not certain if the "else" statements are 100% necessary and if it is just easier to have the two "if" statements by themselves since their "then" parts won't execute once each stepping variable is at 0. I figured it would be a good thing to have to make sure that the test in the while loop returns false.

void doublestep (int steps1, int steps2, int dir1, int dir2, int style1, int style2) {
  while (steps1 || steps 2) {
    if (steps1 > 0)  {
      motor1.step(1, dir1, style1); 
      steps1--;
    }
    else  {
      steps1 = 0;
    }
    if (steps2 > 0)  {
      motor2.step(1, dir2, style2); 
      steps2--;
    }
    else  {
      steps2 = 0;
    }
  }
}

TedCook said: I believe negative int's evaluate to true in c/c++, so your code would not work.

if(...) and while(...) are looking for a True/False question where the ... is.
Usually you see something like:
while(score > 0)
if(myScore >= yourScore)
etc.

It gets a little strange when the comparison operators are not used.

C, C++, VB and many other languages treat:

if(steps)

is still evaluated as a comparison because it converts "if(steps)" to be "if(steps <> 0)" or "if steps is non-zero", which is why positive and negative values both evaluate to true.