Two steppers controlling position

After posting this I realized my algorithm doesn't work. Ignoring that, I'd still like to understand why the code shown has a problem.

I have a circular disk, and two motors controlling the location of a point on the disk.
I can't go off the disk.

I drive belts, and microstep 2, accel 400, maxSpeed 1600.

This code works almost exactly as I want:

    stepperX.moveTo(xDI);
    stepperY.moveTo(yDI);

    while ((stepperX.distanceToGo() != 0) || stepperY.distanceToGo() != 0) {
        stepperX.run();
        stepperY.run();
    }

However, I need to control which stepper moves, since moving together (on a 45deg angle) will go off the disk in some situations.

My (not so) clever idea:

stepperX.moveTo(xDI);
    stepperY.moveTo(yDI);

    while ((stepperX.distanceToGo() != 0) || stepperY.distanceToGo() != 0) {
      if (stepperX.distanceToGo() > stepperY.distanceToGo() ) {
        stepperX.run();
      } else {
        stepperY.run();
      }
    }

Neither stepper moves.

I then added diagnostic monitor println() to the code, and found the while loop loops, and the if statement executes in the loop, but the else never happens.
So it loops happily forever.

Of course if the x dist is greater than the y dist, and the stepper doesn't move, the while() and if() never change, so the infinite loop makes sense.
But why does the stepper work in the first case and not the second?

Is this something to do with stepper.run() ??

I find the documentation foggy. Or it more probably is me....

Thanks in advance!

this issue seems to come up often enough

in this case, is the path more important than simply reaching some position.

if you had to move the x motor 10 steps and the y motor 100, would you want them to reach the end point at the same time? would you always want the path to be a straight line?

given some maximum time for either motor to reach the endpoint, why not delay the steps for the other motor so that each motor reaches the endpoint at the same time and step each motor on step at a time?

As I stated, I am interested in understanding why the code above doesn't work when a seemingly innocuous if() is added, not the algorithmic issues (which is the fun part).

Do you have insights for the described code behavior?
Thanks.

Inside the while loop, before the if statement, can you print out

  • stepperX.distanceToGo()
  • stepperY.distanceToGo()

...and provide the output

1 Like

wow, that's great.
When you requested that, I thought it a strange request.
"The stepper hasn't moved so there are distances to go" I thought...

Turns out, not.

So a confluence of problems all came together.
The distanceToGo x was zero before and after the while()
For y it was -1000.
That explains why the while was entered. (ydist != 0)
And x distance was greater than y distance, so that is why the if() was entered, the stepper didn't move because there was no move needed, and the else() was not entered, since the if() was entered.

And it explains why the if() screwed up a working program.

Solved.

I guess my take away is to put in diagnostic prints to dump more variables, even if I think I know what those are.
"Kilroy was here" messages are not nearly as useful as variable values.

Thanks for the lesson!

Now on to the fun part if figuring out a fast functioning algorithm to always stay in bounds.
I appreciate your help!

Serial.print statements are probably the best thing in your debugging toolbox. Assuming what a variable contains, is never quite as good as seeing what a variable contains. :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.