After working through these exercises, check out this article on how to avoid rollover or reset mills().

After learning how to flash a single LED on your Arduino, you are probably looking for a way to make cool patterns, but feel limited by the use of delay(). If you ask in the forums, you get told to look at the “Blink Without Delay” example. This example introduces the idea of replacing delay() with a state machine. If you’re confused how to use it, this tutorial is setup to take you from blinking two LEDs with delay, to using an alternate method, right down to how you can use millis().

The millis() function is one of the most powerful functions of the Arduino library. This function returns the number of milliseconds the current sketch has been running since the last reset. At first, you might be thinking, well that’s not every useful! But consider how you tell time during the day. Effectively, you look at how many minutes have elapsed since midnight. That’s the idea behind millis()!

Instead of “waiting a certain amount of time” like you do with delay(), you can use millis() to ask “how much time has passed”? Let’s start by looking at a couple of ways you can use delay() to flash LEDs.

Example #1: Basic Delay

You are probably already familiar with this first code example The Arduino IDE includes this example as “Blink.”

void setup() {
	pinMode(13, OUTPUT);
}

void loop() {
	digitalWrite(13, HIGH); // set the LED on
	delay(1000); // wait for a second
	digitalWrite(13, LOW); // set the LED off
	delay(1000); // wait for a second
}

Reading each line of loop() in sequence the sketch:

  1. Turns on Pin 13’s LED,
  2. Waits 1 second (or 1000milliseconds),
  3. Turns off Pin 13’s LED and,
  4. Waits 1 second.
  5. Then the entire sequence repeats.

The potential issue is that while you are sitting at the delay(), your code can’t be doing anything else. So let’s look at an example where you aren’t “blocking” for that entire 1000 milliseconds.

Example #2: Basic Delay with for() loops

For our 2nd example, we are only going to delay for 1ms, but do so inside of a for() loop.

void setup() {
	pinMode(13, OUTPUT);
}

void loop() {
	digitalWrite(13, HIGH); // set the LED on
	for (int x=0; x < 1000; x++) { // Wait for 1 second
		delay(1);
	}
	digitalWrite(13, LOW); // set the LED on
	for (int x=0; x < 1000; x++) { // Wait for 1 second
		delay(1);
	}
}

This new sketch will accomplish the same sequence as Example #1. The difference is that the Arduino is only “delayed” for one millisecond at a time. A clever trick would be to call other functions inside of that for() loop. However, your timing will be off because those instructions will add additional delay.

Example #3: for() loops with 2 LEDs

In this example, we’ve added a second LED on Pin 12 (with a current limiting resistor!). Now let’s see how we could write the code from Example #2 to flash the 2nd LED.

void setup() {
	pinMode(13, OUTPUT);
	pinMode(12, OUTPUT);
}

void loop() {
	digitalWrite(13, HIGH); // set the LED on
	for (int x=0; x < 1000; x++) { // wait for a secoond
		delay(1);
		if (x==500) {
			digitalWrite(12, HIGH);
		}
	}
	digitalWrite(13, LOW); // set the LED off
	for (int x=0; x < 1000; x++) { // wait for a secoond
		delay(1);
		if (x==500) {
			digitalWrite(12, LOW);
		}
	}
}

Starting with the first for() loop, while Pin 13 is high, Pin 12 will turn on after  500 times through the for() loop.  It would appear that Pin 13 and Pin 12 were flashing in Sequence.  Pin 12 would turn on 1/2 second after Pin 13 turns on.  1/2 second later Pin 13 turns off, followed by Pin 12 another 1/2 second.

This code is pretty complicated, isn’t it?

If you wanted to add other LEDs or change the sequence, you have to start getting ingenious with all of the if-statements. Just like example #2, the timing of these LEDs is going to be off. The if() statement and digitalWrite() function all take time, adding to the “delay()”.

Now let’s look at how millis() gets around this problem.

The millis() Function

Going back to the definition of the millis() function: it counts the number of milliseconds the sketch has been running.

Step back and think about that for a second. In Example #3, we are trying to flash LEDs based on a certain amount of time. Every 500ms we want one of the LEDs to do something different. So what if we write the code to see how much time as passed, instead of, waiting for time to pass?

Example #4: Blink with millis()

This code is the same “Blink” example from #1 re-written to make use of millis(). A slightly more complicated design, because you have to include a couple of more variables. One to know how long to wait, and one to know the state of LED on Pin 13 needs to be.

unsigned long interval=1000; // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.

bool ledState = false; // state variable for the LED

void setup() {
     pinMode(13, OUTPUT);
     digitalWrite(13, ledState);
}

void loop() {
	unsigned long currentMillis = millis(); // grab current time

	// check if "interval" time has passed (1000 milliseconds)
	if ((unsigned long)(currentMillis - previousMillis) >= interval) {
		ledState = !ledState; // "toggles" the state
		digitalWrite(13, ledState); // sets the LED based on ledState
		// save the "current" time
		previousMillis = millis();
	}
}

Let’s look at the code from the very beginning.

unsigned long interval=1000; // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.

millis() returns an unsigned long.

When using variables associated with millis() or micros(), ALWAYS declare them as an unsigned long

The variable interval is the amount of time we are going to wait. The variable previousMillis is used so we can see how long it has been since something happened.

bool ledState = false; // state variable for the LED

This code uses a variable for the state of the LED. Instead of directly writing a “HIGH” or “LOW” with digitalWrite(), we will write the value of this variable.

The setup() function is pretty standard, so let’s skip directly to the loop():

