How do i write a "run for 8hrs" Stepper motor loop

I am trying to run a stepper motor for a 8hr "burn in" run. I had this running before about 1 month ago and ran many different test sessions with it. Now it will only run forward and reverse motion 1 time. I have verified that a different program does work that is just the loop just fine. It is not a hardware issue since again i have run the motor just fine.

I am just (as of right now) trying to run this program for a set time. I am absolutely a newbie at this so please comment accordingly.

#include <AccelStepper.h>

/*

WIRE COLOR

Yellow wire on pin 6,8,10  -- Step/Pul- 
Purple wire on pin 7,9,11 -- DIR

TB6600 Wiring

ENA- will not have a wire
ENA+, DIR+, PUL+ will need 5v DC off the Arduino
DIR- will go to pin 9
PUL- will go to pin 8
VCC and GND will go to Vcc IN from 9v-40v DC

Half Step Setup: SW1-SW6 should be ON, OFF, ON, ON, ON, ON
Full Step Setup: SW1-SW6 should be ON, ON, OFF, ON, ON, ON

*/

// Stepper Motor Pinout

AccelStepper stepperS(1, 10, 11);  // Shoulder motor on pins 9 and 10.  **HALF-SPEED Setup**

void setup() {

// Stepper Motor Homing Speed

stepperS.setMaxSpeed(3000);     // Set maximum speed   max speed can only be 3000
stepperS.setAcceleration(1500); // Set acceleration  1500 seems to work the best
stepperS.setCurrentPosition(0);

delay(5000);  // This should give time for the TB600 driver to power up

}

// Programing MOTOR runs Below

