There might still be holes in your description.
If a led is on, and the button is pressed (while the led is still on), should it advance to the next led ?
I wanted to see how many variables I would need when there are 4 blinking leds. It turns out that I need a many variables. Maybe too many ![]()
This is not me knowing how to write this sketch. To be honest, I randomly threw in the code that I needed and then I moved around the code lines until it worked ![]()
#define NUM_LEDS 4
int ledPins[NUM_LEDS] = { 13, 12, 11, 10};
int currentLed = 0; // this is also the index to the array with pins
int ledState = LOW; // used the blink the active current led
bool ledActive; // is the led blinking and the timeout active ?
unsigned long timeStampButton = 0; // remember moment of last button press
unsigned long previousMillisBlink; // used to blink the led
const unsigned long timeOut = 2000UL; // timeout for millis-timer
const unsigned long blinkInterval = 150UL; // interval for blinking
const unsigned long debounceTime = 20UL; // timing for debouncing
const int buttonPin = 2; // a button is connected to pin 2 and GND
int lastButtonState = HIGH; // idle high
void setup()
{
for( int i=0; i<NUM_LEDS; i++)
pinMode( ledPins[i], OUTPUT); // all the leds are outputs
pinMode( buttonPin, INPUT_PULLUP);
// Set initital state, turn first led on, start millis-timer
currentLed = 0;
timeStampButton = millis();
ledActive = true;
}
void loop()
{
unsigned long currentMillis = millis();
int buttonState = digitalRead( buttonPin);
if( buttonState != lastButtonState && currentMillis - timeStampButton >= debounceTime)
{
lastButtonState = buttonState;
timeStampButton = currentMillis; // timestamp of last valid button press
if( buttonState == LOW) // low is active
{
// The current led could be on
if( ledActive && ledState == HIGH)
digitalWrite( ledPins[currentLed], LOW);
// advance to the next led
currentLed++;
if( currentLed >= NUM_LEDS)
currentLed = 0;
ledActive = true;
}
}
if( ledActive)
{
if( currentMillis - timeStampButton >= timeOut)
{
// turn this led off
digitalWrite( ledPins[currentLed], LOW);
ledActive = false; // turn millis-timer off
}
else if( currentMillis - previousMillisBlink >= blinkInterval)
{
previousMillisBlink = currentMillis;
ledState = ledState == HIGH ? LOW : HIGH; // toggle led state
digitalWrite( ledPins[currentLed], ledState);
}
}
}
Try this sketch in Wokwi simulation:
You should find you own way to make your own sketch. I hope that you see that I put the millis-timer in the main level of the loop() and the millis-timer runs on its own.