Stepper motor fwd/rev + countdown timer + LCD

Hello Arduino fans,

31 year old female, first time programming, first time poster.

One month ago I ordered an Arduino Mega kit for an exploration into creating a product. I need a stepper motor to turn 4 times during a 20 minute interval, and an LCD to display a few different words along with a countdown timer for the entire 20 minutes.

Getting the motor to turn, the words to display, and the timer to run have been a challenging success. My problem is when I ask the stepper motor to turn again, at a 5 minute interval. It seems I am unable to get out of the loop to have it turn, then return to the loop, while the countdown timer continues to run.

I have spliced code from all corners of the internet to get as far as I have and a few suggestions would be appreciated.

// int minutes says 20 though I test with lower numbers.
// Thank you in advance.

Chelsea

#include <CountUpDownTimer.h>
#include <LiquidCrystal.h>
#include <Stepper.h>

int hours = 0; // start hours
int minutes = 20; //start min
int seconds = 0; //start seconds

#define STEPS_PER_MOTOR_REVOLUTION 32
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 64 //2048
Stepper myStepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);

// Numbers of the interface pins
LiquidCrystal lcd(0, 1, 2, 3, 4, 5);

const int stepsPerRevolution = 32; // number of steps per revolution
// for my motor

int step();

void setup() {
lcd.begin(16,2);
lcd.setCursor(0, 0);
lcd.print("");
lcd.setCursor(0,1);
lcd.print("
_");
delay(4000);

lcd.clear();
}

void loop() {
// for now I am programming it to run the tendon program
lcd.print("Increasing");
lcd.setCursor(0,1);
lcd.print("to Level 40");
myStepper.setSpeed(100); // = 1667 milliseconds
myStepper.step(200);
lcd.clear();
lcd.print("Lvl. 40 - 5 MIN");
lcd.setCursor(0,1);
lcd.print("Remaining");

while (minutes > 0 || seconds >= 0) {

lcd.setCursor(11, 1);
(minutes < 10) ? lcd.print("0") : NULL;
lcd.print(minutes);
lcd.print(":");
(seconds < 10) ? lcd.print("0") : NULL;
lcd.print(seconds);
lcd.display();
stepDown();
delay(1000);

}
}
/* This is where I encounter the problem. After 5 out of 20 minutes has passed,

  • I need the stepper motor to take another 350 steps and wait for 6 minutes.
  • After 6 minutes I need it to take another 350 steps and wait for 6 minutes.
  • then I need it to take 850 reverse steps and wait until the 20 minute timer runs out.
  • It seems no matter how I attempt to break the loop my lcd gets screwed up or my
  • stepper motor does not pause for the amount of time it needs to, but rather, just continues to rotate
  • and then pause.
  • OR NOTHING happens and the stepper does not turn again and the timer just runs out.
    */

void stepDown() {
if (seconds > 0) {
seconds -= 1;
} else {
if (minutes > 0) {
seconds = 59;
minutes -= 1;
} else {
if (hours > 0) {
seconds = 59;
minutes = 59;
hours -= 1;
} else {
trigger();
}
}
}
}

void trigger() {
lcd.clear(); // clears the screen and buffer
lcd.setCursor(5, 1); // set timer position on lcd for end.

lcd.println("END");
delay(1000);

lcd.display();
}

For the future please use the code button </> so your code looks like this

#include <CountUpDownTimer.h>
#include <LiquidCrystal.h>
#include <Stepper.h>
 
 
int hours = 0; // start hours
int minutes = 20; //start min
int seconds = 0; //start seconds

#define STEPS_PER_MOTOR_REVOLUTION 32   
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 64  //2048 
Stepper myStepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);

// Numbers of the interface pins
LiquidCrystal lcd(0, 1, 2, 3, 4, 5);

const int stepsPerRevolution = 32;  // number of steps per revolution
// for my motor

int step();

void setup() {
 lcd.begin(16,2);
 lcd.setCursor(0, 0);
 lcd.print("____________");
 lcd.setCursor(0,1);
 lcd.print("_____________");
 delay(4000);

  lcd.clear();
}
 
void loop() {
 // for now I am programming it to run the tendon program
 lcd.print("Increasing");
 lcd.setCursor(0,1);
 lcd.print("to Level 40");
 myStepper.setSpeed(100); // = 1667 milliseconds
 myStepper.step(200);
 lcd.clear();
 lcd.print("Lvl. 40 - 5 MIN");
 lcd.setCursor(0,1);
 lcd.print("Remaining");
 
 while (minutes > 0 || seconds >= 0) {
 
 lcd.setCursor(11, 1);
 (minutes < 10) ? lcd.print("0") : NULL;
 lcd.print(minutes);
 lcd.print(":");
 (seconds < 10) ? lcd.print("0") : NULL;
 lcd.print(seconds);
 lcd.display();
 stepDown();
 delay(1000);

 }
}
/* This is where I encounter the problem. After 5 out of 20 minutes has passed,
 *  I need the stepper motor to take another 350 steps and wait for 6 minutes.
 *  After 6 minutes I need it to take another 350 steps and wait for 6 minutes.
 *  then I need it to take 850 reverse steps and wait until the 20 minute timer runs out.
 *  It seems no matter how I attempt to break the loop my lcd gets screwed up or my
 *  stepper motor does not pause for the amount of time it needs to, but rather, just continues to rotate
 *  and then pause.
 *  OR NOTHING happens and the stepper does not turn again and the timer just runs out.
 */

void stepDown() {
 if (seconds > 0) {
 seconds -= 1;
 } else {
 if (minutes > 0) {
 seconds = 59;
 minutes -= 1;
 } else {
 if (hours > 0) {
 seconds = 59;
 minutes = 59;
 hours -= 1;
 } else {
 trigger();
 }
 }
 }
}
 
void trigger() {
 lcd.clear(); // clears the screen and buffer
 lcd.setCursor(5, 1); // set timer position on lcd for end.
 
 lcd.println("END");
 delay(1000);
 
 lcd.display();
}

To achieve an interactive program you need to get rid of the blocking WHILE and the delay()s. Use IF rather than WHILE and allow loop() to do the repetition. And use millis() to manage the timing without blocking as illustrated in Several Things at a Time.

...R
Stepper Motor Basics
Simple Stepper Code
Planning and Implementing a Program

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom. :slight_smile:

Thanks guys I will post my code properly next time!
I am under the impression that using millis() is limited because it only goes up to 32,000? I will keep working at it. Thanks so much for the replies and reference materials :slight_smile:

Chelsea

Icandothis:
I am under the impression that using millis() is limited because it only goes up to 32,000?

millis() returns an unsigned long 32 bit value that can count up to 232-1 which takes it about 49 days.

...R