Arduino Example: Police Lights with millis()

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

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.

ALL comments submitted with fake or throw-away services are deleted, regardless of content.

Don't be a dweeb.

Leave a comment

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

  1. The code wouldn’t run until I inserted (long) before the two occurrences of millis in the loop().
    This was included in an earlier example but is missing in this one.

    Out of interest, it didn’t work with (unsigned long) inserted. Why is this????

  2. Thank you for this, I find it very helpful. One thing I noticed: “`strobeWait += strobeDelay;“` would count up until breaking some limit or buffer wouldn’t it? Could you show to to modify your example to prevent that? Thank you.

  3. Dear James Lewis , I used your code to my IR control code ,the Police Lights can ruining and flash,
    but i can not turn off some time,some time the pin 13 light on,some time the pin 11 light on ,some time pin 12 & 13 off .
    I am a tiro ,can you help me what wrong in my code at turn off the police lights,thank you.

    #include

    int irPin = 7; //ir sensor pin
    int landing = 5; //landing lights, taxi lights and logo lights
    int Position = 6; //red/green/white lights on wing tips – no flash –
    int antiCol = 9; //red flashing lights on top and bottom
    const int strobe = 8; //tail and wingtips
    int all[] = {5, 6, 9, 8}; //all lights
    int strobeState = LOW;
    long prevMillis = 0;
    long interval = 3500; //time between flashes
    bool StrobeIsFlashing=false;

    // 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 = 11;
    const int LED_Blue = 13;

    // 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

    IRrecv irrecv(irPin);
    decode_results results;

    void setup(){
    Serial.begin(9600); //starts serial monitor *for debuging*
    irrecv.enableIRIn(); //starts IR reciever
    pinMode(landing, OUTPUT);
    pinMode(Position, OUTPUT);
    pinMode(antiCol, OUTPUT);
    pinMode(strobe, OUTPUT);
    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

    if (irrecv.decode(&results)){
    long int decCode = results.value;
    Serial.println(decCode);
    switch (results.value){
    case 2079:
    digitalWrite(landing, 1);
    Serial.println(“LANDING/TAXI/LOGO LIGHTS ENGAGED”);
    break;

    case 31:
    digitalWrite(landing, 0);
    Serial.println(“LANDING/TAXI/LOGO LIGHTS DISENGAGED”);
    break;

    case 2108:
    digitalWrite(Position, 1);
    Serial.println(“POSITION LIGHTS ENGAGED”);
    break;

    case 60:
    digitalWrite(Position, 0);
    Serial.println(“POSITION LIGHTS DISENGAGED”);
    break;

    case 0xFF52AD:
    Serial.println(“STROBE ACTIVATED”);
    StrobeIsFlashing=!StrobeIsFlashing;
    break;

    default:
    Serial.println(“WAITING”);
    }
    irrecv.resume();
    }
    if(StrobeIsFlashing)
    {
    FlashStrobe();
    }
    }

    void FlashStrobe()
    {
    if (strobeState == 0)
    if ((long)(millis() – waitUntilSwitch)>=0) {
    // time is up!
    Red_State = LOW;
    Blue_State = LOW;
    whichLED = !whichLED; // toggle LED to strobe
    waitUntilSwitch += switchDelay;
    }
    if ((long)(millis() – strobeWait)>=0) {
    if (whichLED == RED)
    Red_State = !Red_State;
    if (whichLED == BLUE)
    Blue_State = !Blue_State;
    strobeWait += strobeDelay;
    strobeState = 1;
    }
    else
    digitalWrite(LED_Red, LOW);
    digitalWrite(LED_Blue, LOW);
    strobeState = 0;
    }

  4. Hi, Tried your code and it works great. I also added a button to the code so I can turn it on and off. But sometimes (can’t really tell when exactly) when I turn on the flasing leds, they don’t flash like I expect (500/50) but they just light up one by one, with half a second of delay, so the switching of the leds works, but the strobe flashing doesn’t. After a couple of seconds (didn’t count this) the normal pattern starts again.

    Any idea what could cause this?

  5. Great to visit the page.

    In fact I was looking for how to use mill() instead of delay and the research forced me to leave my problem.
    I am working on a program where i want to press and hold a push button and stop the program to wait till i release the button then the program will resume where it stopped within a set time . Now when i press and hold the button, the time is running and after releasing the code ends before the set time ends.

     while (!digitalRead(pushButtonin)) // If the button pin is low, this will wait until it goes high again. Otherwise it'll just skip
         {}
            delay(1000);
    float  elapsed,finished, start; 
              
          while(digitalRead(pushButtonin)==HIGH)
      {    
       digitalWrite(relaypin, LOW); 
    } 
       delay(100);
          val=digitalRead(pushButtonin);
         start=millis();             
    while(DT>=elapsed)
    
    { 
    if( val=HIGH){
      digitalWrite(relaypin, HIGH); 
    }
       while(digitalRead(pushButtonin))
      {    
       digitalWrite(relaypin, LOW); 
         
          }
    
     digitalWrite(relaypin, HIGH);
     
      finished=millis();
     elapsed=(finished-start);
    }
     
       delay(DT); 
        
    digitalWrite(relaypin,LOW);
    

    kind regards