#include <AccelStepper.h>
#include <Bounce2.h>
#define NUM_BUTTONS 2
const int dirPin1 = 4;
const int stepPin1 = 5;
const int dirPin2 = 6; // Pins for the second stepper motor
const int stepPin2 = 7;
const int motorInterfaceType = 1;
bool start1 = false;
bool start2 = false;
bool movingFirstStepper = false;
bool movingSecondStepper = false;
const int buttonPin[NUM_BUTTONS] = {2, 3};
AccelStepper myStepper1 = AccelStepper(motorInterfaceType, stepPin1, dirPin1);
AccelStepper myStepper2 = AccelStepper(motorInterfaceType, stepPin2, dirPin2);
Bounce2::Button button[NUM_BUTTONS] = {Bounce2::Button()};
void setup()
{
Serial.begin(9600);
for (byte i = 0; i < NUM_BUTTONS; i++)
{
button[i].attach(buttonPin[i], INPUT_PULLUP);
button[i].setPressedState(LOW);
button[i].interval(5);
}
myStepper1.setMaxSpeed(1000); // Set a higher speed for the first stepper motor
myStepper1.setAcceleration(300); // Set acceleration for the first stepper motor
myStepper2.setMaxSpeed(1000); // Set a higher speed for the second stepper motor
myStepper2.setAcceleration(300); // Set acceleration for the second stepper motor
}
void loop()
{
for (byte i = 0; i < NUM_BUTTONS; i++)
{
button[i].update();
if (button[0].fell())
{
Serial.println("Start button pressed");
start1 = true;
}
if (button[1].fell())
{
Serial.println("Stop button pressed");
start1 = false;
myStepper1.stop();
myStepper2.stop();
myStepper1.setCurrentPosition(0);
myStepper2.setCurrentPosition(0);
}
}
if (start1)
{
if (!movingFirstStepper)
{
myStepper1.move(200);
movingFirstStepper = true;
}
if (myStepper1.distanceToGo() == 0 && !movingSecondStepper)
{
myStepper2.move(100);
movingSecondStepper = true;
}
myStepper1.run();
myStepper2.run();
if (movingFirstStepper && myStepper1.distanceToGo() == 0 && movingSecondStepper && myStepper2.distanceToGo() == 0)
{
myStepper2.moveTo(0);
movingFirstStepper = false;
movingSecondStepper = false;
}
}
}
I already have created more or less the code I desire to run. My only problem as of right now is that I desire stepper2 to move back to its 0 position from the 100 steps before stepper1 engages again moving 200 steps. If anyone could solve my problem and write the code or explain what I could change I would appreciate it as I have been stuck for hours...
Would that make any difference in the overall result that I want? If I am being honest I just started coding and lost my patience the more I added to the code
What you have coded here is a if-condition that uses the logical and operator.
Only in case
each partial condition as there are
movingFirstStepper == true
and
myStepper1.distanceToGo() == 0 // stepper1 has finished his 200 steps
and
movingSecondStepper == true
and
myStepper2.distanceToGo() == 0 // stepper2 has finished his 100 steps
which means the condition all in all becomes only true
if your stepper1 has finished his 200 steps
You will have to write code with two different conditions
one for stepper1
and one for stepper 2
seems like you need a sequencer. you're already doing something similar within the start1 condition but could make it more explicit.
instead of using an if statement, add a state variable indicating what it being done, including an IDLE and START states and use a switch statement to invoke the code for each state
the IDLE state does nothing. Pressing a button changes state to START which invokes myStepper1.move(200); and set state to the next state, MOVE_1, for example.
the MOVE_1 state waits for motor 1 to reach it's destination, starts the 2nd motor moving and advances to the next state, MOVE_2
the MOVE_2 state is similar to MOVE_1, waiting for the 2nd motor to reach it's desitination. When it does, sounds like you want the 2nd motor to move back to its original position, myStepper2.move(-100);. invoke those commands and advance to the next state, RETURN_2.
the RETURN_2 state is similar to the others, waiting for the 2nd motor to reach it's destination. When it does, it sounds like you want to start the 1st motor moving again and can advance to the MOVE_1 state
pressing a button could invoke some commands to stop the motors and enter a state that waits for both motors to reach their destinations and move the IDLE state
Not sure if this description describes all details,
@calisifer
You should write a posting where you describe the movements in normal words without any code.
moving 200 steps sounds like one complete rotation = 360°
moving 100 steps sounds like half a rotation = 180°
Is this correct?
So my understanding of what the two steppermotors shall do is
stepper1 rotates 200 steps
at the same time as stepper1 starts to rotate
stepper2 starts to rotate 100 steps
when stepper1 has reached his target (= 200 steps)
stepper2 shall rotate back 100 steps
when stepper2 has finished rotating back 100 steps
stepper2 shall do his next 200 steps.
It is unclear if these are the movements that you want to have.
So please confirm or correct this description.
When you have posted this description the correct code can be written.
Hey Stefan,
Thanks for being willing to help. The description would be that I desire the first button to do a full rotation and once it reaches that full rotation only then will the second stepper do a 180° rotation which should go back to its original position and then the first stepper can rotate 360° again.
by linear sequence do you mean something like the following. the sequence is started and runs to completion each time the button is pressed. Since the sequence runs to completion, it blocks, buttons aren't checked and the sequence can't be interrupted
void loop ()
{
for (byte i = 0; i < NUM_BUTTONS; i++) {
button[i].update ();
if (button[0].fell ()) {
Serial.println ("Start button pressed");
myStepper1.move (200);
while (myStepper1.distanceToGo () != 0)
myStepper1.run ();
myStepper2.move (100);
while (myStepper2.distanceToGo () != 0)
myStepper2.run ();
myStepper2.move (0);
while (myStepper2.distanceToGo () != 0)
myStepper2.run ();
if (button[1].fell ()) {
Serial.println ("Stop button pressed");
myStepper1.stop ();
myStepper2.stop ();
myStepper1.setCurrentPosition (0);
myStepper2.setCurrentPosition (0);
}
}
}