AccelStepper help

I have a feeling this is not how the code should look. I am trying to run a few commends in sequence for a robotic arm using 3 stepper motors, 1 is for the X axis using a timing belt, 2 is for an arm to rotate 3 is to turn a key.I am tiring to code a sequence of commends that will be crried out ina specific order and length of time. Pleac can you help me and tell me what I am missing or doing wrong. FYI it works perfectly as it is.

This is the code running on an arduino:

       #include <Stepper.h>
       #include <AccelStepper.h>
         
       #define STEPS_PER_MOTOR_REVOLUTION 32   
       #define STEPS_PER_OUTPUT_REVOLUTION 32 * 64  //2048 
       //Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11)(9 X-,1= 10 Y-,2= 11 Z-,3= 12 SpinEn,4= 13 SpinDir);
       Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 10, 12, 11, 13);
       int  Steps2Take;
       
AccelStepper Xaxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Qaxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Waxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Uaxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Yaxis(1, 3, 6); // pin 4 = step, pin 7 = direction
AccelStepper Zaxis(1, 4, 7); // pin 5 = step, pin 8 = direction
boolean runonce = true;
boolean runonce2 = true;
//-------------------------------------------- SETUP LOOP 
void setup ()
{
  pinMode(8,OUTPUT); // Enable
  digitalWrite(8,LOW); // Set Enable low
  
  
  Xaxis.setMaxSpeed(200);
  Qaxis.setMaxSpeed(200);
  Waxis.setMaxSpeed(200);
  Qaxis.setMaxSpeed(200);
  
  Yaxis.setMaxSpeed(80);
  Zaxis.setMaxSpeed(50);
  
  Xaxis.setAcceleration(100);
  Qaxis.setAcceleration(100);
  Waxis.setAcceleration(100);
  Uaxis.setAcceleration(100);
  
  Yaxis.setAcceleration(30);
  Zaxis.setAcceleration(30);

}
//---------------------------------------------MAIN LOOP 
void loop() {
  
  moveforward();
  if (Xaxis.distanceToGo() == 0)
  lockkey();
  if (Xaxis.distanceToGo() == 0)
  moveback();
  if ((Xaxis.distanceToGo() == 0) && (Qaxis.distanceToGo() == 0))
  turnarm();
  if ((Xaxis.distanceToGo() == 0) && (Qaxis.distanceToGo() == 0) && (Waxis.distanceToGo() == 0) && (Yaxis.distanceToGo() == 0))
  unlockkey();
     
 }
//-------------------------------------------------------------------------------------------------
void moveforward(){
Xaxis.moveTo(-200);
Xaxis.run();  
 // if (Yaxis.distanceToGo() == 0)
 // Zaxis.run();
//stepper1.moveTo(-stepper1.currentPosition()); //Change direction at the limits
  
}
 
//-------------------------------------------------------------------------------------------------
void lockkey(){
  if (runonce) {
    delay(2000);
       Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION / 3.4;  // Rotate CW 1/2 turn
       small_stepper.setSpeed(500);   
       small_stepper.step(Steps2Take); 
    delay(2000);   
       runonce = false;
   } 
}
//-------------------------------------------------------------------------------------------------
void moveback(){
  Qaxis.moveTo(100);
  Qaxis.run();
  Qaxis.distanceToGo() == 0;
  } 
//-------------------------------------------------------------------------------------------------
void turnarm(){
Yaxis.moveTo(50);
Yaxis.run();
Waxis.moveTo(100);
Waxis.run();
  }
//-------------------------------------------------------------------------------------------------
void unlockkey(){
   if (runonce2) {
     delay(2000);
     Steps2Take  =  STEPS_PER_OUTPUT_REVOLUTION / -3.4; 
     small_stepper.setSpeed(500);   
     small_stepper.step(Steps2Take);
     runonce2 = false;
   }
}  
//-------------------------------------------------------------------------------------------------

First of all, you are using the run() function completely inappropriately. The run() function for every motor should appear once in loop() and loop() should repeat as often as possible - considerably faster than the shortest step interval.

It follows from that that you should not use delay() anywhere in your program. Have a look at how millis() is used to manage timing without blocking in several things at a time

Alternatively you could use one of the blocking functions in the AccelStepper library such as runToPosition() but IMHO that would be very much a second-rate solution.

...R