void loop() {
  
  // Motors should start running

  stepperS.moveTo(3500); // ********************get this from Wrist alone program********************
  while (stepperS.currentPosition() != 3500) {  // number after != needs to be the same # as line 11
  stepperS.run();
  }

  delay(1000);  // Pause to go back to position

  stepperS.moveTo(0); // Move back to position 0
  while (stepperS.currentPosition() != 0) {
  stepperS.run();
  }
   
  delay(1000);  // Pause to restart the loop

If you want to do something for 8 hrs you could use an external RTC but also a simple millis loop. Something like
eightHrs = 1000ms/sec * 60sec/min * 60 min/hr * 8hr
Use that value in a
if millis() < eightHrs then keep running
else stop motor

2 Likes
static bool keepRunning = true;
if(millis()>3600000UL*8){
  keepRunning=false;
}
if(keepRunning){
// stuff to do for 8 hours
}
2 Likes

Thank you so much for your help!! where would i put this into the code?

I think i got it. can you run this IF loop inside an additional IF loop.

Yes, you can nest if(...){...} statements: if statement - cppreference.com

Your code in #1 is incomplete, but you could wrap the stuff in the body of your loop(){...} function inside my if statement:

void loop() {
  static bool keepRunning = true;
  if (millis() > 3600000UL * 8) {
    keepRunning = false;
  }
  if (keepRunning) {
    // stuff to do for 8 hours
    // Motors should start running

    stepperS.moveTo(3500); // ********************get this from Wrist alone program********************
    while (stepperS.currentPosition() != 3500) {  // number after != needs to be the same # as line 11
      stepperS.run();
    }

    delay(1000);  // Pause to go back to position

    stepperS.moveTo(0); // Move back to position 0
    while (stepperS.currentPosition() != 0) {
      stepperS.run();
    }

    delay(1000);  // Pause to restart the loop
  }
  ...
2 Likes

thank you again for your help! I have no clue how or why my other program worked in the first place last month without this. Im sure i will have more questions as i dive more into the arduino and coding.

Did you not see post#2?

alright now im just as confused. It worked perfect in my single run and i know i am missing something very simple in here. If statement "1" is not working yet and i will try to figure that out but i can only get IF "2" and "3" to complete 1 up down cycle and it just stops.

#include <AccelStepper.h>

/*

WIRE COLOR

Yellow wire on pin 6,8,10  -- Step/Pul- 
Purple wire on pin 7,9,11 -- DIR

TB6600 Wiring

ENA- will not have a wire
ENA+, DIR+, PUL+ will need 5v DC off the Arduino
DIR- will go to pin 9
PUL- will go to pin 8
VCC and GND will go to Vcc IN from 9v-40v DC

Half Step Setup: SW1-SW6 should be ON, OFF, ON, ON, ON, ON
Full Step Setup: SW1-SW6 should be ON, ON, OFF, ON, ON, ON

**********************************************************
Programs Available for Testing
  "1"--  Homing Shoulder
  "2"--  30 min FULL RUN
  "3"--  8 hr TEST RUN
**********************************************************
*/

// Stepper Motor Pinout

AccelStepper stepperS(1, 10, 11);  // Shoulder motor on pins 9 and 10.  **HALF-SPEED Setup**

// Define the Pins used 

#define home_switchS 5 // Pin 5 connected to Arduino D5

//------------------------------------------------------------------------------------

void setup() {

pinMode(home_switchS, INPUT);  // HIGH means the sensor is off, and LOW means the sensor is on.

// Stepper Motor Homing Speed

stepperS.setMaxSpeed(160.0);       // Set Max Speed of Stepper (Slower to get better accuracy)
stepperS.setAcceleration(1000.0);  // Set Acceleration of Stepper

delay(5000);  // This should give time for the TB600 driver to power up

Serial.begin(9600);  // Setting the baud rate for COM

delay(2000);  // Waiting for 2 secs

Serial.println(" Programs Available for Testing     1--  Homing Shoulder, 2--  30 min FULL RUN, 3--  8 hr TEST RUN");
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Programing MOTOR runs Below

void loop() {

if (Serial.available() > 0) {
int receivedChar = Serial.read();

  if (receivedChar == '1') {
    
  // Start Program 1 -- Homing Motors
    
  Serial.println("Starting to home the Shoulder....");

  // Start Homing procedure of Stepper Motor "S" at startup

  // Check if sensor is active

    if (digitalRead(home_switchS) == HIGH) {

    // Move right until sensor is no longer active
    
      while (digitalRead(home_switchS) == HIGH) {
        stepperS.move(1000); // Move a certain number of steps
        while (stepperS.distanceToGo() != 0) {
        stepperS.run();
        }

      delay(100);
      }
    }
    
    else {

    // Move left until sensor is active
    
      while (digitalRead(home_switchS) == LOW) {
        stepperS.move(-1000); // Move a certain number of steps
        while (stepperS.distanceToGo() != 0) {
        stepperS.run();
        }
      delay(100);
      }
    }

    Serial.println ("Shoulder Motor Homed");
   // stepperS.setCurrentPosition(0);
    delay(1000);
  }



  else if(receivedChar == '2') {
    
  // Start program 2 -- 30 min Run
    
  Serial.println("Starting 30 min Run");
    
    static bool keepRunning = true;
    if(millis()>30000UL*8){   //Simulate running for 1hr run  **28,800,000 will run for 8hr**
    keepRunning = false;
    }

    if(keepRunning){

      // Implement the code for program 2 here

      // Running speeds for testing loop

        stepperS.setMaxSpeed(2500);     // Set maximum speed   max speed can only be 3000
        stepperS.setAcceleration(1500); // Set acceleration  1500 seems to work the best
        stepperS.setCurrentPosition(0);

      // Motors should start running

        stepperS.moveTo(3500); // ********************get this from Wrist alone program********************
        while (stepperS.currentPosition() != 3500) {  // number after != needs to be the same # as line 11
        stepperS.run();
        }

        delay(1000);  // Pause to go back to position

        stepperS.moveTo(0); // Move back to position 0
        while (stepperS.currentPosition() != 0) {
        stepperS.run();
        }

      delay(2000);  // Pause to restart the loop
    }

    Serial.println("30 Min test run completed");

    // end of Static bool
  }

  else if (receivedChar == '3') {
    
  static bool keepRunning = true;
if(millis()>30000UL*8){
  keepRunning=false;
}
if(keepRunning){

    Serial.println("Starting 8hr run.....pray for me....");
    
    // Start program 3 -- 30 min run

    // Running speeds for testing loop

      stepperS.setMaxSpeed(3000);     // Set maximum speed   max speed can only be 3000
      stepperS.setAcceleration(1500); // Set acceleration  1500 seems to work the best
      stepperS.setCurrentPosition(0);

      // Motors should start running

      stepperS.moveTo(3500); // 
      while (stepperS.currentPosition() != 3500) {  // Number after != needs to be the same # as line 11
      stepperS.run();
      }

      delay(1000);  // Pause to go back to position

      stepperS.moveTo(0); // Move back to position 0
      while (stepperS.currentPosition() != 0) {
      stepperS.run();
      }
      delay(1000);  // Pause to restart the loop
  }  
  Serial.println("8 Hr run completed.  Go have a Whiskey");  

}


  else {
      Serial.println("Invalid command.");
   }

  // Clear the serial buffer after reading

    while (Serial.available() > 0) {
      Serial.read();
    }
  }
}

I did. i was looking into the RTCs when DaveX replied as well. I appreciate your input very much

I imagine that would give some errors s.

The problem changes a lot if you want to measure time from the start of a command instead of the start of a program. You’ll need to record the time of the start of the command an use something more like:

If(millis()-startMillis>12345)…

You only need one keepRunning flag variable, so only make one declaration.

Then, you can reuse the variables and reset their values when you start the task.

1 Like

I like to rename loop() to some other function name, then use a simplified loop() to do the timing.

unsigned long timer, timeout = 8 * 3600UL * 1000UL; // hour, sec/hour, ms/sec
byte value = 1;

void setup() {
  Serial.begin(115200);
}

void loop() { // rename loop() to myFunction().  This is the new loop()
  while (millis() - timer < timeout) {
    myFunction(value); // call the new function, which was loop()
  }
}

void myFunction(byte val) { // renamed from loop() to myFunction()
  Serial.print(val);
}
2 Likes