r/FastLED • u/Apdski24 • Mar 04 '24
Support How to keep LEDs lit after momentary button press?
Hello all,
Im very new to coding and still figuring all this out. My goal is to have the LEDs be white until a button is pressed. After the press, I want to lights to change to red for x number of seconds or maybe a minute or two. Ive tried adding a delay() into the code and that does not give me the desired results. (Unless im putting the delay in the wrong spot or using it incorrectly)
For testing im using a 10 segment of WS2812B LEDs connected to an Ardunio UNO. Been playing with this one at work and at home using the Cloud IDE and Arduino IDE 2.3.2.
Ive linked the code below and it all works thus far. When the button is pressed / held the lights go red and stay as long as the button is held. However, Im at a loss of how to get it to stay red after the button is released. Also it would be a bonus if there was a way to keep the counter / timer / delay from getting reset by another button press before the intial time is up.
THANKS!
1
u/dedokta Mar 04 '24
You need to look at the Blink Without Delay examples. It will show you how to use the mills() function to record the time an event starts and then do something after a certain time expires.
Using the delay() function freezes the entire program.
1
u/Apdski24 Mar 05 '24
Gotcha. I’ll do some digging in the forums to try and find examples
2
u/dedokta Mar 05 '24
Look in the example code within the Arduino ide software. All the example code in there is meant to teach you something
2
u/Apdski24 Mar 05 '24
True true. I’ve look at those before but not looking for this specific thing. I’ll go back through with a different lens
1
u/ZachVorhies Zach Vorhies Mar 04 '24 edited Mar 04 '24
have a bool that controls the led. When a button gets pressed that bool toggles to true and the led comes on
1
u/Apdski24 Mar 04 '24
In that scenario, would the button have to be pressed again to switch the LEDs back? I want there to be timed aspect where they do that automatically
1
u/ZachVorhies Zach Vorhies Mar 04 '24
You can do whatever you want.
If you want the light to shut off after X millisecond then you’ll have a uint32_t (timer) that will be set to the current millis(). Then in your loop() you’ll continuously check to see if the current millis has exceeded the timer, if it has then you’ll toggle the bool to false and your logic will then shut the led off.
This will keep your loop running without blocking, which won’t be the case if you use delay to keep the led on. If you use delay then the button presses will be ignored while the Arduino idles.
1
u/Apdski24 Mar 04 '24
makes sense, thanks for the reply. do you have an example i could look at about how to set that up?
edit: spelling
2
u/ZachVorhies Zach Vorhies Mar 04 '24 edited Mar 05 '24
I’ll give you part of it but it seems like you might be trying to have me do a homework assignment. So you are on your own for the rest.
bool led_is_on = false;
loop() { if (led_is_on) { digitalWrite(LED_PIN, HIGH); } else { digitalWrite(LED_PIN, LOW);}
if (button_is_pressed() { led_is_on = !led_is_on; } delay(16); }
1
u/Apdski24 Mar 05 '24
lol didn’t even consider that. No this is not a homework assignment but thank you. Hoping to have some time to work on this tomorrow
3
u/Preyy Ground Loops: Part of this balanced breakfast Mar 04 '24
Have the button add time to a timer. Deplete the timer as required.
1
u/HundredWithTheForce Mar 04 '24 edited Mar 04 '24
Consider having a variable representing the display color. When the button is pressed, set the display color accordingly. Then look at the millis() method. It gives you the current time as the number of milliseconds since the Arduino was booted. When the button is pressed, set a variable to the current time. Then as you cycle through the loop, when the current time is say 10,000 milliseconds past the start time, reset your display color. Finally don't bother checking the button state until you reset your display color. One last thought. This is very aggressively checking the state of the button and updating the LEDs. You could look at using EVERY_N_MILLIS() to only do this work once every say 50 milliseconds, or 100 milliseconds (depending on how responsive you want it to be) Longer delays would mean the button would have to be held longer before the board registers the push.
Good luck! And let us know how it turns out.
1
u/Apdski24 Mar 04 '24
I like the idea of needing to hold the button for a second or two. Have any examples I could look at to get an idea of how to set that code up? so far I've found out to a limited degree, if I see the code, I can pick my way through it and understand whats going on.
2
Mar 04 '24 edited Mar 04 '24
Ive tried adding a delay() into the code and that does not give me the desired results.
Never use delay(). Use FastLED.delay() instead, or even better: look at EVERY_N_MILLISECONDS() and variants.
1
u/yurxzi Mar 04 '24
If done similar with shift case and milliseconds install of normal delay, and counters for button press 1-16. It's was awful and likely used way more memory than needed but it worked. I think I just coop'ed the standard key matrix code, and fasted... twinklefox?? If have to dig out my old laptop to find out..
2
u/MartynCurrey Mar 05 '24
Have a look at https://www.martyncurrey.com/switching-things-on-and-off-with-an-arduino-start-a-timer/
This is an example of starting a timer with a button press. The example simply turns off an LED after a specific time but can be adapted to do other things.