AccelStepper Xaxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Qaxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Waxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Uaxis(1, 2, 5); // pin 3 = step, pin 6 = direction
AccelStepper Yaxis(1, 3, 6); // pin 4 = step, pin 7 = direction
AccelStepper Zaxis(1, 4, 7); // pin 5 = step, pin 8 = direction

When the comments do not match the code, the programmer looks like a doofus.

 Qaxis.distanceToGo() == 0;

What is the point of comparing the value returned by distanceToGo() to 0, when you don't do anything if the value is 0, nor do you do anything if it isn't?

Pleac can you help me and tell me what I am missing or doing wrong. FYI it works perfectly as it is.

Aside from the above issues, and commented out code that should have been deleted, what makes you think there is anything wrong or missing? Generally, when the code works, you quit f**king with it.

The run() function for every motor should appear once in loop() and loop() should repeat as often as possible - considerably faster than the shortest step interval.

That is only necessary until the stepper gets to the commanded position. OPs code makes that happen.

It follows from that that you should not use delay() anywhere in your program.

I don't see any problem with using delay, once the steppers have gotten the device to a specific position. That is the only time OP calls a function that uses delay().

PaulS: Aside from the above issues, and commented out code that should have been deleted, what makes you think there is anything wrong or missing? Generally, when the code works, you quit f**king with it.

Thank for your fast response. I have fixed your previous comments. Just not sure how many 'if' statements I can keep using this way... as I need to and more positions for the robotic arm and add sensors.

Again that's for your time

Robin2: First of all, you are using the run() function completely inappropriately. The run() function for every motor should appear once in loop() and loop() should repeat as often as possible - considerably faster than the shortest step interval.

Thank you for your reply. Could you show me how you would run 2 stepper motors to different positions, one after the another using AccelStepper

Thank you

Dronebeard: Could you show me how you would run 2 stepper motors to different positions, one after the another using AccelStepper

Have you looked at the examples on the AccelStepper website?

I suspect if you get one motor working according to the example it will be pretty obvious how to add a second one.

If you can't get it to work then post the program that represents your best attempt and I will try to help.

...R

Robin2:
wow u reply fast 8). I have looked but have not found anything that helps me. As I am going to add some sensors later I need it in to run in the loop (I think), Therefore, I think your right I need millis() (which I have no idea how to use) to get it to run in the loop. When I run in Setup it works fine, but when I run it like this its just keeps looping not sure why the boolean don’t work.

Thanks again

           #include <Stepper.h>

#include <AccelStepper.h>
     
AccelStepper Xaxis(1, 2, 5);
AccelStepper Yaxis(1, 3, 6);
boolean runonce = true;
//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------

void setup ()
{
  pinMode(8,OUTPUT); // Enable
  digitalWrite(8,LOW); // Set Enable low
 
  Xaxis.setMaxSpeed(200);
  Yaxis.setMaxSpeed(80);

Xaxis.setAcceleration(100); 
  Yaxis.setAcceleration(30);

}
//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  if (runonce)
  moveforward();
  moveback();
  moveforward2();
  runonce = false;
  }
//-------------------------------------------------------------------------------------------------------------------------------------
void moveforward(){
Xaxis.moveTo(-200);
Xaxis.runToPosition();
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveback(){
  Xaxis.moveTo(100);
  Xaxis.runToPosition();
  }
  //-------------------------------------------------------------------------------------------------------------------------------------
void moveforward2(){
Xaxis.moveTo(-80);
Xaxis.runToPosition();
}

Dronebeard: wow u reply fast 8). I have looked but have not found anything that helps me. As I am going to add some sensors later I need it in to run in the loop (I think), Therefore, I think your right I need millis() (which I have no idea how to use) to get it to run in the loop. When I run in Setup it works fine, but when I run it like this its just keeps looping not sure why the boolean don't work.

I can't relate your wishes to your code.

What does the code you posted actually do and what do you want it to do that is different?

I notice that you are using the blocking runToPosition() and I suspect that will start to get in your way when you add other features to your program - but I don't have a clear view of what the final project will do.

The usual way to use AccelStepper is with the non-blocking run() function that is called repeatedly from loop() with loop() repeating very frequently. You can use the functions distanceToGo() or currentPosition() to determine whether a motor has arrived at its destination if you need to wait for that before starting the movement of another motor.

...R