Hi all, this is my second project, so I'm still a newbie . For my project I've got an Aruino Uno and 3 steppermotors (steppermotorA, steppermotorB, and steppermotorC).
If the loop starts I want steppermotorA to move to its new position. When steppermotorA is still moving, I want steppermotorB to begin after 1 second to move to its new position. When steppermotorA and steppermotorB are still moving, I want steppermotorC to begin after again 1 second to move to its new position. The idea is that every next steppermotor begins after 1 second.
When each steppermotor has reached its new position, I want them to wait until all of the movements are finished. After that the loop may starts again.
I'm trying to get this done with Millis. It's my first time that I'm trying to use this code.
Here is my code so far;
#include "AccelStepper.h"
unsigned long previousMillis_1 = 0;
unsigned long previousMillis_2 = 0;
unsigned long previousMillis_3 = 0;
unsigned long previousMillis_4 = 0;
unsigned long previousMillis_5 = 0;
unsigned long previousMillis_6 = 0;
const long move_stepperA_1 = 1000;
const long move_stepperB_2 = 2000;
const long move_stepperC_3 = 3000;
const long move_stepperA_4 = 4000;
const long move_stepperB_5 = 5000;
const long move_stepperC_6 = 6000;
// MOTOR A
AccelStepper stepperA(1, 3, 2);
// 1 = Type Driver interface
// Pin 2 connected to STEP pin
// Pin 3 connected to DIR pin
// MOTOR B
AccelStepper stepperB(1, 5 , 4);
// 1 = Type Driver interface
// Pin 4 connected to STEP pin
// Pin 5 connected to DIR pin
// MOTOR C
AccelStepper stepperC(1, 7, 6);
// 1 = Type Driver interface
// Pin 6 connected to STEP pin
// Pin 7 connected to DIR pin
// Stepper Travel Variables
long initial_homing = -1000;
// --------------------------------------------------------------------------------------------------------
void setup() {
stepperA.setMaxSpeed(100.0);
stepperA.setAcceleration(200.0);
stepperB.setMaxSpeed(100.0);
stepperB.setAcceleration(200.0);
stepperC.setMaxSpeed(100.0);
stepperC.setAcceleration(200.0);
}
//--------------------------------------------------------------------------------------------------------
void loop() {
unsigned long currentMillis = millis();
// (1)
if (currentMillis - previousMillis_1 >= move_stepperA_1)
previousMillis_1 = currentMillis;
stepperA.moveTo(-1500);
while
(
stepperA.currentPosition() != -1500
)
{
stepperA.run();
}
//--------------------------------------------------------------------------------------------------------
// (2)
if (currentMillis - previousMillis_2 >= move_stepperB_2)
previousMillis_2 = currentMillis;
stepperB.moveTo(1500);
while
(
stepperB.currentPosition() != 1500
)
{
stepperB.run();
}
//--------------------------------------------------------------------------------------------------------
// (3)
if (currentMillis - previousMillis_3 >= move_stepperC_3)
previousMillis_3 = currentMillis;
stepperC.moveTo(-1500);
while
(
stepperC.currentPosition() != -1500
)
{
stepperC.run();
}
//--------------------------------------------------------------------------------------------------------
// (4)
if (currentMillis - previousMillis_4 >= move_stepperA_4)
previousMillis_4 = currentMillis;
stepperA.moveTo(-250);
while
(
stepperA.currentPosition() != -250
)
{
stepperA.run();
}
//--------------------------------------------------------------------------------------------------------
// (5)
if (currentMillis - previousMillis_5 >= move_stepperB_5)
previousMillis_5 = currentMillis;
stepperB.moveTo(250);
while
(
stepperB.currentPosition() != 250
)
{
stepperB.run();
}
//--------------------------------------------------------------------------------------------------------
// (6)
if (currentMillis - previousMillis_6 >= move_stepperC_6)
previousMillis_6 = currentMillis;
stepperC.moveTo(-250);
while
(
stepperC.currentPosition() != -250
)
{
stepperC.run();
}
//--------------------------------------------------------------------------------------------------------
// END
}
I am not familiar with the AccelStepper library but this
stepperA.moveTo(-1500);
while
(
stepperA.currentPosition() != -1500
)
{
stepperA.run();
}
looks wrong because nothing in the while loop changes the value of stepperA.currentPosition() as far as I can see, so the code will not exit the while loop
Does that match what you are seeing when you run the sketch ?
Put a Serial.print() inside the while loop to see whether it gets stuck and what the value of stepperA.currentPosition() is
You said you wanted while stepper A is still moving to start stepper B moving after 1 sec. What you coded is Start stepper B after stepper A has finished moving.
I think the .run function updates the .currentPosition, but I am too lazy to go look. If it doesn't, then yes the while never ends, but even if it does, the code does not do what he wants.
I haven't played with steppers for a while, but are not the whiles totally not needed? Logic needs to be time (millis()) based with all runs at the bottom of the main loop. Here is how .run works from the library info
The run() function must be called frequently until the motor is in the desired position, after which time run() will do nothing.
I don't need to read more carefully thanks, I can see it is an example that shows the position is initialised before the main loop.
Whether the example does something useful or not is not the point.
If this is in the main loop of the program it will continually initialise.
It is, but the code is very strangely formatted. With proper formatting the while loop looks like:
while ( stepperA.currentPosition() != -250 )
{
stepperA.run();
}
And yes, the run() function updates the current position.
But the while loop is blocking until the stepper reaches its target. No other stepper can be started during this time. The advice of @gcjr in post #8 is correct.
Or @jodo82 could use the MobaTools library. His goal could be reached much more easy , because there is no need to cope with step generation in the sketch ( no run() function needed )-
Yes, but the point is it doesn't have to be that way, the OP knows he needs some sort of millis() code, what he doesn't know (at that point) is how the run member works.
Which is why I pointed this out with just one example chosen from many examples of how it should be written.
The point is that that particular command should be in setup and the move() command should be in the main loop instead.
Here is the actual function inside the class:
void moveTo(long absolute);
The OP is going around the loop and setting an absolute position each time.
with the move command function.
void move(long relative);
Using the move(new position) function at the end of the loop along with the run()
Create a new variable to hold the next position data: long new_position, then as an example:
stepperXmove(new_position);
stepperX.run()
"This is a pretty advanced, compressed code that uses all features the C++-language offers to write a code that is very compact and therefore hard to analyse.
It uses
non-blocking timing
arrays
the -> syntax
short and therefore hard to understand variable names
sprintf
So gcjr's code offers to learn 5 chapters of C++ programming where you have to find yourself the source (Book, onlinetutorial or whatever ) that explains all the code-features
or you can
If you have any questions about my code ask as many questions as you like
If you find my code too much "above your head" just skip my posting.
it uses a table (array) of cmds to be executed at specific times that update the target position of a motor. It repeats processes the table of commands
it doesn't require an understanding of programming to uedit the table entries. Each command specifies a motor, a time (msec) and postion.
I see the strange formatting now. I have learned myself to put everything seperate. My fault...
I have used the code from @gcjr and it works great. Don't know exactly how the code works, but it does what It needs to do. I'm gonna study it so I gonna know why it does what it does. Thanks a lot for that and all the other tips and advices!