LEDs in sequence without delay()???

Hi everyone, total newb here!

I have been messing with a Leonardo the past few days trying to make a sketch of seven leds that are lit in sequence without switching off the previous led, while and as long as a button is pressed. When the button is released the leds are switched off in sequence as well.

Well everything works perfect… but I am trying to do the exact same thing without using the delay function.

I have been trying the Millis(), the simpleTimer(), the isTime() and many many others… its official I’m stuck.

The code with the delay(), I am trying to rearrange is the following:

/*
  Leds light on and off in sequence
  Lights multiple LEDs in sequence when button is pressed, then in reverse when button is released.
  
*/

const int buttonPin2 = 2;     // the number of the pushbutton pin

int buttonState2 = 0;         // variable for reading the pushbutton status
int timer = 100;              // The higher the number, the slower the timing.

void setup() {
  
  //use a for loop to initialize each pin as an output:
  for (int thisPin = 7; thisPin < 14; thisPin++)  {
  pinMode(thisPin, OUTPUT);      
  }
 
  pinMode(buttonPin2, INPUT);
}

void loop() {
  buttonState2 = digitalRead(buttonPin2);
  
  // when pushbutton is high all related leds light on, in sequence
 if (digitalRead(buttonPin2) == HIGH) {
  // loop from the lowest pin to the highest:
  for (int thisPin = 7; thisPin < 14; thisPin++) {
    // turn the pin on:
    digitalWrite(thisPin, HIGH);  
    delay(timer);                  
    // turn the pin off:
    digitalWrite(thisPin, HIGH);    
  }
 }
  // when push button is low all related leds are turned off in sequence
  else {//(digitalRead(buttonPin2) == LOW)
  // loop from the highest pin to the lowest:
  for (int thisPin = 13; thisPin > 6; thisPin--) {
    // turn the pin on:
    digitalWrite(thisPin, LOW);
    delay(timer);
    // turn the pin off:
    digitalWrite(thisPin, LOW);
  }
 } 
}

Please anything or better yet the solution to my puzzled mind in order to substitute delay() with millis() or any other solution.

Thanks in advance!

P.S. Is there a proper way to upload code in the forum so that it is more read-friendly???

hi

check out this link

it is not hard at all to make your code work

also

hit the icon(that says CODE) on the top right ------------to insert your code

the code is long but he is trying to run a few things at a time

if i were you i would study the code line by line first

just learn how it works

also i would remove a couple of functions such as

void servoSweep()

to make the code easier to understand

You might want another view on it:- http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

wonderful tutorial, grumpy

but i do not understand why you had to use long tho

long int goTime1, goTime2;

Please clear my doubts.

Thanks

I do not understand the following:

This program is a bit simplified in that it doesn't consider what happens when the number of milliseconds since the Arduino was switched on exceeds what will fit in the long variable. This happens once every two months or so. When it does happen, there is a chance that it might fail if you don't check the time every millisecond, but for the sake of simplicity we won't consider that for the moment, just get your head round what is happening. Besides it is a rare program that runs for over two months without powering down.

I tried to use int but the blinking stopped after a short period of time

but i do not understand why you had to use long tho

Because the millis() function returns a long value.

I tried to use int but the blinking stopped after a short period of time

That is because an int is only 16 bits and therefore has maximum value of 32768 milli seconds, so that translates to about 32 seconds before things go wrong.

millis() and micros() return unsigned long: 0 to 4,294,967,295 0xffffffff milliseconds = 49.7+ days 0xffffffff microseconds = 71.58 minutes

all time related elements should use unsigned long to keep the math consistent. Put UL after any constant numbers as well, for example: unsigned long duration = 10000UL; // 10,000uS (10mS)

All is clear now.

Thanks a lot , both of you.

Thank you all for your replies. Unfortunately it seems that what ever I did after reading all posts and links you provided nothing worked...as been said total newb.

The closest I got was when I achieved to light the leds in "sequence"... well the quotes in "sequence" means that when the button is pressed...

  • all leds were lit one after the other... at some point in random time
  • even though I had a 'for statement' to ramp up all pins one by one, I actually achieved to lit the lights in random positions
  • and switch off the leds in random time and position.

Random means complete random namely whenever the button was pushed, high, the randomness of both time and position was also altered.

I have gone through most, if not all, examples I found in the web for the Knight Rider/Cylon/Led Chase with millis function, in order to rearrange it but still no luck. I am frustrated any other hint/tip/solution/keywords???

Thank you all in advance.

Post the code, using code tags, that you are having trouble with and post a schematic of how you have wired it up. If things are happening randomly it looks like you have a floating input somewhere.

Hi everyone and thanks for your feedback and help.

Regarding the previous post from Grumpy_Mike, I followed all connections of buttons and LEDs as the ones given in many other examples in the Arduino examples website. Meaning that I was very confident that NO input was left as floating. As it turns out, I was right for the electronics part of the project, the software part was inadequate since I am a newb.

Instead of posting problems relate to my small project I am posting a tested and working solution for future developers. The following code was tested on an UNO and a Leonardo.

The problem was that I was trying to implement the millis() according to the examples given in the Arduino website without testing other possibilities. The main difference was that ‘while’ I use in the code.

There is a drawback though…

…that small project was part of a larger project where I was trying to use the USB HID properties of the Leonardo hence I was trying to replace the delay(); with the millis();. Well I succeded that but as it turns out the millis(); is still making my USB HID mouse movement to act in the same way as the delay(); so I did not find any difference with that substitution.

I am still seeking explanation over that matter and I believe it lays on my code… again!

However the following code is working as a standalone button and 7 LEDs project and is posted for everyone in need of such feature. All I ask is …whenever you use the following code just open a “cheering” beer and drink it on my behalf. Enjoy the code and beer! Don’t drink and code. Code, then drink wisely! :wink:

/*
  LEDs in sequence, light on and off
  Lights multiple (7) LEDs in sequence when a button is pressed, then are switched off in reverse sequence when the button is released.
  A button is placed in Pin2 of Arduino. 
  LEDs are placed in Pins 7, 8, 9, 10, 11, 12 and 13 of Arduino.
  
  created by Publius, 14/02/2015
*/

const int buttonPin2 = 2;     // the number of the pushbutton pin
int buttonState2 = 0;         // variable for reading the pushbutton status

void setup() {
  
  
  //use a for loop to initialize each pin as an output:
  for (int thisPin = 7; thisPin < 14; thisPin++)  {
  pinMode(thisPin, OUTPUT);      
  }
 
  pinMode(buttonPin2, INPUT);
 }

void loop() {
  buttonState2 = digitalRead(buttonPin2);
  unsigned long previousMillis = 0;
  const long interval = 100;           // sequence interval in milliseconds
  unsigned long currentMillis = millis();

  
  // when pushbutton is high all related leds light on, in sequence
  if (buttonState2 == HIGH) {
  
     // loop from the lowest pin to the highest:
     for (int thisPin = 7; thisPin < 14; thisPin++) {
     // turn the pin on:
    
     while (currentMillis - previousMillis <= interval) 
     currentMillis = millis();
       
     digitalWrite(thisPin, HIGH);    
     currentMillis = millis();
     previousMillis = currentMillis;   
    }
 }
  
  // when push button is low all related leds are turned off in sequence
  else {
    // loop from the highest pin to the lowest:
    for (int thisPin = 13; thisPin > 6; thisPin--) {
    
      while (currentMillis - previousMillis <= interval)
      currentMillis = millis();
  
      digitalWrite(thisPin, LOW);
      previousMillis = currentMillis;   
   }
 } 
}