Accelstepper Sequential Movement

Hi,

I'm using an R3 with an Adafruit V2 Motor Shield to drive two stepper motors for my robot. I'm using Accelstepper and it works well for single move "Switch" commands using a bluetooth controller for Forward, Backward, Left, Right, etc.. However, when I try to string two or more move commands into a sequence, it will only run the first part of the sequence. I've searched the forum for solutions, but haven't found anything to address my issue. Basically I'd like to move two motors in opposite directions, in tandem, first to one position, then to another position, etc.

Here's the (partial) switch code that works for basic forward movement (the complete code is attached):

.......
void goRun ()
{
Astepper1.run();
Astepper2.run();
}
.........
case 'f': // forward 300 steps (about 3')
Astepper1.move(300);
Astepper2.move(-300);
goRun();
break;

Here's the (partial) switch code that DOES NOT work for a simple sequential straight/left turn movemovement:

.......
void goRunTo ()
{
Astepper1.runToPosition();
Astepper2.runToPosition();
}
.........
case 'T': // forward 300 steps (about 3') and then make a left turn (73 steps)
Astepper1.moveTo(-300);
Astepper2.moveTo(300);
goRunTo;
delay(1000);
if (Astepper1.distanceToGo()==0)
Astepper1.move(73);
Astepper2.move(-73);
goRunTo;
break;

If anyone has any suggestions, let me know. Thanks

ChaunceyV4.3.2Accelstepper.ino (9.8 KB)

Don't use runToPosition(). Just use the regular run() function called from loop() and change the destination as required.

Make sure the loop() repeats very quickly - hundreds or thousands of times per second.

...R

runToPosition() is the blocking call - don't use blocking calls if you want drive several motors at once!

moveTo () and move() are non-blocking and you can call distanceToGo(), targetPosition() and currentPosition()
to check on progress.

Make sure loop runs often and that you call run() inside if for each motor.

Thank you so much for the fast responses. I really appreciate the suggestions. Here is what I tried but it still doesn't work. One motor turns forward about 300 steps, the other starts to turn then stops very quickly. Maybe I don't understand how the loop () is supposed to be called. I also tried introducing delay(1000) but that doesn't work at all. I also used moveTo, but that also does not work correctly.

.......
void goRun ()
{
Astepper1.run();
Astepper2.run();
}
.........
case 'T': //forward 300 steps then left 100 steps, then backwards 500 steps, sequentially
loop();
{
Astepper1.move(-300);
Astepper2.move(300);
if (Astepper1.distanceToGo()==0)
Astepper1.move(100);
Astepper2.move(100);
if (Astepper1.distanceToGo()==0)
Astepper1.move(500);
Astepper2.move(-500);
goRun;
}
break;

Here I am trying to simplify even more to see what is going wrong:

case 'T': //forward 300 steps then left 100 steps
loop();
Astepper1.move(-300);
if (Astepper1.distanceToGo()==0)
Astepper1.move(100);
Astepper1.run();
serial.println(Astepper1.distanceToGo());
break;

When I run this code, the motor turns about -300 steps, and the Print Line returns distance to go = -299

I'm very confused.

dave1700:
I'm very confused.

Indeed.

Because there is so much confusion I think the best thing is for you to start over again with one the examples from the AccelStepper website. Get it working with a single motor. Then make a copy of the working program and extend the copy to include a second motor. If you run into a problem post the program.

Just to illustrate some of the confusion ...

You don't call loop() - the Arduino system does that for you and causes the loop() function to repeat indefinitely.

This goRun; does not do anything. To call a function you need goRun();

Have a look at Planning and Implementing a Program to seethe proper program structure.

...R

thanks very much. You might not have noticed in my third post I did exactly what you suggested, I got it down to one motor and eliminated the extra run function. I've reprinted this again below in case you missed it. I've spend about 30 hours trying to figure this out on my own before I posted, and I've gone through every example in the accelstepper documentation. I have yet to find one that uses switches to control a sequence of moves. But, thanks anyway for your suggestions. I do appreciate the time you invest in trying to help others.

case 'T': //forward 300 steps then left 100 steps
loop();
Astepper1.move(-300);
if (Astepper1.distanceToGo()==0)
Astepper1.move(100);
Astepper1.run();
serial.println(Astepper1.distanceToGo());
break;

When I run this code, the motor turns about -300 steps, and the Print Line returns distance to go = -299

FYI, I've decided to abandon the Accelstepper Library for this part of my code. I can get everything to work perfectly without that library using a "for" condition and incrementing the motor steps (ie. the brute force method).

Thanks anyway for your help.

dave1700:
I've reprinted this again below in case you missed it.

...SNIP....

case 'T': //forward 300 steps then left 100 steps
loop();
Astepper1.move(-300);
if (Astepper1.distanceToGo()==0)
Astepper1.move(100);
Astepper1.run();
serial.println(Astepper1.distanceToGo());
break;

You seem to have missed the bit where I said this is wrong.

And you need to post a complete program - not just a snippet.

I repeat my suggestion to start over with one of the Accelstepper example programs.

...R

1 Like