millis() in while() loop for accelstepper

Hi all,

So since accelstepper function run() has to be called continuously, I used while() loop instead of if() to make 2 stepper motors rotate at the same time. However, for a while() loop, the codes run longer than coded (I made 5 loops similar to the on below but with different time loop

while(millis()<12000 && millis >=20000 {

stepper1. moveTo(1000);
stepper2.moveTo(-1000);

stepper1.run();
stepper2.run();

}

The above is the last loop and my codes seem to not enter this last loop. What do you guys reckon the problem is?

Many thanks

P/s: Here is the full codes

 ////  PERIOD 1:  \\\\
  

    while( millis()<=5000){                                                //0:00-0:05 s 
  
      stepper1.moveTo(-753);
      stepper4.moveTo(753);
  
      stepper1.run();
      stepper4.run();
  
      myStepper2->release();
      myStepper3->release();
    }



    

 //// PERIOD 2:  \\\\

    while( millis()>5000 && millis()<=11000 ){                             // 0:05-0:11 
  
      stepper2.moveTo(692); // going towards
      stepper3.moveTo(-692);
  
      stepper2.run();
      stepper3.run();

  
  
      myStepper1->release();
      myStepper4->release();
    }




  //// PERIOD 4:  \\\\

    while(millis()>12000 && millis<= 19000){                                 // 0:12-0:20  
  
      stepper1.moveTo(-653);
      stepper4.moveTo(653);
  
      stepper1.run();
      stepper4.run();
  
      myStepper2->release();
      myStepper3->release();
    }


    

  //// PERIOD 5:  \\\\

    while( millis()>12000 && millis()<=26000 ){                                  // 0:21-0:26

  
      stepper2.moveTo(-692); // going backwards
      stepper3.moveTo(692);
  
      stepper2.run();
      stepper3.run();
  
  
      myStepper1->release();
      myStepper4->release();


    }

I’m quite sure that you will get a warning (set your warning level to ALL in file → preferences) that you can’t ignore in this case.

Compare

while( millis()>5000 && millis()<=11000 ){

with

while(millis()>12000 && millis<= 19000){

Might be more wrong, but that caught my eye.

PS
That’s not full code

oops that was a typo mistake. It works now thanks a lot! However, in the fourth loop, the motors rotate the opposite direction I coded them for 1 or 2 rev before rotating the way I want. Is it some silly mistakes again?

And I copied the draft instead of the real one. I will reupload it :slight_smile:

#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>



Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers
Adafruit_MotorShield AFMSpulley(0x62); // Rightmost jumper closed


Adafruit_StepperMotor myStepper1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor myStepper2 = AFMStop.getStepper(200, 2);

Adafruit_StepperMotor myStepper3 = AFMSbot.getStepper(200, 1);
Adafruit_StepperMotor myStepper4 = AFMSbot.getStepper(200, 2);


// wrappers for the first motor!
void forwardstep1() {
  myStepper1->onestep(FORWARD, DOUBLE);

}
void backwardstep1() {
  myStepper1->onestep(BACKWARD, DOUBLE);

}
// wrappers for the second motor!
void forwardstep2() {
  myStepper2->onestep(FORWARD, DOUBLE);

}
void backwardstep2() {
  myStepper2->onestep(BACKWARD, DOUBLE);

}
// wrappers for the third motor!
void forwardstep3() {
  myStepper3->onestep(FORWARD, DOUBLE);

}
void backwardstep3() {
  myStepper3->onestep(BACKWARD, DOUBLE);

}

// wrappers for the fourth motor!
void forwardstep4() {
  myStepper4->onestep(FORWARD, DOUBLE);

}
void backwardstep4() {
  myStepper4->onestep(BACKWARD, DOUBLE);

}


// Now we'll wrap the 6 steppers in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);
AccelStepper stepper3(forwardstep3, backwardstep3);
AccelStepper stepper4(forwardstep4, backwardstep4);


void setup()
{



  AFMSbot.begin(); // Start the bottom shield
  AFMStop.begin(); // Start the top shield


  // Set speed or acceleration for motors

  // ----
  stepper1.setMaxSpeed(100.0);
  stepper1.setAcceleration(80.0);

  //----
  stepper2.setMaxSpeed(100.0);
  stepper2.setAcceleration(80.0);

  //----
  stepper3.setMaxSpeed(100.0);
  stepper3.setAcceleration(80.0);

  //----
  stepper4.setMaxSpeed(100.0);
  stepper4.setAcceleration(80.0);


  stepper1.setCurrentPosition(0);
  stepper2.setCurrentPosition(0);
  stepper3.setCurrentPosition(0);
  stepper4.setCurrentPosition(0);


}

void loop()
{

  //  PERIOD 1: 

    while(millis()<=6000){                                       
  
      stepper1.moveTo(-753);
      stepper4.moveTo(753);
  
      stepper1.run();
      stepper4.run();
  
      myStepper2->release();
      myStepper3->release();
    }


 // PERIOD 2: 
    while(millis()>7000 and millis()<=12000){                        
  
      stepper2.moveTo(1653);
      stepper3.moveTo(-1653);
  
      stepper2.run();
      stepper3.run();
  
      myStepper1->release();
      myStepper4->release();
    }
    



  // PERIOD 3: Moving sideways to bunker
  
    while(millis()>13000 && millis()<=19000){                                
 
      stepper1.moveTo(-1753);
      stepper4.moveTo(1753);
  
      stepper1.run();
      stepper4.run();
  
      myStepper2->release();
      myStepper3->release();
    }



    // PERIOD 4:
    
    while(millis()>20000 and millis()<=28000){                        
  
      stepper2.moveTo(-1653);
      stepper3.moveTo(1653);
  
      stepper2.run();
      stepper3.run();
  
      myStepper1->release();
      myStepper4->release();
    }
    

    
}

If the stepper movements need ever happen only once when the Arduino is powered up or reset then why bother putting the code in loop() when it could just as well go in setup() ?

Do the movements only ever need to happen once or would it be more convenient to be able to trigger them with a button instead of turning the Arduino on/off or resetting it which seems rather clumsy at best.

Tyloren:
Hi all,

So since accelstepper function run() has to be called continuously, I used while() loop instead of if() to make 2 stepper motors rotate at the same time. However, for a while() loop, the codes run longer than coded (I made 5 loops similar to the on below but with different time loop

while(millis()<12000 && millis >=20000 {

stepper1. moveTo(1000);
stepper2.moveTo(-1000);

stepper1.run();
stepper2.run();

}

That seems a very strange way to use the AccelStepper library. The intended way of using it is to put stepper.run() in loop() so it is called all the time. The motor will stop moving when the destination is reached.

Can you describe the project you are trying to create? I suspect there is a simpler way.

…R

Hi Robin, I am trying to make the 2 stepper motors run at the same time so stepper.run() was the best option I could find. The project requires me to do the following in order

  1. Run 2 steppers at the same time (stepper 1 & 2)
  2. Run another 2 steppers at the same time (3&4)
  3. Run DC motor using stepper shield v2
  4. Run the first 2 steppers again
  5. Run DC again

Currently I am stuck at the DC. It stops running the steppers in the while loop I made even tho the codes did get in the loop. It skipped to the next delay() since I used delay() for DC motor

If you want to run several motors at the same time and don't need acceleration then use runSpeed(). If you want to be able to stop calling that so as to stop the motor then create a little function for each motor and in the function check if the motor may run. Then all you have to do is change the variable elsewhere in your program when you want the motor to go or stop. Something like this

void runMotorA() {
  if (motorAmayRun == true) {
    motorA.runSpeed();
  }
}

and as the last lines in loop() have calls to those functions - like this

void loop() {
  // other stuff
  runMotorA();
  runMotorB();
  runMotorC();
  // etc
}

...R

Thanks for the replies Robin! I made functions like you recommended. I ran into a new problem where after activating the DC motor, the functions made for steppers did not work despite working before using DC motor.

#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"



Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers
Adafruit_MotorShield AFMSpulley(0x62); // Rightmost jumper closed


// Connect two steppers with 200 steps per revolution (1.8 degree)
// to the top shield
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2);

// Connect one stepper with 200 steps per revolution (1.8 degree)
// to the bottom shield
Adafruit_StepperMotor *myStepper3 = AFMSbot.getStepper(200, 1);
Adafruit_StepperMotor *myStepper4 = AFMSbot.getStepper(200, 2);

// Connect one stepper with 200 steps per revolution (1.8 degree)
// to the bottom shield

Adafruit_DCMotor *myMotor = AFMSpulley.getMotor(4);


// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!

// wrappers for the first motor!
void forwardstep1() {
  myStepper1->onestep(FORWARD, DOUBLE);

}
void backwardstep1() {
  myStepper1->onestep(BACKWARD, DOUBLE);

}
// wrappers for the second motor!
void forwardstep2() {
  myStepper2->onestep(FORWARD, DOUBLE);

}
void backwardstep2() {
  myStepper2->onestep(BACKWARD, DOUBLE);

}
// wrappers for the third motor!
void forwardstep3() {
  myStepper3->onestep(FORWARD, DOUBLE);

}
void backwardstep3() {
  myStepper3->onestep(BACKWARD, DOUBLE);

}

// wrappers for the forth motor!
void forwardstep4() {
  myStepper4->onestep(FORWARD, DOUBLE);

}
void backwardstep4() {
  myStepper4->onestep(BACKWARD, DOUBLE);

}

// Now we'll wrap the 6 steppers in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);
AccelStepper stepper3(forwardstep3, backwardstep3);
AccelStepper stepper4(forwardstep4, backwardstep4);


// Steps we want to go
int stepLeft = 100;
int stepRight_1 = 100;
int stepRight_2 = 100;
int stepForwards = 100;
int stepBackwards = 100;


// Time
unsigned long time_1 = 5000;                     

unsigned long time_2_start = time_1 + 1000;       // 1s wait
unsigned long time_2_end = time_2_start + 7000;  // 7s for 2nd action

unsigned long time_3_start = time_2_end + 1000;   // 1s wait
unsigned long time_3_end = time_3_start + 11000;  // 11s to lift 

unsigned long time_4_start = time_3_end + 1000;   // 1s wait
unsigned long time_4_end = time_4_start + 4000;   // 4s for 3rd action

unsigned long time_5_start = time_4_end + 1000;   // 1s wait
unsigned long time_5_end = time_5_start + 11000; // 11s for 4th action





void setup()
{


  Serial.begin(9600);

  
  // Basic set up
  AFMSbot.begin(); // Start the bottom shield
  AFMStop.begin(); // Start the top shield
  AFMSpulley.begin(); // Start the mid shield


  // Set speed or acceleration for motors

  // ----
  stepper1.setMaxSpeed(100.0);
  stepper1.setAcceleration(80.0);

  //----
  stepper2.setMaxSpeed(100.0);
  stepper2.setAcceleration(80.0);

  //----
  stepper3.setMaxSpeed(100.0);
  stepper3.setAcceleration(80.0);

  //----
  stepper4.setMaxSpeed(100.0);
  stepper4.setAcceleration(80.0);



  stepper1.setCurrentPosition(0);
  stepper2.setCurrentPosition(0);
  stepper3.setCurrentPosition(0);
  stepper4.setCurrentPosition(0);


}




void loop()
{

  

  //  PERIOD 1:

  while (millis() <= time_1) {                                                  

  while (millis() > (time_2_start) and millis() <= time_2_end) {                

    moveForwards(stepForwards);
  }



  
  while (millis() > (time_3_start) and millis() <= (time_3_end)) {

  // Initialize variable i

    uint8_t i;

    myMotor->run(FORWARD);
    for (i = 0; i < 100; i++) {
      
      myMotor->setSpeed(i);
      delay(10);

      // Check if the code enters here
      Serial.print("Period_3a");
    }

    // When reach max speed, keep it constant
    myMotor->setSpeed(i);
    delay(5000);      

    

    // Decelerate to a lower speed to keep torque
    for (i = 100; i != 50; i--) {
      myMotor->setSpeed(i);
      delay(10);

      // Checking
      Serial.print("ONE");
      


    }

    // Keep the low speed for a while                                                 
    myMotor->setSpeed(i);
    delay(5000);

    // Checking
    Serial.print("TestForOne");

  }




    //PERIOD 4: hold the lift and move backwards          //PROBLEM, moveBackwards() did not activate\\

    
      myMotor->run(RELEASE); 

    while (millis() > (time_4_start) and millis() <= (time_4_end)) {


      //myMotor->run(RELEASE);                                                         
      Serial.print("Period_4a");

      //myMotor->setSpeed(40);
     //delay(2000);        // const speed



      moveBackwards(stepBackwards);
      Serial.print("TestForTwo");

    }




}
  // New functions

  void moveLeft(int L) {

    stepper2.moveTo(-L);
    stepper4.moveTo(L);

    stepper2.run();
    stepper4.run();

    myStepper1->release();
    myStepper3->release();

  }

  void moveRight(int R) {

    stepper1.moveTo(-R);
    stepper4.moveTo(R);

    stepper1.run();
    stepper4.run();

    myStepper2->release();
    myStepper3->release();
  }

  void moveForwards(int F) {

    stepper2.moveTo(F); // going forwards
    stepper3.moveTo(-F);

    stepper2.run();
    stepper3.run();

    myStepper1->release();
    myStepper4->release();
  }

  void moveBackwards(int B) {


    stepper1.moveTo(-B); // going backwards
    stepper4.moveTo(B);

    stepper1.run();
    stepper4.run();

    myStepper2->release();
    myStepper3->release();


  }

What you have in Reply #7 is not remotely like what I suggested in Reply #6.

Of course you are perfectly free to ignore my advice.

There should be no WHILE and no DELAY() in your program.

...R