Led chase help

I’m new to Arduino and could use a bit of help. I’d like to make 8 leds loop in a chasing motion for 1 minute after a button is pressed. I know how to achieve the effect by modifying the “loop” sketch example, and am fairly confident that I can activate it with a button, but have no idea how to make it run for a minute and stop. thanks in advance for help

See this: http://arduino.cc/en/Tutorial/Loop
:slight_smile:

As I mentioned above, I know how to make the leds chase in a loop, what I don’t know is how to make it do it for a minute after a button press. thanks for the prompt response though

what I don’t know is how to make it do it for a minute after a button press.

Have a Boolean variable called “running” set to false. In the main loop check this variable and only do the switching of the LEDs when it is true.
Also in the main loop look at your button. If it is pressed make the “running” variable true and set a “finish” variable (long int) to a value of millis() + 60000
Then again in the main loop check if “running” is true and millis()> finished. If it is then set running back to false.

thanks, this is slightly over my head, but the research and learning will be good for me. at least I’m moving in the right direction now.

Expanding on Mike’s idea, I would try something like this. Note if you left this on a really really long time the millis() function rolls over after a few days. This isn’t a full sketch, there would have to be a bunch of stuff in setup()

boolean running = false;
int finish = 0;
boolean buttonPressed = false;
int timer = 100;

loop()
{

// See if we pushed the button
buttonPressed = checkButtonPressed();

// If we pushed the button, and we’re not already running, start
// running, and set an end time
if (buttonPressed && !running)
{
running = true;
finish = millis() + 60000;
}

// See if we should stop running
if (running && ( finish < millis() ))
{
running = false;
finish = 0;
}

// If we’re running, loop through lights once
if (running)
{
loopLights()
}

}

// Modify http://arduino.cc/en/Tutorial/Loop to suit
loopLights()
{
int i;

for (i = 0; i < num_pins; i++) // loop through each pin…
{
digitalWrite(pins*, HIGH); // turning it on,*

  • delay(timer); // pausing,*
    _ digitalWrite(pins*, LOW); // and turning it off._
    _
    }_
    _
    }_
    _
    // Detect a button press*_
    checkButtonPressed()
    {
    * // figure out how to detect a button press then*
    * return true;*
    * // or*
    * return false;*
    }

thanks, this gives me a lot to tinker with

ok , getting closer (I think…) First is the following code right?
, and second why do I get a error: ‘False’ was not declared in this scope message

int running = FALSE;
int finish = 0;
int buttonPressed = FALSE;
int timer = 100;
int buttonPin = 1;
int pins[] = {2, 3, 4, 5, 6, 7, 8, 9};
int num_pins = 8;

void setup()
{
  int i;

  for (i = 0; i < num_pins; i++)   // the array elements are numbered from 0 to num_pins - 1
    pinMode(pins[i], OUTPUT);    // set each pin as an output
    pinMode(buttonPin, INPUT);   //set input pin 1
    
}

