Arduino Example: Police Lights with millis()

Based on a question from Anderw 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 ((long)(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 ((long)(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.]

Leave comments below if you have Questions or other Example Ideas.

Long comments, URLs, and code tend to get flagged for spam moderation. No need to resubmit.

Leave a comment

30 thoughts on “Arduino Example: Police Lights with millis()

    • Depends on what you mean by add. If you want more LEDs to turn on at the same time, add more pin assignments, pinmodes(), and digitalWrites().

      If you more patterns, then you duplicate all of the “red/blue” variables for more groups. There are more efficient coding methods, maybe using an enum.

  1. I found this code on Youtube and I’m sure it is yours but it is slightly different as it has wigwags integrated into it. I absolutely love the design. and will be using it in my project (Thank you). I was hoping to be able to alter the wigwag to wigwag for a few seconds and then strobe for a couple seconds then repeat. Also I was wondering if there is a way to integrate an IR receiver to control functions separately. For example 1 just the wigwags and another just the other lights, and another all the lights. I hope that you can help as I can alter code some but am terrible at writing it. Here is the code I have:

    #define RED 0x0
    #define BLUE 0x1
     
    int variStrobe[7]={100,250,250,100,450,50,75};
    int variCount = 0;
    int variAdder = 0;
    int variLast = 0;
    int wigWagDelay = 200;
    long wigWagPrev = 0;
    int wigWagState = LOW;
     
     
    byte whichLED = RED;
     
     
    const int LED_Red = 12;
    const int LED_Blue = 13;
    const int LED_wigwag1 = 11;
    const int LED_wigwag2 = 10;
     
     
    byte Red_State = LOW;    
    byte Blue_State = LOW;    
     
     
    unsigned long switchDelay = variStrobe[variAdder];
    unsigned long strobeDelay = 50;
     
     
    unsigned long strobeWait = strobeDelay;
     
     
    unsigned long waitUntilSwitch = switchDelay;  
     
     
    void setup() {
       pinMode(LED_Red, OUTPUT);
       pinMode(LED_Blue, OUTPUT);
       pinMode(LED_wigwag1, OUTPUT);
       pinMode(LED_wigwag2, OUTPUT);
    }
     
    void loop() {
            digitalWrite(LED_Red, Red_State);
            digitalWrite(LED_Blue, Blue_State);
     
    unsigned long wigWagMillis = millis();
             
            if ((long)(millis() - waitUntilSwitch)>=0) {
                    // time is up!
                    Red_State = LOW;
                    Blue_State = LOW;
                    whichLED = !whichLED;  // toggle LED to strobe
                    waitUntilSwitch += switchDelay;
                     
                    variCount++;
                    if(variCount-variLast==10)
                  {
                    variAdder++;
                    variLast = variCount;
                    switchDelay = variStrobe[variAdder];
                    if(variAdder>6){
                     variCount = 0;
                     variAdder = 0;
                     variLast = 0; 
                    }
                  }
                   
                }
            
            // Create the stobing effect
            if ((long)(millis() - strobeWait)>=0) {
                    if (whichLED == RED)
                            Red_State = !Red_State;
                    if (whichLED == BLUE)
                            Blue_State = !Blue_State;
                    strobeWait += strobeDelay;
            }
       
      if(wigWagMillis - wigWagPrev > 150)
      {
       wigWagPrev = wigWagMillis;
       wigWagState = !wigWagState;
       digitalWrite(LED_wigwag1, wigWagState);
       digitalWrite(LED_wigwag2, !wigWagState);   
      }
             
    }
    
    • In order to help, you’d need to provide more details. It might be better to post your questions on a forum, like the Programming Forum on arduino.cc. So that others can help you as well.

  2. hello, I would like to include in your sketch also turn signals. which code should I add? Thanks. Sorry for my bad! english.

  3. This is unbelievable to me. The logic evades me for some reason. I’ve even drawn the flow of it out on paper and can’t quite get it. It works beautifully, though. Really cool. I had my own version without using delay(), but yours is more robust. The strobes are brighter and more definite.
    My version switches between two if() statements with 4 digitalWrite()s in each of them. LOL.
    Thanks.

  4. 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?)

  5. 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.

      • 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.

          • 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.

  6. 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. 😉