void loop() {
     unsigned long currentMillis = millis(); // grab current time

Each time loop() repeats, the first thing we do is grab the current value of millis(). Instead of repeated calls to millis(), we will use this time like a timestamp.

void loop() {
     if ((unsigned long)(currentMillis - previousMillis) >= interval) {

Holy cow does that look complicated! It really isn’t, so don’t be afraid to just “copy and paste” this one. First, it is an if()-statement. Second the (unsigned long)  isn’t necessary (but I’m not going to sit around for 49 days to make sure). Third “(currentMillis – previousMillis) >= interval)” is the magic.

What it boils down to, this code will only become TRUE after millis() is at least “interval” larger than the previously stored value of millis, in previousMillis. In other words, nothing in the if()-statement will execute until millis() gets 1000 milliseconds larger than previousMillis.

The reason we use this subtraction is that it will handle the roll-over of millis. You don’t need to do anything else.

ledState = !ledState;

This line of code will set the value of ledState to the corresponding value. If it is true, it becomes false. If it is false, it becomes true.

digitalWrite(13, ledState); // sets the LED based on ledState

Instead of writing a HIGH or LOW directly, we are using a state variable for the LED. You’ll understand why in the next example.

previousMillis = millis();

The last thing you do inside of the if-statement is to set previousMillis to the current time stamp. This value allows the if-statement to track when at least interval (or 1000ms) has passed.

Example #5: Adding a 2nd LED with millis()

Adding a second flashing LED is straightforward with the millis() code. Duplicate the if-statement with a second waitUntil and LEDstate variable.

// each "event" (LED) gets their own tracking variable
unsigned long previousMillisLED12=0;
unsigned long previousMillisLED13=0;

// different intervals for each LED
int intervalLED12 = 500;
int intervalLED13 = 1000;

// each LED gets a state varaible
boolean LED13state = false; // the LED will turn ON in the first iteration of loop()
boolean LED12state = false; // need to seed the light to be OFF

void setup() {
	pinMode(13, OUTPUT);
	pinMode(12, OUTPUT);
}
void loop() {
	// get current time stamp
	// only need one for both if-statements
	unsigned long currentMillis = millis();

	// time to toggle LED on Pin 12?
	if ((unsigned long)(currentMillis - previousMillisLED12) >= intervalLED12) {
		LED12state = !LED12state;
		digitalWrite(12, LED12state);
		// save current time to pin 12's previousMillis
		previousMillisLED12 = currentMillis;
	}

	// time to toggle LED on Pin 13?
	if ((unsigned long)(currentMillis - previousMillisLED13) >= intervalLED13) {
		LED13state = !LED13state;
		digitalWrite(13, LED13state);
		// save current time to pin 13's previousMillis
		previousMillisLED13 = currentMillis;
	}
}

This code has some small changes from the previous example. There are separate previousMillis and state variables for both pins 12 and 13.

To get an idea of what’s going on with this code change the interval values for each. Both LEDs will blink independently of each other.

Other Examples

Check out this list of millis() examples: https://www.baldengineer.com/millis-cookbook.html
There are examples to create a Police Light Strobe Effect, Time your Code, Change the ON-time and OFF-time for an LED, and others.

Conclusion

At first it seems that using the millis() function will make a sketch more complicated than using delay(). In some ways, this is true. However, the trade-off is that the sketch becomes significantly more flexible. Animations become much simpler. Talking to LCDs while reading buttons becomes no problem. Virtually, you can make your Arduino multitask.

After working through these exercises, check out this article on how to avoid rollover or reset mills().
Author

Fan of making things beep, blink and fly. Created AddOhms. Stream on Twitch. Video Host on element14 Presents and writing for Hackster.IO. Call sign KN6FGY.

122 Comments

  1. ricardo ruiz Reply

    Hello
    How do I use for, random and millis
    I need to make a dice with 7 LEDs based on a random number that when pressing a button “ROTATE” for a while before staying in a value and when giving the value, it flashes for 4 seconds. Thank you

  2. Hello!
    How many times can “millis” be used in a “sketch”?
    For example, for 10 LEDs, each with its own time.
    unsigned long previousMillisLED3=0;
    int intervalLED12 = 1000;

    unsigned long previousMillisLED4=0;
    int intervalLED12 = 300;

    unsigned long previousMillisLED11=0;
    int intervalLED12 = 500;

    unsigned long previousMillisLED12=0;
    int intervalLED12 = 100;

  3. Hello,

    sorry i have a mistake in the previous comment, this is my question

    i have a code and this function below to turn up the led on for 3 sec,it’s like the function i used in my program,
    is it true???

    [code]
    void turnLedOnFor3Sec()
    {
    int intervalTimer=3000;
    unsigned long currentMillis=millis();
    unsigned longpreviousMillis = currentMillis;
    while ((unsigned long)(currentMillis- previousMillis) >= intervalTimer)
    {
    currentMillis=millis();
    digitalRead(led,HIGH);
    }
    }
    [/code]
    Thank you

  4. Hello,
    hank you for your assistance, i have a question usin the millis() function i while loop. I’m working with Arduino Mega

    i have a code and this function below like this function used in my program,
    is it ture???

    [code]

    void turnLedOnFor3Sec()
    int intervalTimer=3000;
    unsigned long currentMillis=millis();
    while ((unsigned long)(millis() – previousMillis) >= intervalTimer)
    {
    previousMillis = currentMillis;
    digitalRead(led,HIGH);
    }

    [/code]

    Thank you

    • John Shute Reply

      Hello Ihab. I think I can help you with this. I’m not a professional but I know how to do this. please email me at [email protected]. Also, I’m guessing English is not your first language. If so, tell me what is your main language and I can get help with translations

  5. marty shen Reply

    I have a problem operating HC-05 Buetooth module : marked Zs-040, 6 pin module with a tiny push button .
    QUESTION: To what pin on Arduno UNO do I connect the Hc-05 RXD , ater using a attenuator to reduce he signal to 3.3v/0v from 5v/0v ?

    “desperate” for an answer !
    marty

    • If you use the Arduino’s hardware serial port, it is pins 0 and 1, where you cross TX and RX. However, that is going to make communicating over USB to the PC difficult. Most people use SoftwareSerial to communicate with a Bluetooth module. (Or an Arduino with multiple hardware serial ports.)

  6. John Shute Reply

    Just Thanks Mostly. You make this so easy to understand.

    Could you sometime post a tutorial using “fadeAmount” and millis()

    • John Shute Reply

      Oops. I found a tutorial that shows it right here on this site. Thanks again.

  7. BE, Is it also possible to use millis to set a timer (it is a timer…) to generate regular interrupt that forces the program to jump to the ISR, which of course is another function? Seems to me it would be easier than keeping track of alt these variables (in trying to run 2 or more programs without_using DELAY). I’ve used interrupts a lot in Motorola assembler (6800,6802, 6809, 68000, 68HC11), but never with Arduino, c++, or Basic.

  8. Systembolaget Reply

    Cheers, well explained! In line 34 of your last long code block, your comment should read “13’s” instead of “12’s”. Might confuse some novices ; )

  9. Robert Sherwood Reply

    Hello
    Thank you for your assistance the line by line explanation of the code is very helpful to this novice.
    I took your example number 5 and modified to my circuit to control 3 different motors using an Arduino UNO and Riorand 6v to 90v 15 amp DC motor speed controller {(being used as a motor controller. sending 5 volts to the 0-5 pin on controller to turn motor on at max RPM.
    Im trying to control the on and off time of the motors individually using analogRead and separate potentiometers. 1 pot for on time and 1 for off time for each controller. Can the analogRead be worked in to the state machine?
    Again thanks for your assistance

    • Can the analogRead be worked in to the state machine?

      You can use a range with a switch() statement, but it takes a special syntax.

      [arduino firstline=””]
      switch (analogRead(0)) {
      // normal switch statement (a character in this case)
      case 0:
      Serial.println("Zero");
      break;

      // CORRECT example of a range
      case 1 … 512:
      Serial.println("OFF");
      digitalWrite(13, LOW);
      break;

      // INCORRECT example of a range
      case 513…1023:
      Serial.println("ON");
      digitalWrite(13, HIGH);
      break;
      }
      [/arduino]

      The range uses three periods with a space before and after. ” … ” and not “…”.

      If you get a “too many decimal points in number” error, it is because you need to add a space before and after the periods.

  10. Hi thanks for your post, this info is going to be very helpful in my project, but i have a doubt, I want to do a project that reads in several sensors and then i want to write the info in a LCD, so my doubt is if the function millis() can work in this project because i want that work without stop for a very long time and I don’t know if there are a way in order to restart the millis()

    • There is never a reason to restart millis(). It automatically rolls over every 49 days. If you use the subtraction method used here, that roll over will never matter to you.

  11. please explain example#4 like initial values of currentMillis , previousMillis and theirs interval comparison.

    please correct me if i am wrong :

    at start of loop :

    unsigned long currentMillis = millis();

    lets assume ” currentMillis” = 200 ms

    then

    if ((unsigned long)(currentMillis – previousMillis) >= interval)

    so in above instruction we will have ( 200 ms – 0 >= interval )

    so if statement is not true and previousMillis will not saved any value.

    again loop begin and this time currentMillis will be lets say 500ms but not if statement will be true till the currentMillis becomes 1000 ms or more .

    as currentMillis will be 1000 ms the LED state will change and previousMillis will saved value lets say 1050 ms …

    and loop will be continue…

    • yes that is how it works. previousMillis will not be updated until the difference between “currentMillis” and “previousMillis” is at least “interval” apart.

  12. Two questions,

    1.) You showed a for loop with delay, is there a for loop without delay way? When I have tried to add millis() inside the for loop i get erratic results because it doesn’t wait for the interval before it increments.

    2.) Using millis() for multiple button inputs simultaneously. Holding one button to run a function and still be able to press another button (or two) to run a separate function. When I do this now, If I hold the one button and press another they both go up, but the state does not change when i released the pressed button. Using this for neopixel animations.

  13. James Riopelle Reply

    A few times I tried running this code without the 2nd (unsigned long) in the loop and it won’t compile. I suppose this means that even though both expressions in the parentheses are unsigned longs that Arduino needs to be told that the difference is also an unsigned long. Thank you very much for posting this educational webpage–very helpful to me. James Riopelle New Orleans

  14. I am a beginner at ardino_UNO .
    I struggled to understand the millis() function, your article made me aware of the technique.
    Question:
    (1)How does ATmega328 , using the millis() function, keep track of multiple counts involved in multiple Leds ?
    Each Lead having different ON/OFF time intervals
    (2)How many Leds could te ATmega328 handle at a time?
    would 5 Leds compared 10 to Leds show the variations counter timing due to ATmega328 storing/retrieving data/resetting i

    • (1)How does ATmega328 , using the millis() function, keep track of multiple counts involved in multiple Leds

      Create variables to track each led. Each LED would get its own previousMillis and interval variable.

      (2)How many Leds could te ATmega328 handle at a time? … due to ATmega328 storing/retrieving data/resetting

      5 or 10 won’t make any difference at all. It would take thousands. But you would run out of RAM or have to use shift registers which would slow it down. But not the processor itself.

  15. I’m an arduino beginner from Thailand and it’s very useful for me, thanks a lot.
    My first task is use photo gate (laser with LDR) to observe a motion of a metal ball rolling down the inclined plane. I use millis() function to count time interval that the metal ball pass photo gate (no light detect on LDR) in order to get an instantaneous velocity at that point, but may problem is that any distance on an inclined plane return nearly the same amount of time (50-52 ms).
    My question is : should I use micros() instead? or Is this problem caused from low sensitivity of LDR? Any idea?
    Thanks

    • My question is : should I use micros() instead? or Is this problem caused from low sensitivity of LDR? Any idea?

      Are you saying that when you check the values of millis() it is nearly the same? or that detection time lasted for 50 ms?

      If the “start” and “stop” time are nearly the same, then you probably need to use micros().

  16. Hi James. Great tutorial. I have a motion sensor and I am looking at the accelerometer values through serial communication of arduino with Matlab. I want to check how many milliseconds have passed from the start of the sketch to the end of 1000 values of accelerometer. But soemhow it messes with the values of accel when I incorporate the millis() funciton. Please guide. Any help will be immensely appreciated!

  17. Hi James, thank you for the tutorial. I’m trying to write a code to know which one of two sensors senses a value first. Can I use mills for this? If not, what can I use? Thank you

  18. the millis() doesn’t return any value for me. I copied & pasted the example #4 uploaded it to the arduino uno r3 . This is all I ever get in the serial monitor “Time: 0
    ” any clue ?

    • Not sure what to tell you. Example #4 has no Serial prints, so I don’t know why you’d expect to see anything. If you added code, I can’t help debug code I can’t see.

      • I probably damaged one of the libraries. I removed Arduino 1.8.5-windows and reinstalled. Any clue what library millis() uses? Any way thanks for the reply and excellent examples. I am struggling with my first(-ish) attempt at micro-controller programming. timers and timed events are kicking my but 😉

        • [arduino]
          unsigned long interval=1000; // the time we need to wait
          unsigned long previousMillis=0; // millis() returns an unsigned long.

          bool ledState = false; // state variable for the LED

          void setup() {
          pinMode(13, OUTPUT);
          digitalWrite(13, ledState);
          Serial.begin(9600);
          }

          void loop() {
          unsigned long currentMillis = millis(); // grab current time
          Serial.print("Time: ");
          Serial.println(currentMillis);
          Serial.print("previousTime: ");
          Serial.println(previousMillis);

          // check if "interval" time has passed (1000 milliseconds)
          if ((unsigned long)(currentMillis – previousMillis) >= interval) {

          ledState = !ledState; // "toggles" the state
          digitalWrite(13, ledState); // sets the LED based on ledState
          // save the "current" time
          previousMillis = millis();
          }
          }
          [/arduino]

        • Any clue what library millis() uses?

          It’s part of the core Arduino library. It is in wiring.c. That’s as core as Arduino’s library gets. There’s no reason for it to return 0. What board are you using?

  19. Hi,
    My project is little bit difficult. I am passing time value for which my led should on via serial communication. i have int value in my arduino. how to loop for that time of millisecond and than stop my program. can i convert int into long for delay operation or not?
    help me.

  20. Thanks for the UL tip, I spent hours trying to figure out why I couldn’t pass 32 * 1000 in my Millis timer code.
    Now with 33 * 1000UL, everything working great.
    Very Much appreciated!

  21. First I would like to thank you for posting this website it has been a great help as I am a 70 year old Neophyte to Adruino & Coding. I would like to know if there is a way to incorporate two of your sketches. I would like to combine your Fading analogWrite mills with example #5: “Adding a 2nd LED with millis()” as I would like to have one LED Fading at one rate as the other two LEDs Blink at their own rates. I have tried combining the different areas together ie.. unsigned long, Int,, Void Setup & Void Loops. If you would, could you point me in the right direction as to what I’m doing wrong. Thank you again for your website and for (hopefully) helping this old dog learn a new trick 😀

    • Hello, Just a quick line to again thank you for your website. I was able to play with the two sketches (noted above) and was able to get the effect I was looking for. My apologize for having taken of your time with this question

  22. Hey, sir tutorial is fantastic
    Is their any problem if i remove “>” sign from the expression “(currentMills – perviousMills) >=interval

    • James Lewis Reply

      Yes. If the time between checks is larger than interval then the expression will be false. The likelihood of checking when the difference between times is EXACTLY the interval value is very low.

  23. hi, nice tutorial there,

    a question:

    supposedly i have this two function, one is way faster one is slower, will reading the (unsigned long)(currentMillis – previousMillisLED12-intervalLED12) signify how late that execution is late?

  24. Thank you for the guide. How do i use millis for longer periods, for example 60 minutes? My example is sending data to thingspeak every hour?

    • The biggest mistake people make is something like this:
      [arduino firstline=”1″]
      unsigned long interval = 1000 * 60 * 60; // 1000 ms times 60 seconds times 60 minutes = 1 hour
      [/arduino]
      This method is a problem because the compiler does all the math before storing it into the variable. The values “1000” and “60” are both small enough to fit into an integer, so it treats the entire math problem as an integer. The 1000 times 60 might be okay, but when multiplied again the integer will overflow. So you have to cast to a larger variable like this:
      [arduino firstline=”1″]
      unsigned long interval = 1000UL * 60UL * 60UL;
      [/arduino]
      The “UL” tells the compiler to treat the integers as unsigned long integers, so the math will be treated as an unsigned long the entire time. (Really you only need to cast one of the constants, but I added it all for this example.)
      [arduino firstline=”1″]
      unsigned long interval = 3600000;
      [/arduino]
      Just using the amount of milliseconds as a constant would work too. Personally, I find that hard to read sometimes.

  25. Hi,

    Thanks for your detailed tutorial.
    I want to sound a buzzer for 10sec when the state of a input pin changes. I have written following code using millis() function. There are no compilation errors. But when I am changing the pin state buzzer is not giving any sound. Can you please have a look at the code and what is wrong?

    CODE:

    int b;
    const int a = 8;
    int c;
    unsigned long previousMillis = 0;
    const long interval = 1000;
    void setup() {
    // put your setup code here, to run once:
    pinMode(a, INPUT);
    pinMode(13, OUTPUT);
    Serial.begin(9600);

    }

    void loop() {

    unsigned long currentMillis = millis();

    Serial.println(“previousMillis”);
    Serial.println(previousMillis);
    Serial.println(“currentMillis”);
    Serial.println(currentMillis);
    if(currentMillis – previousMillis >= interval) {
    b = digitalRead(a);
    Serial.println(“b”);
    Serial.println(b);
    previousMillis = currentMillis;
    c = digitalRead(a);
    if(b != c) {
    digitalWrite(13, HIGH);
    delay(10000);
    }
    else {
    digitalWrite(13, LOW);
    }
    Serial.println(“c”);
    Serial.println(c);
    }
    delay(1000);
    }

    Thanking you,
    Yoga

    • Make sure the buzzer is the type that “self excites.” Which means a DC signal will make a sound. Otherwise, you need to do something like a PWM waveform. The delay()s in your code makes using millis() totally pointless.

      • luis0000luis Reply

        Hi James!
        This is to just to give something back, since your page helped me. The following code works and I post it as an example for your readers, I did it as a prop, to help my daughter in a school presentation.

        The code lights up a series of 8 LEDs connected (via BUFFERED outputs) to digital pins 2 through 9 of my Arduino Nano. Once all the 8 LEDs are lit up, a further button press will switch off all the LEDs and start again.

        The 8 LEDs light up in sequence and each time a button (connected to digital input 13) is pressed — I actually us an RF relay switch, but it may as well be a button — and extra LED lights up.

        A long button press will switch off the all the LEDs and start the sequence again (in case my daughter is halfway through, makes a mistake and needs to start again). This is where I need the millis function.

        Note: I put in delays of 50ms here and there to avoid some transient noise from being interpreted as multiple presses.

        CODE:

        const int ButtonPin = 13;
        const unsigned long longPressInterval=1000;

        int i;
        unsigned int ActiveLEDs=0;
        int buttonState = LOW;
        int previousState = LOW;
        unsigned long previousMillis;

        void setup() {
        // Initialize the output pins. One per LED:
        for (i=2; i= 8) {
        //All the LEDs are on, so we can’t light up any more. Instead we switch them all off.
        for (i=2; i longPressInterval) {
        // Long Press detected. Reset the LEDs.
        for (i=2; i<10; i++) digitalWrite(i, LOW);
        ActiveLEDs=0;
        // Let's wait until the button is released before going any further.
        while ((buttonState=digitalRead(ButtonPin)) == HIGH) delay(50);
        }

        previousState=buttonState;
        delay(50);
        }

        • luis0000luis Reply

          Something gobbled up part of the code, above.
          Here it is again.
          const int ButtonPin = 13;
          const unsigned long longPressInterval=1000;

          int i;
          unsigned int ActiveLEDs=0;
          int buttonState = LOW;
          int previousState = LOW;
          unsigned long previousMillis;

          void setup() {
          // Initialize the output pins. One per LED:
          for (i=2; i= 8) {
          //All the LEDs are on, so we can’t light up any more. Instead we switch them all off.
          for (i=2; i longPressInterval) {
          // Long Press detected. Reset the LEDs.
          for (i=2; i<10; i++) digitalWrite(i, LOW);
          ActiveLEDs=0;
          // Let's wait until the button is released before going any further.
          while ((buttonState=digitalRead(ButtonPin)) == HIGH) delay(50);
          }

          previousState=buttonState;
          delay(50);
          }

  26. finallyfreedsiteNaeem Reply

    Hi,

    Will you be able to post an example of how I would use the millis function with an IR remote. What I am trying to do is make an LED blink when a remote button is pressed and also stop when the same button is pressed.

    • There’s nothing special about an IR remote program. Set a flag variable to true when the button is pressed and false when it is let go. Only blink while the flag variable is true.

      • I am unable to use the MillisTimer library with IRremote. When I combine the two, the MillisTimer apparently locks (the LCD indicates the timer quits advancing). If I rem out the receiver.enableIRIn() line, the timer advances as advertised. What might the conflict be and is there a resolution?

        I am using pin 7 for the receiver pin for the IR sensor and pins 2-5 and 11-12 for the LCD display if that makes any difference.

        I have been a VBA developer for nearly 20 years so my general programming acumen is not particularly lacking, but I’m a newb in the Arduino/C/C++ world.

        • I have never used the MillisTimer library. Or the IR library really. So I don’t know how they might be conflicting. The IR library may be modifying the hardware timers directly, which may cause the other one issues. I have no idea.

          None of the “millis libraries” really solved a problem for me. I found just doing my own if-millis check is sufficient and straightforward.

  27. Setiawan Putra Hendratno Reply

    Hello. Thank you for the helpful articles. Would you mind if you give me the reference of millis() project.

  28. Darshan Amoateng Reply

    i am working with a Spo2 probe sensor and I am supposed to alternate the switching on of two LEDs(red and ir).How should i go about it using the millis() function?

  29. Mburu David Reply

    Hi James. thanx for very informative posts. I have 2 questions.I have an array of 12 Leds and would like to sequence them from the centre outwards, to the right and to the left at the same time. the second problem is how do you sequence like 3leds together at the same time in a row. …………
    Thanks in advance

  30. Hey James!

    I am trying to use a potentiometer to turn on an LED on, 5 seconds after reaching high travel(1000). However the program counts down from 5 seconds from reset/upload and then turns the LED on instead of waiting for the pot to reach 1000 and then count down from 5 and then turn the LED on.

    Heres part of the code(Void setup is fine):
    ***********************************************************************************************************************************

    const byte BluePin = 3;
    const byte GreenPin = 4;
    const byte LevelPin = A0; //potentiometer pin
    int waterLevel;

    unsigned long savedStartTime=0;
    unsigned long timeToPass=5000;
    unsigned long start;

    void loop() {
    waterLevel = analogRead(LevelPin); //Read the voltage from the Potentiometer pin

    if (waterLevel >= 1000) {
    start = millis();
    savedStartTime=start;
    digitalWrite(BluePin, HIGH);

    if((millis() – savedStartTime) >= timeToPass ){

    digitalWrite(GreenPin, HIGH);
    }
    **************************************************************************************************************************************
    When the pot is at 1000 the first LED(BluePin) comes on but the countdown doesn’t start there and then. GreenPin which I want to come on 5 seconds after reaching 1000 with the pot starts 5 seconds from reset/upload to arduino regardless Am I missing some code?.

    If your interested in providing a little advice this question is also here:

    https://forum.arduino.cc/index.php?topic=451429.0

    • James Lewis Reply

      You are constantly “resetting” start. Each iteration of loop, the “if waterLevel” is checked and found to be true. So start never really changes much. I would add a flag variable that i set false in that if statement. Then i would do “if waterLevel > 1000 and flag==true” so you only “set” start once.

      The millis() if should be outside of that check, on its own.

  31. N.N. JOGLEKAR Reply

    [arduino]
    const int outputpin = 4;
    int pin4State = HIGH;
    unsigned long previousMillis = 0;
    unsigned long interval = 10000;
    void setup() {
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(13, OUTPUT);
    pinMode(4, OUTPUT);

    }

    void loop() {
    if (digitalRead(2) == LOW) {
    digitalWrite(13, HIGH);
    }
    else {
    digitalWrite(13, LOW);
    }
    digitalWrite(4, HIGH);
    unsigned long currentMillis = millis();
    if ((pin4State == HIGH) && (digitalRead(3) == HIGH) && (unsigned long)(currentMillis – previousMillis >= 10000)) {
    pin4State = LOW;
    digitalWrite(4, LOW);
    }
    else {
    digitalWrite(4, HIGH);
    }

    }
    [/arduino]
    Sir in above code I am controlling output pin 13 on input pin 2. I want to start time when pin 13 & pin 4 goes high. If time interval is greater than 10 sec & if pin 3 remains high then I am expecting pin 4 should go low. With above code I am not getting expected result. What is reason. What mistake I am making. I am using arduino uno .
    Regards,
    N.N.Joglekar
    Nasik , Maharashtra State, India.

    • You never “reset” previousMillis, so this code will only work once. It should be updated inside of the if-statement. This code will turn the LED back on on the next cycle of loop when the if-statement is false. So you won’t actually see the LED on pin 4 ever turn off.

      You need a better state machine, with more states. You might also want to look at this delayed event millis example.

  32. Gone through it, few understand , few not. actually i want to learn how to make function and call it when ever required.
    Background- I connect 20 nos. LED with Arduino UNO and able to address it individually. also able to write different pattern, but to repeat the pattern I need to write the same program lines again. I know this is immature programing,
    Now I want to write this patterns as different functions so that I call them as required
    let say I write 5 typed of pattern for LED, now I call them -lets say 1st pattern 2 times 2nd pattern 4 times 3 pattern 3 times etc and when last pattern executed again first pattern will start and cycle will be repeated.
    Now please help me how I write LED patterns as functions and how to call them for n time repetition and finally complete cycle will be repeated again and again.

  33. Nikos Kiriakopoulos Reply

    Hello ,
    my name is Niko and i am from Greece.
    I am after millis implementation using fastled patterns and i have to admitt it is pain…..
    inserting inside a for loop….
    below is a demo for loop which cannot work with millis,
    what it does is waiting for the interval time i set and then passes all leds at very fast speed.
    the purpose i want is to use BLYNK platform which does not like delays…..
    any help will be much apreciated……

    [arduino]
    #include "FastLED.h"
    #define NUM_LEDS 54
    #define DATA_PIN 6
    CRGB leds[NUM_LEDS];

    unsigned long interval = 100;
    unsigned long previousMillis = 0;

    void setup() {
    LEDS.addLeds(leds, NUM_LEDS);
    LEDS.setBrightness(255);
    }

    void fadeall() {
    for (int i = 0; i = interval) {
    previousMillis = millis();

    for (int i = 0; i &lt; NUM_LEDS; i++) {
    leds[i] = CHSV(hue++, 255, 255);
    FastLED.show();
    fadeall();
    }
    }
    }
    [/arduino]
    Thanks in advance

    • Nikos Kiriakopoulos Reply

      this is the right code

      [arduino]
      #include "FastLED.h"
      #define NUM_LEDS 54
      #define DATA_PIN 6
      CRGB leds[NUM_LEDS];

      unsigned long interval = 100;
      unsigned long previousMillis = 0;

      void setup() {
      LEDS.addLeds(leds, NUM_LEDS);
      LEDS.setBrightness(255);
      }

      void fadeall() {
      for (int i = 0; i = interval) {
      previousMillis = millis();
      for (int i = 0; i &lt; NUM_LEDS; i++) {
      leds[i] = CHSV(hue++, 255, 255);
      FastLED.show();
      fadeall();
      }
      }
      }
      [/arduino]

    • Nikos Kiriakopoulos Reply

      i dont know how to paste my code correctly…..
      i send you an email…
      sorry for this..

      • Nikos Kiriakopoulos Reply

        [arduino]
        void loop() {
        static uint8_t hue = 0;
        if ((unsigned long)(millis() – previousMillis) &gt;= interval) {
        previousMillis = millis();
        for (int i = 0; i &lt; NUM_LEDS; i++) {
        leds[i] = CHSV(hue++, 255, 255);
        FastLED.show();
        fadeall();
        }
        }
        }
        [/arduino]

        this is the loop..i hope it pastes ok…..

        • Δημήτρης Καλογερόπουλος Reply

          Hello Nikos Ι am Dimitris Kalogeropoulos from Kalamata! Please patrioti why this kommati of the code is not working:
          [arduino firstline=””]
          currentMillis=millis();
          if (millis()-currentMillis>=duration)
          {hronos= millis()-currentMillis;

          Serial.print (" hronos ");
          Serial.print (hronos);
          myservo.write(10);
          delay(100);
          myservo.write(90);
          delay(100);
          [/arduino]

          It doesn’t mpainei sto if!!!
          Thanks in advance!!

  34. Hi James!
    When you are starting with millis magic, each time you repeate: “if ((UNSIGNED LONG)(currentMillis – previousMillisLED13) >= intervalLED13)”
    currentMillis is already set as UNSIGNED LONG, so why you repeat it all the time? Is it necessery?

    Why not to write just like this: “if ((currentMillis – previousMillisLED13) >= intervalLED13)” ?

    I wrote quite long but very simple code (as I am total begginer) and I am using 8 timers which work with millis() using this method and I am still afraid about rollover. I have read your tutorial about this problem but I do not get it for 100% :/
    Any chance you can take a look for this code and say if rollover will not mess upt the timers?

    Thanks, Michal

    • When you are starting with millis magic, each time you repeate: “if ((UNSIGNED LONG)(currentMillis – previousMillisLED13) >= intervalLED13)”
      currentMillis is already set as UNSIGNED LONG, so why you repeat it all the time? Is it necessery?

      I have had conflicting research that says it is necessary. So I leave it in, just in case.

  35. This was an absolute great article . Thanks to you, i could build my multi-tasking project , and stop using the delay() function . Thank you for this shared knowledge !!

  36. Hi great tutorial, I have situation where I have set of Neopixels light a different colour when something happens (IFTTT trigger it calls a colorwipe function). I want them to stay this colour for say 60-90 seconds. Delay will work but not ideal,where would I use millis() for this situation. It can’t be used in the loop as the strip stay the same colour and only change for certain events. Thanks

  37. James, I cannot get ex 5 to run! It compiles and uploads, but nothing is happening on my Uno. I tried through Codebender’s interface and the Arduino IDE (1.0.6). What gives? The board is working fine.

  38. Hi,

    First of all, thanks for the tutorial, I’m sure many people finds it helpful!
    I might miss the magic, but I think #5 example is wrong, it won’t survive the millis() rollover.
    I have to admit, I didn’t wait for ~50 days to be sure, but if you’re using this
    if(millis()>=waitUntil)
    style, it will fire every time after waitUntil wraps around, and waitUntil will climb extremely fast (by flashDelay each time). After that either waitUntil wraps around again, or millis() does, and it won’t activate again (freeze) until it reaches waitUntil’s highly inflated value, which might be a few days or weeks.
    If you agree with me, please correct that example, as it’s a millis() tutorial after all. If I’m wrong, please explain why.

    • Weird. It’s suppose to be code more similar to #4, something caused it to roll back to an early draft. Will fix it later.

  39. Hi James i have been having some issues with delay() function. Your tutorial was very useful thanks. Am working on a traffic light with sensor . The sensing part is where am got stuck. I have this code that i want to rewrite without using delay() function
    Basically, i wanted a delay before the LDR (photocell) sensor sense a car. if the delay is 10sec , and a car did not spend up to 10sec nothing should happen but if = 10sec turn pin 5 HIGH. your help will be highly appreciated .
    1 to write the code without using delay () function
    or
    2 10secs timer without using delay () function
    thanks here is my code
    [arduino language=””]
    int sensorPin = A0; // select the input pin for the ldr
    unsigned int sensorValue = 0; // variable to store the value coming from the ldr
    int LDRLED = 5; // select the input pin for the ldr

    void setup()
    {
    pinMode(LDRLED, OUTPUT);
    //Start Serial port
    Serial.begin(9600); // start serial for output – for testing
    }

    void loop()
    {
    // read the value from the ldr:
    sensorValue = analogRead(sensorPin);
    if(sensorValue<300)
    {
    delay (3000);
    sensorValue = analogRead(sensorPin);
    if(sensorValue<300)
    digitalWrite(LDRLED, HIGH);

    }
    else
    {
    digitalWrite(LDRLED, LOW); // set the LED off

    }
    //For DEBUGGING – Print out our data, uncomment the lines below
    Serial.print(sensorValue, DEC); // print the value (0 to 1024)
    Serial.println(""); // print carriage return
    delay(500);
    }[/arduino]

    thanks .

  40. cant you help me how to me after 20 sec forward and reverse motor will stop automaticly

    [arduino collapse=”true”]
    unsigned long interval = 100; // the time we need to wait
    unsigned long previousMillis = 120;
    int E1 = 5;
    int M1 = 4;
    int Led1 = 9;
    int Led2 = 10;
    int Led3 = 11;
    int x;
    int i;

    String readString;
    #include
    //#include
    //LiquidCrystal_I2C lcd(0x20,16,2);

    char command = ”;
    int pwm_speed; //from 0 – 255

    void setup() {
    pinMode(Led1, OUTPUT);
    pinMode(Led2, OUTPUT);
    pinMode(Led3, OUTPUT);
    pinMode(M1, OUTPUT);
    Serial.begin(9600);

    // lcd.init(); // initialize the lcd
    // lcd.backlight();
    // lcd.home();
    }

    void loop()
    {
    forward();
    reverse();
    Stop();
    }

    void forward() {

    char *help_menu = “\’e\’ go forward\n\’d\’ stop\n\’s\’ left\n\’f\’ right\n\’c\’ go backward\n”;

    if (Serial.available() > 0)
    {
    command = Serial.read();
    }

    switch (command)
    {
    case ‘e’: //go forward
    Serial.println(“Go!!\r\n”);
    digitalWrite(M1, LOW);
    if ((unsigned long)(millis() – previousMillis) >= interval) {
    previousMillis = millis();
    }
    digitalWrite(Led1, HIGH);
    digitalWrite(Led2, LOW);
    digitalWrite(Led3, LOW);
    // lcd.setCursor(0, 0);
    // lcd.print(“forward”);
    analogWrite(E1, 255); //PWM speed control
    command = ”; //reset command
    break;

    }
    }

    void reverse() {
    char *help_menu = “\’e\’ go forward\n\’d\’ stop\n\’s\’ left\n\’f\’ right\n\’c\’ go backward\n”;

    if (Serial.available() > 0)
    {
    command = Serial.read();
    }

    switch (command)
    {
    case ‘c’: //backward
    Serial.println(“Back!!\r\n”);
    digitalWrite(M1, HIGH);
    digitalWrite(Led1, LOW);
    digitalWrite(Led2, HIGH);
    digitalWrite(Led3, LOW);
    // lcd.setCursor(0, 0);
    // lcd.print(“backward”);
    analogWrite(E1, 255); //PWM speed control
    command = ”; //reset command
    break;
    }
    }

    void Stop() {
    char *help_menu = “\’e\’ go forward\n\’d\’ stop\n\’s\’ left\n\’f\’ right\n\’c\’ go backward\n”;

    if (Serial.available() > 0)
    {
    command = Serial.read();
    }

    switch (command)
    {
    case ‘d’: //stop
    Serial.println(“Stop!\r\n”);
    analogWrite(E1, 0); //PWM speed control
    digitalWrite(Led1, LOW);
    digitalWrite(Led2, LOW);
    digitalWrite(Led3, HIGH);
    // lcd.setCursor(0, 0);
    // lcd.print(“stop “);
    command = ”; //reset command
    break;
    }
    }
    [/arduino]

    • Untested, but I’d do something like this. Basically, save the current time in previousMillis(). In loop, constantly check if you ever had a 20 second wait since the previous command. If so, issue stop, anyway.

      Also, I tried to clean up your code. You should only need to check for a serial command once, then run the function related to that command.

      [arduino collapse=”true”]
      unsigned long interval = 20000UL; // 20,000 ms = 20s
      unsigned long previousMillis = 0;
      int E1 = 5;
      int M1 = 4;
      int Led1 = 9;
      int Led2 = 10;
      int Led3 = 11;
      int x;
      int i;

      String readString;
      //#include
      //LiquidCrystal_I2C lcd(0x20,16,2);

      char command = ‘\0’;
      int pwm_speed; //from 0 – 255

      void setup() {
      pinMode(Led1, OUTPUT);
      pinMode(Led2, OUTPUT);
      pinMode(Led3, OUTPUT);
      pinMode(M1, OUTPUT);
      Serial.begin(9600);

      // lcd.init(); // initialize the lcd
      // lcd.backlight();
      // lcd.home();
      }

      void loop()
      {
      char *help_menu = "\’e\’ go forward\n\’d\’ stop\n\’s\’ left\n\’f\’ right\n\’c\’ go backward\n";

      if (Serial.available() > 0)
      {
      command = Serial.read();

      switch (command)
      {
      case ‘e’: //go forward
      forward();
      break;

      case ‘c’:
      reverse();
      break;

      case ‘d’:
      Stop();
      break;
      }
      command = ‘\0’; //reset command
      }
      if ((unsigned long)(millis() – previousMillis) >= interval) {
      Stop();
      }
      }

      void forward() {
      Serial.println("Go!!\r\n");
      digitalWrite(M1, LOW);
      digitalWrite(Led1, HIGH);
      digitalWrite(Led2, LOW);
      digitalWrite(Led3, LOW);
      // lcd.setCursor(0, 0);
      // lcd.print("forward");
      analogWrite(E1, 255); //PWM speed control
      previousMillis = millis();
      }

      void reverse() {
      Serial.println("Back!!\r\n");
      digitalWrite(M1, HIGH);
      digitalWrite(Led1, LOW);
      digitalWrite(Led2, HIGH);
      digitalWrite(Led3, LOW);
      // lcd.setCursor(0, 0);
      // lcd.print("backward");
      analogWrite(E1, 255); //PWM speed control
      previousMillis = millis();
      }

      void Stop() {
      analogWrite(E1, 0); //PWM speed control
      digitalWrite(Led1, LOW);
      digitalWrite(Led2, LOW);
      digitalWrite(Led3, HIGH);
      Serial.println("Stop!\r\n"); // usually you want to stop immediately
      // lcd.setCursor(0, 0);
      // lcd.print("stop ");
      }
      [/arduino]

  41. Hello James.

    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 .

    • I do not see why you would need millis().

      AND statements need to be full statements:

      if ((d > 10) && (d < 20)) {

  42. Hello dear Sir,

    First of all compliments for the tutorial.

    But i am still wondering of with some quiestions, I am working on a simple RGB light. And for now i just want the primair colors to go on one after another.

    With your code for 2 led lights i did manage to get it to work. But now i am trying to add the 3th led, and now i get stuck. Somehow my code doesnt work.

    i am totally new in programming, and i was always using the delay function, i really want to get that away from my programming.

    [arduino]
    long sequenceDelay2 = 2000;
    long sequenceDelay = 1000;
    long flashDelay = 1000;
    long flashDelay2 = 2000;

    boolean LED13state = false; // the LED will turn ON in the first iteration of loop()
    boolean LED12state = false; // need to seed the light to be OFF
    boolean LED11state = false;

    long waitUntil13 = 0;
    long waitUntil12 = sequenceDelay; // the seed will determine time between LEDs
    long waitUntil11 = sequenceDelay + sequenceDelay2; // the seed will determine time between LEDs

    void setup() {
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(11, OUTPUT);
    }
    void loop() {
    digitalWrite(13, LED13state); // each iteration of loop() will set the IO pins,
    digitalWrite(12, LED12state);
    digitalWrite(11, LED11state);
    // checking to see if enough time has elapsed
    if (millis() >= waitUntil13) {
    LED13state = !(LED13state);
    waitUntil13 += flashDelay;
    // this if-statement will not execute for another 1000 milliseconds
    }
    // keep in mind, waitUntil12 was already seeded with a value of 500
    if (millis() >= waitUntil12) {
    LED12state = !(LED12state);
    waitUntil12 += flashDelay;
    }
    //keep in mind, waitUntil12 was already seeded with a value of 500
    if (millis() >= waitUntil11) {
    LED11state = !(LED11state);
    waitUntil11 += flashDelay2;
    }
    }
    [/arduino]

    • I’m uncertain what you mean “doesn’t work”. The code works exactly as written.

      Pin 13 will flash on and off once per second
      Pin 12 will flash on and off once per second, starting 1 second after Pin 13
      pin 11 will flash on and off once every 2 seconds, starting 3 second after Pin 13

      You probably need to add independent on and off times. For example, if your first LED is on for 1 second you need to keep it off for the next 2 seconds. That will give time for the 2nd LED to turn on for 1 second and then led 3 to turn on for 1 second.

      So the code works fine. Your logic doesn’t is wrong.

  43. Please help with the code according to the logic you’ve shown in ???

    Microcontrollers atmega 328p

    Are 3 switch( No) and 1 close (Nc)
    Are 3 outputs for Rele and 1 Led alarm

    1- switch 1- A0. On …… D5 for 5 minute …..D5 off……D6 on…..for 5minute …….D6 off…….D7 on……5minute .Resetting

    2- switch 1- A0 and 2A1 .is on. …..D5 and D6 on for 5minute..
    D5 off. D6 and D7 on for 5minute .. D6 off. D7 and D5 n for 5minute.Resetting

    3- switch. 1,2,3__ A0,A1,A2. On D5,D6,D7.On No limit.

    4_ switch 4 open_ A3 OFF . Off D5,D6,D7. And on D8 led alarm

    5_ Switch 4 closed A3 on returning home

    • I’m sorry but I am not sure I understand your question. You should post on the Official Arduino Forums, in your native language.

  44. Pingback: Project 2: Robot Arm | UWE Product Design Physical Computing

  45. Hi James,
    Let me start by saying your tutorial was excellent!! I have been studying many methods of timing led’s and reading the arduino examples and have to say your insight, attention to detail and explanation was perfect!!
    So may hat goes off to you for taking valuable time out of your life to help us understand.
    Thank you!!!

    Respectably
    Dave Pina

  46. Brian Gonzalez Reply

    I know this is an old post, but thank you! Been stuck killing a PID program from running in the background using delay(). This solved that issue so simply! No additional library necessary. Thank you again, Brian

  47. Pingback: Week 5: Photocells & Timers | Art & Electronics Spring 2014

  48. Hello James,

    Something odd is happening with example #4 and my arduino. When it executes, there is a short interval, then the LED lights (but dimly). Then it brightens. Then it goes back to dim. And that’s it. It doesn’t brighten again, nor does it turn off.

    I cut and pasted #4, verified it, and uploaded it correctly, as far as I can see. I’m mystified.

    Any help would be much appreciated.

    • It going to be a couple of days because I’m traveling without my Arduino this week. Are you certain you included the pinMode call?

      • I believe so. I copied and pasted Example #4 in its entirety. (By the way, Example #2 is missing a “;” at the end of Line 2)

        • I fixed #2, oops!

          Like I said, I’ll get back to you on #4. I’m not sure I see a problem with the code, but sometimes little things happen when I paste into the blog.

          • James

            Mark, I’ve updated #4 with correct code… Thank you for pointing out the issue! Sorry about that.

  49. Hi, I need help please. I am trying to remove the delays from the codes below:

    int northRed = 0; //first of all associate a pin number with the Northern red light, in this case 13
    int northAmber = 1; // associate pin 12 with the amber light
    int northGreen = 2; //and finally the green light with pin 11

    int eastRed = 3; //a pin for the east red light, 8
    int eastAmber = 4; //a pin for the east amber light , 9
    int eastGreen = 5; //a pin for the east green light, 10

    int maindelay = 1500; //The timings of the lights are based around this number.

    void setup() {
    pinMode(northRed,OUTPUT); //set the north red pin as an output
    pinMode(northAmber,OUTPUT); //set the north amber pin as an output
    pinMode(northGreen,OUTPUT); //set the north green pin as an output
    pinMode(eastRed,OUTPUT); //set the east red pin as an output
    pinMode(eastAmber,OUTPUT); //set the east amber pin as an output
    pinMode(eastGreen,OUTPUT); //set the east green pin as an output

    digitalWrite(northRed,HIGH); //Switch the red light on so we have something to start with
    digitalWrite(eastRed,HIGH); //switch the east red light on as well
    }

    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

    }

    can someone help please?

  50. Thanks a bunch James.
    Its working now!
    This is the coolest thing ever. Don’t ask me why but it is! Hah.
    Now I can get rid of my obviously infantile delay script and possibly add another LED to the chain. I am creating a sign that has a (IR) remote control and I got that to work. I am using case/switch statements so I can chose between a couple blinking patters, but they stop after one pass through the case scenario. In other words, It will blink the leds in sequence I programmed then stop. I suppose I make them continue with some sort of “while” statement or something like that. Eh?
    Thanks again,,
    Mark
    PS. Happy Holidays.

    • It sounds like you need a state machine for each pattern. If the patterns have the same number of “states” (or you can fit them into the name of states, e.g. repeat states) you can use one state variable. Use your switch() statement to select the correct pattern and then use another switch statement to execute the correct pattern state.

      case pattern1:
        switch(pattern state) {
          case 0;
          break;
          case 1;
          break;
        }
        break;
      case pattern2:
      //...
      
  51. Nice explanations. I’m a NOOB.
    I tried to upload some of the sketches above and kept getting warnings such as “gt was not declared in this scope. (example 5) and “&lt ” in example 4.
    Could this be because I have a newer model Arduino and those were written in 2011?
    Thanks

    • No, it is a problem with WordPress. Occasionally it converts the greater-than and less-than symbols in the code into their HTML-escaped code. I’ve updated the examples to show the correct symbol.

  52. Pingback: Week 5: Photocell + millis() timers | Art and Electronics – Fall 2013

  53. I’m trying to use a plurality of leds as a six string strobe tuner for guitar… Aparently this works with micros too, and I’m sure I’ll require the micro resolution… Rounding to the nearest 4th micro has me kinda spooked. Is there no way around this?

  54. I’m trying to get the code for 2 butons controlling 1 led(when they are pressed simultaneously the led turns on) end a buton, when is presed 2 times , turns a led on for a couple of seconds.My problem is that i ned them to work simultaneos, de delay() function esent ideal, the mili() function , i can not get my head around it.

    Here is my code:

    [cpp]
    const int Pin5 = 5;
    const int Pin6 = 6;
    const int Pin3 = 3;

    const int ledPin = 9;
    const int ledPin1 = 10;
    const int ledPin2 = 11;

    int buttonPushCounter = 0; // counter for the number of button presses
    int buttonState = 0; // current state of the button
    int lastButtonState = 0; // previous state of the button

    void setup() {

    pinMode(ledPin, OUTPUT);
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);

    pinMode(Pin5, INPUT);
    pinMode(Pin6, INPUT);
    pinMode(Pin3, INPUT);

    }

    void loop() {

    int Value = digitalRead(Pin5);
    int Value1 = digitalRead(Pin6);
    int Value2 = digitalRead(Pin3);
    buttonState = digitalRead(Pin3);

    if (Value == HIGH &amp; Value1 == HIGH)

    {
    digitalWrite(ledPin, HIGH);
    delay(2000);
    }

    else

    {
    digitalWrite(ledPin,LOW);
    }

    if (Value2 != lastButtonState)

    {

    if (buttonState == HIGH)

    {

    buttonPushCounter++;

    }

    lastButtonState = buttonState;

    if (buttonPushCounter % 2 == 0)

    {
    digitalWrite(ledPin1, HIGH);
    delay(3000);
    digitalWrite(ledPin1, LOW);

    }

    }

    }
    [/cpp]

    • You are really trying to combine two different things. Using the Button library might help with managing when or how the buttons are pressed. You should avoid variable names like “Value” and certainly don’t want to use conventions like “Value” and “Value1”. That makes it difficult to follow code later on because they don’t describe what you are trying to store. Variables like “LeftButtonValue” or “RedLED” are far more descriptive.

      Using millis() is all about creating a state machine. You need to constantly be checking what is happening with the buttons and reacting when they change. Then you need to have some state variables for your LEDs and constantly calling digitalWrite() using those state variables.

  55. I was wondering if you could help me? I would like to use use millis() with two different delays say light is on for 2 sec and off for 1 sec. On pin 13. Is this possible with millis? I’m sure it is im just not sure how to do it. Could you do an example like that? I would be very grateful.

    Thanks,

    Matt

  56. This is a great tutorial! I’ve got one quick suggestion for an addition though –

    The way it’s presently coded it always makes sure that at least one second passes between times the code executes, but that means that the actual cycle time is the time the code takes to execute plus one second, and if you’re doing something intensive elsewhere in the program this lost time can add up. If you change

    waitUntil = millis() + 1000;
    to
    waitUntil = waitUntil + 1000;

    then the program always tries to execute your code ‘on time.’ One iteration may start late if the program was doing something else, but that doesn’t delay every other time through the code.

    • Hi Art,

      You are absolutely correct. I’ve updated examples 4 and 5 to reflect this change.

      Cheers,
      James

  57. Hi James. Thanks for your tutorials. I am just starting with Arduino. I looked at the above sketch and added another LED which I got to flash at it’s own rate. But where I am stumped is I want it to flash twice quickly and then another led to flash twice quickly then back to the last LED. What I am going for is a police car type flasher where the headlights wig wag on their own and the blue and reds flash on their own and strobes flash on their own, normally all at different rates. I don’t expect you to write code for me but can you point me in the right direction?? I can’t seem to get a handle on this. But it’s a great learning tool and I look forward to cracking it finally! LOL…
    Thank you.

    • Hi Andrew, I think the key is going to be creating a State variable for each LED and tracking how many times the LED has strobed. Once you’ve strobed enough times, set a wait state for the amount of time the other LED will take to strobe. Does that make sense?

  58. Pingback: Arduino: How do you reset millis() ? - CMiYC Labs, Inc.

  59. No, the increment isn’t random. The same instructions are executed between the two calls every time.

    There is an accruacy issue with the code abive. For completeness the code should either: a) assign millis() a variable, check that variable, and increment waitUntilX based on that variable. Or b) adjust flashDelay to account for the time between instructions.

    In practice, if timing isn’t absolutely critical then the above method is okay.

  60. Sudarshan S K Reply

    Hi,
    I am curious is the time changes between the fist call to millis() to the second call to millis() within the if statements. In this case there will be a random increment in the duration. Isn’t this true.
    Thanks,
    Sudarshan

  61. Don DeGregori Reply

    Could I send you a sketch using the mills() function? I have been working on the problem for days with no success. It involves the Leah Buechley turn signal sketch, which works fine unmodified. I’m trying to add “chasing light” to the turn signals.I think other delays are interfering with the mills() function.

    Thanks, Don

  62. Chad LaFarge Reply

    Looks like the last example sketch comments do not agree with the values of the variables sequenceDelay (100 is referred to as 1000) and flashDelay (250 is referred to as 500).

    Or did I misunderstand?

    Thank you for the excellent tutorial.

    Chad

    • James Lewis Reply

      Chad, you are correct. The comments did not agree, the listing has been updated. In debugging the original code I started changing the Delays to make sure the lights (and the code) acted as I expected. I forgot to change them back before posting.

      It is an interesting exercise to change each on independently, to see how the code reacts differently. It is even more fun when you have a few more LEDs.

Write A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.