void loop() 
{
  int i;

  for (i = 0; i < num_pins; i++) 
  {                                 // loop through each pin...
    digitalWrite(pins[i], HIGH);   // turning it on,
    delay(timer);                  // pausing,
    digitalWrite(pins[i], LOW);    // and turning it off.
  }
  
{

 // See if we pushed the button
 buttonPressed = checkButtonPressed();
 
 // If we pushed the button, and we're not already running, start
 // running, and set an end time
 if (buttonPressed && !running)
 {
   running = TRUE;
   finish = millis() + 60000;
 }
 
 // See if we should stop running
 if (running && ( finish < millis() ))
 {
   running = FALSE;
   finish = 0;
 }
 
 // If we're running, loop through lights once
 if (running)
 {
   loopLights()
 }

}

// Modify http://arduino.cc/en/Tutorial/Loop to suit
loopLights()
{
 int i;

   for (i = 0; i < num_pins; i++)     // loop through each pin...
   {   
     digitalWrite(pins[i], HIGH);   // turning it on,
     delay(timer);                  // pausing,
     digitalWrite(pins[i], LOW);    // and turning it off.
   }
}

// Detect a button press
checkButtonPressed()
{
 // figure out how to detect a button press then
 return true;
 // or 
 return false;
}

Oops, in checkButtonPressed() it should return TURE or FALSE, not true or false.
Ignore that, Mike has it correct below.

In your loop() function, you have too many opening { You can delete the for loop at the top of loop(), since that same logic happens inside of loopLights().

“why do I get a error: ‘False’ was not declared in this scope message?”

You get an error because Arduino’s language (C) is case sensitive. “FALSE”, “false”, “False”, “faLse” are all different variable names. (Yes, I agree it’s screwy, but That’s The Way It Is.)

Go through your code and change all "false"s to FALSE, and do the same for true, and the error will go away.

–Rich

Changed the false to FALSE and still getting the error, any suggestions?
thanks for all the help and patience.

int running = FALSE;
int finish = 0;
int buttonPressed = FALSE;
int timer = 100;
int buttonPin = 1;
int pins[] = {2, 3, 4, 5, 6, 7, 8, 9};
int num_pins = 8;

void setup()
{
  int i;

  for (i = 0; i < num_pins; i++)   // the array elements are numbered from 0 to num_pins - 1
    pinMode(pins[i], OUTPUT);    // set each pin as an output
    pinMode(buttonPin, INPUT);   //set input pin 1
    
}

void loop() 
{
  int i;

  
{

 // See if we pushed the button
 buttonPressed = checkButtonPressed();
 
 // If we pushed the button, and we're not already running, start
 // running, and set an end time
 if (buttonPressed && !running)
 {
   running = TRUE;
   finish = millis() + 60000;
 }
 
 // See if we should stop running
 if (running && ( finish < millis() ))
 {
   running = FALSE;
   finish = 0;
 }
 
 // If we're running, loop through lights once
 if (running)
 {
   loopLights()
 }

}

// Modify http://arduino.cc/en/Tutorial/Loop to suit
loopLights()
{
 int i;

   for (i = 0; i < num_pins; i++)     // loop through each pin...
   {   
     digitalWrite(pins[i], HIGH);   // turning it on,
     delay(timer);                  // pausing,
     digitalWrite(pins[i], LOW);    // and turning it off.
   }
}

// Detect a button press
checkButtonPressed()
{
 // figure out how to detect a button press then
 return TRUE;
 // or 
 return FALSE;
}

Because it should be false and a boolean type variable like this:-

boolean running = false;
int finish = 0;
boolean buttonPressed = false;
int timer = 100;

Sorry for my last post, I rushed it.

This is my implementation of your problem:

#include <LED.h>//http://www.arduino.cc/playground/uploads/Code/LED.zip
#include <Button.h>//http://www.arduino.cc/playground/uploads/Code/Button.zip
#include <Scheduler.h> //http://www.arduino.cc/playground/uploads/Code/Scheduler.zip
#include <TimedAction.h> //http://www.arduino.cc/playground/uploads/Code/TimedAction.zip

//configuration
const boolean DEBUG = true;
const byte NUMBER_OF_LEDS = 5;
const byte CHASE_DELAY = 1000;

//create array of LED instances, wire LEDs from pin 8 to 12 (to ground through a resistor).
LED led[NUMBER_OF_LEDS] = { LED(8), LED(9), LED(10), LED(11), LED(12) };

//handle user input
Button button = Button(13,PULLUP);

//object that handles delayed function calls
Scheduler scheduler = Scheduler(); //create a scheduler

//controls the speed of the chase
TimedAction chaseAction = TimedAction(CHASE_DELAY,chase);

//variables
byte currentLEDIndex = 0; //keep track of current LED to blink
boolean doChase = false;

void setup(){
if (DEBUG){ Serial.begin(9600); }
}

void loop(){
if (button.uniquePress()){
doChase = true; //enable chase
scheduler.schedule(disableChase,(1601000)); //set doChase false in (1601000) microseconds
}

if (doChase){
chaseAction.check(); //maybe it’s time to advance the LED chase
}

scheduler.update(); //has there been a scheduled function call that needs to be executed?
}

//disable the LED chase
void disableChase(){
if (DEBUG){ Serial.println(“disableChase”); }
doChase = false;
}

//light next LED in array
void chase(){
if (DEBUG){ Serial.print("currenLEDIndex = "); Serial.println((int)currentLEDIndex); }
for (byte i=0; i<NUMBER_OF_LEDS; i++) {
led*.off();*

  • }*

  • led[currentLEDIndex++].on();*

  • currentLEDIndex %= NUMBER_OF_LEDS; //constrain to [0,NUMBER_OF_LEDS-1]*
    }[/quote]
    It uses a set of libraries, but I think it makes for a simple, clean and self-explanatory code.
    Atleast, that is what I hope. :slight_smile:

TimedAction is really useful, I’ve used it in a couple of places. I like the idea of going full OO on simple stuff like this.

Sorry for my true/false error, I’ve been doing too much PHP lately. I usually use just int blah = 0/1 for true false. I will correct the original post if I can…

Here is a really simple loop that will blink an led for one minute after each push of a button.

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for a pushbutton)
int val = 0;                    // variable for reading the pin status
long now = 0;                    // variable for holding millis()

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare pushbutton as input
}

void loop(){
  val = digitalRead(inputPin);  // read button value
  
  if (val == HIGH) {            // check for button push
    now = millis();
    while((millis() - now) < 60000){
      digitalWrite(ledPin, HIGH);  // turn LED ON
      delay(500);                  // delay for 1/2 second
      digitalWrite(ledPin, LOW);   // turn LED OFF
      delay(500);                  // delay for 1/2 second    
    }   
  }
}

Once you have your variables defined and you’ve checked for the button push event the loop for one minute is simply this…

    now = millis();                // Set now to the current millis
    while((millis() - now) < 60000){
      digitalWrite(ledPin, HIGH);  // turn LED ON
      delay(500);                  // delay for 1/2 second
      digitalWrite(ledPin, LOW);   // turn LED OFF
      delay(500);                  // delay for 1/2 second    
    }

Replace the led blink code and put in your chaser code and viola you have chasing leds for one minute after you push the button.

For simplicity sake here is the stripped down bare bones minimum code to react to a button push and loop for a minute.

int buttonPin = 2;               // the pin the button is connected to
int val = 0;                     // variable for reading the pin status
long now = 0;                    // variable for holding millis()

void setup() {
  pinMode(buttonPin, INPUT);     // declare pushbutton as input
}

void loop(){
  val = digitalRead(buttonPin);  // read button value
  
  if (val == HIGH) {               // check for button push
    now = millis();                // Set now to the current millis
    while((millis() - now) < 60000){
      //Chaser led code goes here 
    }   
  }
}

Thanks to all of you for the help

this is working much better now, and I’m learning a lot. one more question. I’m trying to add a relay to pin 12 that is switched on with the chase effect ( light stays on while led’s chase, light goes out when they stop) this what I have so far. how do I make the relay (relayPin) stop. thanks

int buttonPin = 11;               // the pin the button is connected to
int relayPin = 12;
int timer = 50;
int pins[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int num_pins = 8;
int val = 0;                     // variable for reading the pin status
long now = 0;                    // variable for holding millis()


void setup() {
  pinMode(relayPin, OUTPUT);
  pinMode(buttonPin, INPUT);     // declare pushbutton as input
  int i;

  for (i = 0; i < num_pins; i++)   // the array elements are numbered from 0 to num_pins - 1
    pinMode(pins[i], OUTPUT);      // set each pin as an output
}

void loop(){
  val = digitalRead(buttonPin);  // read button value
  
  if (val == HIGH) {               // check for button push
    now = millis();                // Set now to the current millis
    while((millis() - now) < 60000){
     int i;
     digitalWrite(relayPin, HIGH);

  for (i = 0; i < num_pins; i++) { // loop through each pin...
    digitalWrite(pins[i], HIGH);   // turning it on,
    delay(timer);                  // pausing,
    digitalWrite(pins[i], LOW);    
    }  
  }
}
}

Consistent indentation and bracketing can help you visualise what the code is doing

int buttonPin = 11;         // the pin the button is connected to
int relayPin = 12;
int timer = 50;
int pins[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int num_pins = 8;
int val = 0;        // variable for reading the pin status
long now = 0;       // variable for holding millis()


void setup() {
  pinMode(relayPin, OUTPUT);
  pinMode(buttonPin, INPUT);     // declare pushbutton as input
  for (int i = 0; i < num_pins; i++) {
    pinMode(pins[i], OUTPUT);
  }
}

void loop(){
  val = digitalRead(buttonPin);  // read button value

  if (val == HIGH) {               // check for button push
    now = millis();                // Set now to the current millis
    while((millis() - now) < 60000){
      int i;
      digitalWrite(relayPin, HIGH);

      for (i = 0; i < num_pins; i++) { // loop through each pin...
        digitalWrite(pins[i], HIGH);   // turning it on,
        delay(timer);                  // pausing,
        digitalWrite(pins[i], LOW);
        delay(timer);      // I slipped this one in
      }
    } // your minute is up (end of "while" loop)
    digitalWrite (relayPin , LOW);
  }
}

Another useful tip is to keep things as local as possible;; “now” and “val” don’t need to be global, and could be declared within “loop”/

Another useful tip is to keep things as local as possible;; “now” and “val” don’t need to be global, and could be declared within “loop”/

Ah, yes… good point. Another tip (correct me if i’m wrong) is to drop the int i; declaration and declare it inside the loop to tidy things up a bit in code.

Like this…

      for (int i = 0; i < num_pins; i++) { // loop through each pin...
        digitalWrite(pins[i], HIGH);   // turning it on,
        delay(timer);                  // pausing,
        digitalWrite(pins[i], LOW);
        delay(timer);      // I slipped this one in
      }

Oh yes, - I forgot about “i” in that case, didn’t I? :-[