Based on a question from Andrew on the initial Multitasking with millis() tutorial, this example shows how to create a Police-Light like strobe effect. The following code uses no calls to delay().
Code also available via Pastebin.org.
// English for which LED to Strobe #define RED 0x0 #define BLUE 0x1 // Variable to track which LED is on byte whichLED = RED; // Where are the LEDs connected? const int LED_Red = 7; const int LED_Blue = 11; // State variables for the LEDs byte Red_State = LOW; byte Blue_State = LOW; // Some delay values to change flashing behavior unsigned long switchDelay = 250; unsigned long strobeDelay = 50; // Seed the initial wait for the strobe effect unsigned long strobeWait = strobeDelay; // Variable to see when we should swtich LEDs unsigned long waitUntilSwitch = switchDelay; // seed initial wait void setup() { pinMode(LED_Red, OUTPUT); pinMode(LED_Blue, OUTPUT); } void loop() { digitalWrite(LED_Red, Red_State); // each iteration of loop() will set the IO pins, digitalWrite(LED_Blue, Blue_State); // even if they don't change, that's okay // Toggle back and forth between the two LEDs if ((millis() - waitUntilSwitch) >= 0) { // time is up! Red_State = LOW; Blue_State = LOW; whichLED = !whichLED; // toggle LED to strobe waitUntilSwitch += switchDelay; } // Create the stobing effect if ((millis() - strobeWait) >=0 ) { if (whichLED == RED) Red_State = !Red_State; if (whichLED == BLUE) Blue_State = !Blue_State; strobeWait += strobeDelay; } }
State Variables
Red_State and Blue_State
Instead of using digitalWrite() directly, “state” variables are used to determine the state (on or off) of each LED. This allows logic inside the loop() to determine when the lights should be turned on or off. Each iteration of loop() will update the LEDs with a digitalWrite() based on this state variable.
whichLED
Using a couple of #define statements, this variable tracks which LED should be strobing at a given time. The #define statements are optional, but make the code easier to follow later on (Around line 46).
wait Variables
waitUntilSwitch
This variable tracks the millis() value needed before switching between the Red and Blue LED. It is incremented by switchDelay.
strobeWait
This variable determines the rate at for the currently strobing LED. It is incremented by strobeDelay. [Note: strobeDelay must be some multiple less than switchDelay for a strobe effect.]
millis() if-statements
Both of the millis() if-statements make use of millis() rollover handling, instead of trying to reset millis().
The millis() loops should be self-explanatory, after reading the millis() multitasking tutorial. The first if-statement (line 36) checks to see if it time to switch the active LED. It makes sure to disable both LEDs before setting a state, so one does not get “stuck on.”
The if-statement on line 45 independently controls the strobing of the active LED. This is why the #define statements were used at the top of the code. It makes it clearer to the reader that lines 46 and 48 are checking to see which LED is the active LED. [Note: A switch() statement would be appropriate if more than 2 LEDs were used in the sequence.]
Just an update from me, I built 2 light bars for my truck and modified your code here to suit my needs and I’ve made a video of both bars.
You can view the video here
Looks great! Thanks for sharing the update.
Love the code, simplifies my giant batch of delays which stopped me reading an input status down to something totally workable.
one question though, is it possible to have differnt timing for the on and off times. ie yours currently runs at 50ms on 50ms off and completes 3 flashes before changin colour.
is it possible to have 60ms on, 25 ms off. in the same pattern? obviously changing the switch delay to 340ms (would give 4 flashes of each colour with a delay in the middle. unlike your code that skips the delay on the transition?)
You would need to modify the code to define an “on” and “off” delay. An example of a single LED can be found here: https://www.baldengineer.com/blog/2013/12/10/millis-ind-on-off-times/. Can’t just copy and paste the two together, but I think you could see how to build up a simple state machine.
Great site, thanks. Took your Police Light and implemented it on a NeoPixel Shield. You can see a video here http://youtu.be/2VhoQlK7hMs and the code is available in pastebin http://pastebin.com/eeiPckxx
Thanks
Stuart/
[Edit: I fixed the link and deleted the other comment…]
like this setup. trying to get a strobe to work where i get two quick flashes and then off for x time trying to so without a delay command
You need to setup a flag variable to tell when you should be strobing and a variable as the timer. Set the timer to off-value. Whenever the timer is reached, set the flag variable to true. When flag variable is true, flash the strobes. On the 2nd strobe, set the variable back to false and reset your timer.
Would it be possible to see an example with more than 2 led’s, say maybe 7 led’s?
I’m not really sure how to create a “police” strobe with 7 LEDs, since they generally just flash back and forth.
I’m thinking more along the lines of a light bar, like you see on the roof of the cars, they have 8 segments (16 if you include front and rear), that flash at different times.
I have acquired a tow truck light bar (all amber leds) that was damaged. I only have 7 working led packs (three to a pack) and am currently using lots of delays and spaghetti code to make it work. Your method seems nicer.
Can they flash randomly or do you want a specific pattern?
Currently I have 6 patterns that I can select from, but that’s overkill really. A random strobe effect would be cool, as well as two official looking patterns. I was discussing your code with a friend a bit more knowledgeable than myself, and he said using arrays to define the patterns would be my best bet.
Sorry about that. I’m not sure what step in my publishing process introduces the change. The symbols < and > are used by HTML code, so one step in my process converts them into the symbol codes > and %lt;.
But, that’s why I also make the code available via Pastebin. 😉
Checked code on other site and it was better..it should be a > symbol.
What is the >? It gives me an error..
Andrew
I will give that a try and try to add more lights at different rates. Thanks!