Arduino Millis() Examples

Example code using millis()

You’ve recently learned about millis() and can’t way to delete all of your references to delay().  The problem is that you don’t know quite how to convert your code into millis()-compatible code.  Here is a (running) list of millis() examples I’ve put together to help.  If you want to know when more are added make sure you subscribe to the RSS feed or email notification list.

Baldengineer’s Arduino millis() Examples

  1. Arduino Multitasking – Step by step examples of how to convert delay() code into millis() based code, to simulate multitasking.
  2. Police Lights – Flash two LEDs like strobing police lights
  3. Control ON and OFF time for a flashing LED. – More control than “blink without delay”
  4. Stopwatch Example – Calculate how much time code takes to execute
  5. Chasing LEDs – Larson-scanner style chasing pattern
  6. De-bounch a button (or switch) – No need for de-bouncing capacitor
  7. Delayed events after a button push – Timed events (button push is just example.)
  8. analogWrite() PWM Fading – No delay() and a simple function to keep a LED fading with PWM
  9. Detect Short and Long Button Press – Give one button multiple functions

You might also want to check out my “Blink Without Delay – Line by Line  Tutorial.” It is a much more in-depth explanation than the comments provided with the Arduino IDE example.

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

Leave a comment

52 thoughts on “Arduino Millis() Examples

  1. Oh I forgot to add, and can see why this is creating some confusion,

    the front and rear lights are off the same pin (im using a mosfet to drive the leds, in parallel, all white, no issue so far

    and the side maker lights are another pin, mosfet etc, so there are only 2 pins, just need another funcition

    sorry for the lack of info..

    • Hi Tim,
      Here is a simpler program. No Mode, only Patterns, You could modify at will each pattern or add new pattern just be sure to update the MaxPattern definition if you do,
      Since we have went around this program a lot, the other readers of this Millis() collumn will find boring reading all of our discussions so If you need other modification or need some clarifications, feel free to contact me using my email. Just use my username and add email to it then ampersand then gmail.com.
      I will be pleased to help you.

      // Arduino program for Strobing Bicycle Lights V 1.00
      //
      // In this program 4 patterns for 2 lights blinking are sequentially selected by a push button
      // Patterns are kept in a 2 dimension Matrix named Event 
      // The corresponding delays is in the Matrix Delays
      
      #define MaxPattern	4			// Number of pattern of blinking light
      #define MaxEvent	9			// Number of max blinking event
      #define ledwstrobe	2			// Define white led pin
      #define ledrstrobe	3			// Define Red led pin
      #define ButtonPin	4			// Define push Button pin. other side connected to ground
      
      // Type of event possible
      enum EventType {None,BothLo,BothHi,RedLo,RedHi,WLo,WHi};   		
      
      // Actual event suite for each pattern. If you have less than MaxEvent, fill with None
      EventType Event[MaxPattern][MaxEvent] =   {{BothHi,None,None,None,None,None,None,None,None},
      									 {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,None},
      									 {BothHi,RedLo,None,None,None,None,None,None,None},
      									 {BothLo,None,None,None,None,None,None,None,None}};
      
      // Actual delay suite for each pattern. If you have less than MaxEvent, fill with 0 delay
      int Delays[MaxPattern][MaxEvent] =  {{0,0,0,0,0,0,0,0,0},
      				  			 {125,125,750,62,63,62,63,125,0},	
      							 {63,63,0,0,0,0,0,0,0},
      							 {0,0,0,0,0,0,0,0,0}};
      		
      unsigned long NextEventTime = 0;   		// When millis() >= NextEventTime then Event is due
      unsigned long LastDebounceTime = 0;		// When millis() >= NextButtonTime then bounce time is due 
      unsigned long DebounceDelay = 50;		// 50ms for general debounce delay
      
      int Pattern = 0;							// Keep track on the next pattern. Value 0 - MaxPattern-1
      int NextEvent = 0;            			        // Keep track of the next event. Value 0 - MaxEvent-1
      
      int ButtonState = HIGH;   				// Variable for current button reading
      int LastButtonState = HIGH;				// Variable for last known button reading
      
      void setup() {
           pinMode(ledwstrobe,OUTPUT);			// white LED
           pinMode(ledrstrobe,OUTPUT);			// red LED
           pinMode(ButtonPin,INPUT_PULLUP);	// put the button to ground to activate
      }
      
      void loop() {
      	
      	// Check the push button
      	int reading = digitalRead(ButtonPin);
        
      	//in the case that the reading is not equal to the last state set the last debounce time to current millis time
      	if (reading != LastButtonState)  {
      		LastDebounceTime = millis();
      	}
      	//check the difference between current time and last registered button press time, if it's greater 
      	if ((millis()-LastDebounceTime) > DebounceDelay) {
      		if (reading != ButtonState) {
      			ButtonState = reading;
      			if (ButtonState == LOW) {						                // Button Pushed !
      				Pattern++;										//	increment Pattern Index
      				if (Pattern == MaxPattern) Pattern=0;	// Roll over if Mode is too big
      				NextEvent = 0;						     			       // Reset to first Event
      				NextEventTime = millis();					               // Reset the Nextime Event Delay
      			}  
      		}
      	}		
      	LastButtonState = reading;								              // Keep the last button state
      
      	if (millis() >= NextEventTime) GoBlink();
         
         // do whatever here 
      
      }
      
      // Do the actual blinking
      
      void GoBlink() {
      // If we find None return to the start of the list
      	if (Event[Pattern][NextEvent] == None) NextEvent = 0;
      	
      // Do the blink indicated by the NextEvent for the current pattern
         switch (Event[Pattern][NextEvent]) {
            case BothLo:
               digitalWrite(ledwstrobe,LOW);
               digitalWrite(ledrstrobe,LOW);
               break;
            case BothHi:
               digitalWrite(ledwstrobe,HIGH);
               digitalWrite(ledrstrobe,HIGH);
               break;
            case RedHi:
               digitalWrite(ledrstrobe,HIGH);
               break;
            case RedLo:
               digitalWrite(ledrstrobe,LOW);
               break;
            case WHi:
               digitalWrite(ledwstrobe,HIGH);
               break;
            case WLo:
               digitalWrite(ledwstrobe,LOW);
               break;
      		case None:
      			break;
         }
      	
      // Add the next delay to millis() and increment tne NextEvent counter
         NextEventTime = millis() +  Delays[Pattern][NextEvent];
         NextEvent++;
      	
      // if we have attained the end of the list, return to the beginning
         if (NextEvent == MaxEvent) NextEvent = 0;
      }
      
  2. Dear bald engineer, (Excuse my english)
    Something puzzle me about millis()
    You used millis() in a way to overcome a roll over problem.
    if (millis() – previousMillis > 1000)

    I don’t understand where the problem is with
    NextTime = millis() + 1000;
    if (millis() >= NextTime)
    As I understand it, if millis() is at his unsigned long limit when I add a Delay of say 1000 to it, NextTime will have a roll over value of 1000. and when millis() is incremented it will revert to 0 and go up until it attain 1000 and the condition will be true. Where is my error in my reasonning?
    Thank’s for helping me understand this question that puzzle me..

    • The problem is how often the if-statement is checked. Here is a practical example where using the “increment” variable fails.

      Let’s say the max millis value is 4,294,967,295. And let’s say when you run “NextTime = millis() + 1000;” millis is 4,294,966,000.
      Now let’s say your code is:

      NextTime = millis() + 1000;
      if (millis() >= NextTime){}
      

      NextTime has the value of 295, because it rolled over. However, millis() has not rolled over yet. So on the next statement, millis() is 4,294,966,002. The if-statement is:

      if (4,294,966,000 > 295). That evaluates as true! And will be true until millis() finally rolls over.

      • Perfect example James. Now I understand why your method is better in the long run.
        Thank you very much.

        Continue your great work, it help a lot of us coding better programs.

  3. Delays[] contain all the delay for the events. The program will add each one in turn to the millis() counter and each time the loop is executed it will check if millis() is now greater than the old millis()+delay implying that it is now the time to switch something on or off. The GoBlink will check which event is due using the array Events[] and switch on or off the led accordingly.

    I made the assumption that your code run indefinitely that blinking pattern and that you wanted your program to do other thing simultaneously. But if this is not the case you could tell me what exactly you want to do. If you want to do many blinking patterns commanded by push button we could alter the solution to suit your need. Just tell me more of what you want to do in detail so I can help you. How many pattern, how many push button, etc.

    • Thanks very much for your reply and help. Basically, I have 1 push button I am using to toggle through 3 modes, (1) mode is all leds on, (2) mode strobe pattern (3) mode leds off. The problem was all the delays and the push button not responding. Perhaps I could put your function into mode 2, call that function on the 2 nd button push.

      void loop() {
      if (digitalRead(3) != state) {
      state = digitalRead(3);
      if (digitalRead(3) == HIGH) {
      mode += 1;
      if (mode > 2) {
      mode = 0;
      }

      if (mode == 0);{

      //all leds on

      }

      if (mode == 1) {

      GoBlink();

      }

      if (mode == 2){

      //all leds off

      }

      something like this is what Im trying to do. Before, with all the delays in the code, it would hang up the digitalRead on pin 3, so it took like 10 pushes just to get a toggle

      • Good idea,

        You shoud reset the mode = 2 variables when a button is pushed just in case the next mode = 2;

        if (digitalRead(3) == HIGH) {
        mode += 1;
        if (mode > 2) mode = 0;
        NextTime = 0;
        NextEvent = 0;
        }

        for mode = 1 you should test if it is time for the next event before jumping to GoBlink()

        if (mode == 1 & millis() >= NextTime) GoBlink();

        When I have a single very short statement in a “if” i don’t use the bracket. I find it cleaner. But maybe it is not a good practice. Do it the way you prefer.

        Good luck!

        • well basically Im not trying to reset, just need to toggle between modes
          your code works great, have the strobes on now, but I want to toggle with a button push, to another mode, like off, on, strobes, then another mode perhaps, front and back on, with side marker leds strobing

          I dont know how to implement that with your code, into the mode toggles

          • Hi Tim, sorry for the delay. ;O)

            Here is the code you need. Was tested with success.
            Work only for around 49 continous days until millis roll over. ;O)

            By the way where are you from?
            I’m from Quebec, Canada

            #define MaxEvent 9 // number of event
            #define ledwstrobe 2 // Define white led pin
            #define ledrstrobe 3 // Define Red led pin
            #define ButtonPin 4 // Define button pin

            // Buttons with Pull-Ups are “backwards” so LOW = Pushed, HIGH = Released

            byte Mode = 0; // Mode 0=On, 1=Blink pattern, 2=Off

            enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi}; // Type of event for blink

            EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
            int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual delay after event

            int NextEvent = 0; // Keep track of the next event value 0 – MaxEvent
            unsigned long NextTime = 0; // When millis() >= NextTime then Event is due
            unsigned long LastDebounceTime = 0; // When millis() >= NextButtonTime then bounce time is due
            unsigned long DebounceDelay = 50; // 50ms for general debounce delay

            int ButtonState = HIGH; //Variable for current button reading
            int LastButtonState = HIGH; //Variable for last known button reading

            void setup() {
            pinMode(ledwstrobe,OUTPUT);
            pinMode(ledrstrobe,OUTPUT);
            pinMode(ButtonPin,INPUT_PULLUP);
            }

            void loop() {

            // Check the push button
            int reading = digitalRead(ButtonPin);

            //in the case that the reading is not equal to the last state set the last debounce time to current millis time
            if (reading != LastButtonState) {
            LastDebounceTime = millis();
            }
            //check the difference between current time and last registered button press time, if it’s greater
            if ((millis()-LastDebounceTime) > DebounceDelay) {
            if (reading != ButtonState) {
            ButtonState = reading;
            if (ButtonState == LOW) { // Button Pushed
            Mode++; // increment Mode
            if (Mode == 3) Mode=0; // Roll over if Mode is too big
            NextEvent = 0; // Reset to first Event
            NextTime = millis(); // Reset the Nextime Event Delay
            }
            }
            }
            LastButtonState = reading; // Keep the last button state

            // do what the Mode variable says
            switch (Mode) {
            case 0:
            digitalWrite(ledwstrobe,HIGH); // LED White On
            digitalWrite(ledrstrobe,HIGH); // LED RED On
            break;
            case 1:
            if (millis() >= NextTime) GoBlink(); // If delay is passed, GoBlink
            break;
            case 2:
            digitalWrite(ledwstrobe,LOW); // LED White Off
            digitalWrite(ledrstrobe,LOW); // LED Red Off
            break;
            }

            // do whatever here
            }

            // Blinking routine

            void GoBlink() {
            switch (Event[NextEvent]) {
            case BothLo:
            digitalWrite(ledwstrobe,LOW);
            digitalWrite(ledrstrobe,LOW);
            break;
            case BothHi:
            digitalWrite(ledwstrobe,HIGH);
            digitalWrite(ledrstrobe,HIGH);
            break;
            case RedHi:
            digitalWrite(ledrstrobe,HIGH);
            break;
            case RedLo:
            digitalWrite(ledrstrobe,LOW);
            break;
            case WHi:
            digitalWrite(ledwstrobe,HIGH);
            break;
            case WLo:
            digitalWrite(ledwstrobe,LOW);
            break;
            }
            NextTime = millis() + Delays[NextEvent];
            NextEvent++;
            if (NextEvent == MaxEvent) NextEvent = 0;
            }

          • Hi Tim, Sorry for the delay(). ;O)

            Here is your program tested and working.
            By the way, where are you from?
            I’m from Quebec, Canada

            Have fun!

            #define MaxEvent 9 // number of event
            #define ledwstrobe 2 // Define white led pin
            #define ledrstrobe 3 // Define Red led pin
            #define ButtonPin 4 // Define button pin

            // Buttons with Pull-Ups are “backwards” so LOW = Pushed, HIGH = Released

            byte Mode = 0; // Mode 0=On, 1=Blink pattern, 2=Off

            enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi}; // Type of event for blink

            EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
            int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual delay after event

            int NextEvent = 0; // Keep track of the next event value 0 – MaxEvent
            unsigned long NextTime = 0; // When millis() >= NextTime then Event is due
            unsigned long LastDebounceTime = 0; // When millis() >= NextButtonTime then bounce time is due
            unsigned long DebounceDelay = 50; // 50ms for general debounce delay

            int ButtonState = HIGH; //Variable for current button reading
            int LastButtonState = HIGH; //Variable for last known button reading

            void setup() {
            pinMode(ledwstrobe,OUTPUT);
            pinMode(ledrstrobe,OUTPUT);
            pinMode(ButtonPin,INPUT_PULLUP);
            }

            void loop() {

            // Check the push button
            int reading = digitalRead(ButtonPin);

            //in the case that the reading is not equal to the last state set the last debounce time to current millis time
            if (reading != LastButtonState) {
            LastDebounceTime = millis();
            }
            //check the difference between current time and last registered button press time, if it’s greater
            if ((millis()-LastDebounceTime) > DebounceDelay) {
            if (reading != ButtonState) {
            ButtonState = reading;
            if (ButtonState == LOW) { // Button Pushed
            Mode++; // increment Mode
            if (Mode == 3) Mode=0; // Roll over if Mode is too big
            NextEvent = 0; // Reset to first Event
            NextTime = millis(); // Reset the Nextime Event Delay
            }
            }
            }
            LastButtonState = reading; // Keep the last button state

            // do what the Mode variable says
            switch (Mode) {
            case 0:
            digitalWrite(ledwstrobe,HIGH); // LED White On
            digitalWrite(ledrstrobe,HIGH); // LED RED On
            break;
            case 1:
            if (millis() >= NextTime) GoBlink(); // If delay is passed, GoBlink
            break;
            case 2:
            digitalWrite(ledwstrobe,LOW); // LED White Off
            digitalWrite(ledrstrobe,LOW); // LED Red Off
            break;
            }

            // do whatever here
            }

            // Blinking routine

            void GoBlink() {
            switch (Event[NextEvent]) {
            case BothLo:
            digitalWrite(ledwstrobe,LOW);
            digitalWrite(ledrstrobe,LOW);
            break;
            case BothHi:
            digitalWrite(ledwstrobe,HIGH);
            digitalWrite(ledrstrobe,HIGH);
            break;
            case RedHi:
            digitalWrite(ledrstrobe,HIGH);
            break;
            case RedLo:
            digitalWrite(ledrstrobe,LOW);
            break;
            case WHi:
            digitalWrite(ledwstrobe,HIGH);
            break;
            case WLo:
            digitalWrite(ledwstrobe,LOW);
            break;
            }
            NextTime = millis() + Delays[NextEvent];
            NextEvent++;
            if (NextEvent == MaxEvent) NextEvent = 0;
            }

      • Third time I try to put the code. Hope this time it will work

        Here is your code Tim. Program is tested and working

        Have fun!

        #define MaxEvent   9   // number of event
        #define ledwstrobe 2   // Define white led pin
        #define ledrstrobe 3   // Define Red led pin
        #define ButtonPin	 4	  // Define button pin
        		
        // Buttons with Pull-Ups are "backwards" so LOW = Pushed, HIGH = Released
        
        byte Mode = 0;									// Mode 0=On, 1=Blink pattern, 2=Off 
        
        enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi};    				// Type of event for blink
        
        EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo}; // Actual event suite
        int Delays[] = {125,125,750,62,63,62,63,125,0};                   // Actual delay after event
        
        int NextEvent = 0;            		// Keep track of the next event value 0 - MaxEvent
        unsigned long NextTime = 0;   		// When millis() >= NextTime then Event is due
        unsigned long LastDebounceTime = 0;	// When millis() >= NextButtonTime then bounce time is due 
        unsigned long DebounceDelay = 50;	// 50ms for general debounce delay
        
        int ButtonState = HIGH;   				//Variable for current button reading
        int LastButtonState = HIGH;			//Variable for last known button reading
        
        void setup() {
             pinMode(ledwstrobe,OUTPUT);
             pinMode(ledrstrobe,OUTPUT);
        	  pinMode(ButtonPin,INPUT_PULLUP);
        }
        
        void loop() {
        	
        	// Check the push button
        	int reading = digitalRead(ButtonPin);
          
        	//in the case that the reading is not equal to the last state set the last debounce time to current millis time
        	if (reading != LastButtonState)  {
        		LastDebounceTime = millis();
        	}
        	//check the difference between current time and last registered button press time, if it's greater 
        	if ((millis()-LastDebounceTime) > DebounceDelay) {
        		if (reading != ButtonState) {
        			ButtonState = reading;
        			if (ButtonState == LOW) {				// Button Pushed
        				Mode++;									//	increment Mode
        				if (Mode == 3) Mode=0;				// Roll over if Mode is too big
        				NextEvent = 0;							// Reset to first Event
        				NextTime = millis();					// Reset the Nextime Event Delay
        			}
        		}
        	}		
        	LastButtonState = reading;						// Keep the last button state
        	
        	
        	// do what the Mode variable says
        	switch (Mode) {
        		case 0:
        			digitalWrite(ledwstrobe,HIGH);				// LED White On
        			digitalWrite(ledrstrobe,HIGH);				// LED RED On
        			break;
        		case 1:
        			if (millis() >= NextTime) GoBlink();		// If delay is passed, GoBlink
        			break;
        		case 2:
        			digitalWrite(ledwstrobe,LOW);					// LED White Off
        			digitalWrite(ledrstrobe,LOW);					// LED Red Off
        			break;
        	}
           
           // do whatever here 
        }
        
        // Blinking routine
        
        void GoBlink() {
           switch (Event[NextEvent]) {
              case BothLo:
                 digitalWrite(ledwstrobe,LOW);
                 digitalWrite(ledrstrobe,LOW);
                 break;
              case BothHi:
                 digitalWrite(ledwstrobe,HIGH);
                 digitalWrite(ledrstrobe,HIGH);
                 break;
              case RedHi:
                 digitalWrite(ledrstrobe,HIGH);
                 break;
              case RedLo:
                 digitalWrite(ledrstrobe,LOW);
                 break;
              case WHi:
                 digitalWrite(ledwstrobe,HIGH);
                 break;
              case WLo:
                 digitalWrite(ledwstrobe,LOW);
                 break;
           }
           NextTime = millis() +  Delays[NextEvent];
           NextEvent++;
           if (NextEvent == MaxEvent) NextEvent = 0;
        }
        
        • dude your a genuis….is it possible to add another function that only has the ledrstrobe, for example, strobing and the ledwstrobe HIGH, like to simulate the front and rear lights HIGH (no strobe) and side marker leds, strobing? im still processing how the events map to the delays to the millis..awesome job dude! thanks so much

          • Hi Tim,
            I’m very far from a genius. James is probably nearer to that definition.
            Like I said earlier, i’m French Canadian so English is a second language for me, so I don’t fully understand what you want exactly.

            Correct me if i’m wrong and you can complete.
            So from what I understand, you would like another strobing pattern added. I suppose from another push of the same button. In that new configuration you would have not 2 but 4 lights (LED) In that case the front red light would strobe and the white light would be on at all time. In the back the red would be On and what is side marker?

            Or maybe you have 6 LED. 2 for the front, 2 for the back and 2 for the light on the top of the car

            So please explain in greater detail so I can try to help you better.

            Don’t fuck yourself understanding the code right now cause the next one will be inspired by, but relatively different.

            What are you trying to do by the way? Building something you can put on your car to simulate a police car. ;O)

        • Thanks again for your help and reply. I have total 8 lights, 2 in front, 2 in back and 2 on each side, of the bike

          So for the last function, I would like to keep the 2 fronts and 2 backs on or HIGH, and strobe the 4 side lights. Just a cool patter I would like to achieve.

          This is just for my bike, to be seen from all angles at night

          So this last function would be mode 4, same push button

  4. int switch1 = 2;
    int i[] = {3, 4, 5, 6, 7, 8};
    int BASE = 3 ; // the I/O pin for the first LED
    int NUM = 6; // number of LEDs
    int ledDelay(45);// Delay
    
    void setup() {
      pinMode(2, INPUT_PULLUP);
      for (int i = BASE; i < BASE + NUM; i ++)
      { pinMode(i, OUTPUT); // set I/O pins as output
        digitalWrite(i, HIGH);
        delay(ledDelay * 8);
      }
    }
    
    void loop() {
      switch1 = digitalRead(2);
      if (switch1 == HIGH) {
        for (int i = BASE; i < BASE + NUM; i ++)
        { digitalWrite(i, HIGH);
        }
      } else {
        for (int i = BASE; i < BASE + NUM; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay); // delay
        }
        for (int i = BASE; i < BASE + NUM; i ++)
        {
          digitalWrite(i, LOW); // set I/O pins as “high”, turn on LEDs one by one
          delay(ledDelay); // delay
        }
        for (int i = BASE + NUM ; i >= BASE; i --)
        {
          digitalWrite(i, HIGH); // set I/O pins as “high”, turn on LEDs one by one
          delay(ledDelay); // delay
        }
        for (int i = BASE + NUM ; i >= BASE; i --)
        {
          digitalWrite(i, LOW); // set I/O pins as “high”, turn on LEDs one by one
          delay(ledDelay); // delay
        }
        for (int i = BASE; i < BASE + NUM; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        for (int i = BASE + NUM ; i >= BASE; i --)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          digitalWrite(i - 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        for (int i = BASE; i < BASE + NUM; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        for (int i = BASE; i < BASE + NUM - 1; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        for (int i = BASE; i < BASE + NUM - 2; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        for (int i = BASE; i < BASE + NUM - 3; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(5, HIGH);
        for (int i = BASE; i < BASE + NUM - 4; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(4, HIGH);
        for (int i = BASE; i < BASE + NUM - 5; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(4, HIGH);
        digitalWrite(3, HIGH);
        for (int i = BASE; i < BASE + NUM - 6; i ++)
        {
          digitalWrite(i, HIGH); // set I/O pins as “low”, turn off LEDs one by one.
          delay(ledDelay);
          digitalWrite(i + 1, HIGH);
          digitalWrite(i, LOW);
          delay(ledDelay); // delay
        }
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(4, HIGH);
        digitalWrite(3, HIGH);;
        delay(ledDelay * 2); // delay
        digitalWrite(8, LOW);
        digitalWrite(7, LOW);
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, LOW);
        delay(ledDelay * 2); // delay
        delay(ledDelay * 2); // delay
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(4, HIGH);
        digitalWrite(3, HIGH);
        delay(ledDelay * 2); // delay
        digitalWrite(8, LOW);
        digitalWrite(7, LOW);
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, LOW);
        delay(ledDelay * 2); // delay
        digitalWrite(8, HIGH);
        digitalWrite(7, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(4, HIGH);
        digitalWrite(3, HIGH);
        delay(ledDelay * 2); // delay
        digitalWrite(8, LOW);
        digitalWrite(7, LOW);
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, LOW);
        delay(ledDelay * 2); // delay
      }
    }
    
    
    • You need to implement a state machine. This is not something I can help you with. If you need one-on-one help, please post your questions on the “Programming” section of the Arduino.cc forums.

  5. In response to Tim, Here is how i do it.
    Hope this help!

    #define MaxEvent   9   // number of event
    #define ledwstrobe 2   // Define white led pin
    #define ledrstrobe 3   // Define Red led pin
    
    enum EventType {BothLo,BothHi,RedLo,RedHi,WLo,WHi};     // Type of event
    
    EventType Event[] = {BothLo,RedHi,RedLo,WHi,WLo,WHi,WLo,WHi,WLo};  // Actual event suite
    int Delays[] = {125,125,750,62,63,62,63,125,0};                    // Actual delay after event
    
    unsigned long NextTime = 0;   // When millis() &gt; NextTime then Event is due
    int NextEvent = 0;            // Keep track of the next event value 0 - MaxEvent
    
    void setup() {
         pinMode(ledwstrobe,OUTPUT);
         pinMode(ledrstrobe,OUTPUT);
    }
    
    void loop() {
       if (millis() > NextTime) GoBlink();
       
       // do whatever here 
    
    }
    
    void GoBlink() {
       switch (Event[NextEvent]) {
          case BothLo:
             digitalWrite(ledwstrobe,LOW);
             digitalWrite(ledrstrobe,LOW);
             break;
          case BothHi:
             digitalWrite(ledwstrobe,HIGH);
             digitalWrite(ledrstrobe,HIGH);
             break;
          case RedHi:
             digitalWrite(ledrstrobe,HIGH);
             break;
          case RedLo:
             digitalWrite(ledrstrobe,LOW);
             break;
          case WHi:
             digitalWrite(ledwstrobe,HIGH);
             break;
          case WLo:
             digitalWrite(ledwstrobe,LOW);
             break;
       }
       NextTime = millis() +  Delays[NextEvent];
       NextEvent++;
       if (NextEvent == MaxEvent) NextEvent = 0;
    }
    
    • Hi thanks again for your code and help. Does this code you provided solve by delay problem? I have too many delays in my code. It seems you moved the delays into the int Delays[ ]

      • Hello Tim,
        I’m sorry but english is not my first language so i don’t understand your question. (Solve by delay problem, Do you mean Solve my delay problem. If this is the question, the answer is yes) You could add as many event as you want. Just add them in the two arrays Event[] and Delays[] and update the value of MaxEvent to reflect the total number of event. That way your code is free to run anything you want. Each time the loop is executed the program test if the next event is due, if not, it continue, if yes, it go to the GoBlink routine. It is as simple as that.

        Tell me if it work for you.

  6. Dear Bald Engineer,

    I was wondering if there is a way to turn the strobe pattern below into mills code?

    digitalWrite(ledwstrobe, LOW);       //set off white strobe
      digitalWrite(ledrstrobe, LOW);       //set off red strobe
        delay(125);
      digitalWrite(ledrstrobe, HIGH);     //set on red strobe
        delay(125);
      digitalWrite(ledrstrobe, LOW);       //set off red strobe
        delay(750);
      digitalWrite(ledwstrobe, HIGH);     //set white strobe on
        delay(62);
      digitalWrite(ledwstrobe, LOW);       //set white strobe off
        delay(63);
      digitalWrite(ledwstrobe, HIGH);      //set white strobe on
        delay(62);
      digitalWrite(ledwstrobe, LOW);       //set white strobe off
        delay(63);
      digitalWrite(ledwstrobe, HIGH);     //set white strobe on
        delay(125);
      digitalWrite(ledwstrobe, LOW);      //set white strobe off
        delay(0);
    }
    
    • Thank you for your reply and help.

      Are these int Delays[] = {125,125,750,62,63,62,63,125,0}; // Actual

      or are those timestamps, for use in the milis code?

      im trying to use a push button to toggle through modes, and it wont work with all m delays. will your code solve this issue?

  7. Hi, I am trying this on TInkerCad and the turn LED does not blink. I have the sketch exactly like above but the only thing I changed was the codes for the remote buttons.ANy idea why

    • TinkerCad is a 3D modeling tool (that is no longer supported.) So I have no idea how you would run code there. It works fine on a real Arduino. If it isn’t working in your code, then there is an issue with your code.

  8. I read all of your examples and I got a few questions.

    I want to make codes which control LED.
    I intended to turn on/off the LED depending on the distance.(I use ultrasonic sensor to check distance)

    For example
    if d is between 10cm and 20cm, LED will be on. (d=distance)
    And if d is between 10cm and 20cm for 5 seconds, LED will be off though it is in ‘ON-STATE’ distance.

    My question is how I can do it by using ‘Millis’.
    plz help, especially ‘And if ‘ line .

    • If you have a specific question, I can try to help. But I can’t provide general project help. I recommend posting on the arduino.cc forums. Look at either the Project Guidance or Programming Questions sections.

  9. How to use millis command in coin slot operation? please help thanks. we cannot use delay because it disrupts the process.

  10. Hi i was wondering if you could help me out..i am trying to run a vibrator motor on my arduino along with two other sensors,i want the vibrator motor to start if any of the two sensors are continuously active for 2 minutes ..can you please help me modify my code for millis()

  11. Hi,
    I am trying to make LED blink at 0.7hz like turn signal of cars/motorcycles
    Trying to get it work like this:
    When a button on IR remote is pressed (hex code : 0x811), turn signal should start blinking at 0.7hz until a button on the remote is pressed again to turn it off (0x11).

    Is it possible? I’d really appreciate if you could help me with this.

    So far I have succeded to make LEDs on and off using IR remote buttons. But can’t get LEDs start blinking after pressing a key on IR remote and keep constantly blinking until IR remote button is pressed to turn it off.
    I have tried blink without delay example but couldn’t get it working.

    here is an example code i am using.

    #include <IRremote.h>
    #include <IRremoteInt.h>
    #define irPin 2 //IR receiver on pin 2
    int led1 = 3; //LED that turns on and off using IR remote button.
    int turn = 12; //turn indicator blinker. Should start blinking at 0.7hz after key on remote is pressed
    IRrecv irrecv(irPin);
    decode_results results;
    
    void setup() {
      Serial.begin(9600);
      irrecv.enableIRIn();
      pinMode(led1, OUTPUT);
      pinMode(turn, OUTPUT);
    
    }
    void loop() {
      if (irrecv.decode(&results)) {
        switch (results.value) {
    
          case 0x837: //IR remote key to turn LED1 ON
            digitalWrite(led1, HIGH);
            break;
    
          case 0x37: //IR remote key to turn LED1 OFF
            digitalWrite(led1, LOW);
            break;
    
          case 0x834: //I want to use this key to start blinking ‘turn’ LED at 0.7hz
            // don’t know what to do here
            break;
    
          case 0x34: //I want to use this key to stop blinking ‘turn’ LED
            // don’t know what to do here
            break;
    
        }
        irrecv.resume();
      }
    }
    
    • I would do something like this, using millis() and a flag variable. for your cases when you want to turn the LED on and off, you just set the flag. this way each time loop() runs, if the flag is on, the blink is done.

      (I don’t have an arduino with me to test this code.)

      You can also download here: https://pastebin.com/prQqTWG0

      #include <IRremote.h>
      #include <IRremoteInt.h>
      #define irPin 2 //IR receiver on pin 2
      
      
      int led1 = 3; //LED that turns on and off using IR remote button.
      int turn = 12; //turn indicator blinker. Should start blinking at 0.7hz after key on remote is pressed
      
      bool blinking = false;  //defines when blinking should occur
      unsigned long blinkInterval = 1420;  // number of milliseconds for blink (1/0.7)
      
      unsigned long currentMillis; // variables to track millis()
      unsigned long previousMillis; 
      
      IRrecv irrecv(irPin);
      decode_results results;
      
      void setup() {
        Serial.begin(9600);
        irrecv.enableIRIn();
        pinMode(led1, OUTPUT);
        pinMode(turn, OUTPUT);
      }
      void loop() {
        
        // this code blinks the LED 
        if (blinking) {    
          currentMillis = millis();  // better to store in variable, for less jitter
          if ((unsigned long)(currentMillis - previousMillis) >= blinkInterval) {  // enough time passed yet?
            digitalWrite(turn, !digitalRead(turn));  // shortcut to toggle the LED
            previousMillis = currentMillis;  // sets the time we wait "from"
          }
        } else {
          digitalWrite(turn, LOW); // force LED off when not blinking
        }
        
        if (irrecv.decode(&results)) {
          switch (results.value) {
      
            case 0x837: //IR remote key to turn LED1 ON
              digitalWrite(led1, HIGH);
              break;
      
            case 0x37: //IR remote key to turn LED1 OFF
              digitalWrite(led1, LOW);
              break;
      
            case 0x834: //I want to use this key to start blinking ‘turn’ LED at 0.7hz
              blinking = true;
              break;
      
            case 0x34: //I want to use this key to stop blinking ‘turn’ LED
              blinking = false;
              break;
      
          }
          irrecv.resume();
        }
      }
      
      • Wow. it works

        Thanks alot, you’re the man. 🙂
        I was trying to figure it out for ages. Really appreciate your help.

        Thanks again.

  12. Hi,

    Wondered if you can assist/ point me in the right direction?
    I am thinking about measuring the Overall Equipment Effectiveness of a machine (OEE) via a retro-fitted status box.

    Initial thoughts are to have a sensor measuring the speed
    While the speed is being in the High status no event
    When the speed = 0 [i.e. the machine stops]
    I am wanting to record the real time it actually stopped

    Then the operator will activate a condition toggle for an array of 3 conditions
    1. Waiting for a Material
    2. Waiting for an engineer
    3. Defect

    When the toggle condition is induced this is to be timed (real time)

    until the condition is cleared and the machine runs

    Could you give me a clue where to find a similar program please?

    Thanks in advance

    • I doubt you’ll find an exact match.

      An alternative to a microcontroller based solution would be using a programmable logic controller (PLC). They’re industrial microcontrolllers with programming “languages” designed specifically for working with machines.

  13. Hi, HELP please…
    i want to remove all the delays from the codes below:v

    void loop(){
    northtogreen(); //change the north signal to green
    delay(maindelay*4); //wait for the traffic to pass
    northtored(); //change the north signal back to red
    delay(maindelay/2); //small delay to allow traffic to clear junction
    easttogreen(); //change the east signal to green
    delay(maindelay*4);//wait for the traffic to pass
    easttored(); //change the east signal back to red
    delay(maindelay/2); //small delay to allow the traffic to clear junction

    }
    void northtogreen(){ //sequence of north lights going to green

    digitalWrite(northAmber,HIGH); //Amber on, prepare to go
    delay(maindelay); //Time for traffic to see amber
    digitalWrite(northRed,LOW); //red off, finished with
    digitalWrite(northAmber,LOW); //amber off, finished with
    digitalWrite(northGreen,HIGH); //green on, go

    }
    void northtored(){ //sequence of north lights going to red

    digitalWrite(northAmber,HIGH); //Amber on, prepare to stop
    digitalWrite(northGreen,LOW); //Green off, finished with
    delay(maindelay); //Time for traffic to stop
    digitalWrite(northAmber,LOW); //Amber off
    digitalWrite(northRed,HIGH); //Red on, stop

    }

    void easttogreen(){ //sequence of east lights going to green

    digitalWrite(eastAmber,HIGH); //Amber on, prepare to go
    delay(maindelay); //Time for traffic to see amber
    digitalWrite(eastRed,LOW); //red off, finished with
    digitalWrite(eastAmber,LOW); //amber off, finished with
    digitalWrite(eastGreen,HIGH); //green on, go

    }

    void easttored(){//sequence of east lights going to red

    digitalWrite(eastAmber,HIGH); //Amber on, prepare to stop
    digitalWrite(eastGreen,LOW); //Green off, finished with
    delay(maindelay); //Time for traffic to stop
    digitalWrite(eastAmber,LOW); //Amber off, finished with
    digitalWrite(eastRed,HIGH); //Red on, stop

    }

    thanks 🙂

    • It really isn’t a simple method like “replace” the calls to delay(). You need to create a state machine. (Which will be a topic for a future post). A state machine is where you create one or more variables that tell your code what to do at certain times. So for example you might have a “AmberState”. When State is 0, the pin is off for 500ms. After 500ms you change the state to 1. Whenever the state is 1 you turn on the pin. When another 500ms passes, you set it back to 0.

      • Four year later…

        /*
        	Standard Traffic Light. Red Amber Green on each side
        	No delay, 2 variables
        */
        
        #define NorthGreenPin	2
        #define NorthAmberPin	3
        #define NorthRedPin	4
        #define EastGreenPin	5
        #define EastAmberPin	6
        #define EastRedPin		7
        
        #define WaitGreen			30000			// Green for 30 seconds
        #define WaitAmber			5000			// Amber for 5 seconds
        #define WaitMore			2000			// Red on both side for 2 seconds
        
        unsigned long	NextTime  = 0;
        int			NextEvent = 1;
        
        void setup(){
        // Assign Pin
        	pinMode(NorthGreenPin,OUTPUT);
        	pinMode(NorthAmberPin,OUTPUT);
        	pinMode(NorthRedPin,OUTPUT);
        	pinMode(EastGreenPin,OUTPUT);
        	pinMode(EastAmberPin,OUTPUT);
        	pinMode(EastRedPin,OUTPUT);
        
        // Start with East Red	
        	digitalWrite(EastRedPin,HIGH);
        }
        
        void loop(){
        	if (millis() > NextTime) CheckLight();
        }
        
        void CheckLight(){
        
        switch (NextEvent) {
        	case 1:											// North Green
        			digitalWrite(NorthRedPin,LOW);
        			digitalWrite(NorthGreenPin,HIGH);
        			NextTime = millis() + WaitGreen;
        			NextEvent = 2;
        			break;
        	case 2:											// North Green to Amber
        			digitalWrite(NorthGreenPin,LOW);
        			digitalWrite(NorthAmberPin,HIGH);
        			NextTime = millis() + WaitAmber;
        			NextEvent = 3;
        			break;
        	case 3:											// North Amber to Red 
        			digitalWrite(NorthAmberPin,LOW);
        			digitalWrite(NorthRedPin,HIGH);
        			NextTime = millis() + WaitMore;
        			NextEvent = 4;
        			break;
        	case 4:											// East Green
        			digitalWrite(EastRedPin,LOW);
        			digitalWrite(EastGreenPin,HIGH);
        			NextTime = millis() + WaitGreen;
        			NextEvent = 5;
        			break;
        	case 5:											// East Green to Amber
        			digitalWrite(EastGreenPin,LOW);
        			digitalWrite(EastAmberPin,HIGH);
        			NextTime = millis() + WaitAmber;
        			NextEvent = 6;
        			break;
        	case 6:											// East Amber to Red
        			digitalWrite(EastAmberPin,LOW);
        			digitalWrite(EastRedPin,HIGH);
        			NextTime = millis() + WaitMore;
        			NextEvent = 1;
        			break;
        	}	
        }