Pages: [1]   Go Down
Author Topic: While loop questions.  (Read 1181 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)

Code:
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);
   }
 }
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 300
Posts: 26219
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 610
Posts: 49071
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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

This should do it.
Code:
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);
}
}
}
Logged

Seattle, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 35
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...
Code:
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++;
                }
}
}
Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 7
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Code:
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!


« Last Edit: July 06, 2011, 06:57:07 pm by davekw7x » Logged

Australia
Offline Offline
Jr. Member
**
Karma: 0
Posts: 99
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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".
Logged

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

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...
Code:
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.
Logged

Massa, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 172
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
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);
Logged

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

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.

Code:
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;
    }
  }
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 34
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: