SALES INQUIRIES: 1 (888) 767-9864

Millis vs. Delay Part 3 | A mini-series on Timing Events with Arduino Code

Have you ever tried to create create timed, repetitive events in your Arduino sketches?

Have you run into roadblocks when you try to use the delay() function? We’ll explore why this happens in this lesson.

Intro

This is part 3 of our millis() function mini-series. Part 1 helps us understand what the millis() function does, and part 2 discusses tight loops and blocking code. If you haven’t had a chance yet to look at the previous two videos you should check them out after this lesson.

Let’s say you’re building a project using Arduino and you have an event that you want to have happen every so often. Maybe every three minutes you want a servo motor to move or maybe every 20 seconds you want to update a web server with the most current sensor reading.

That’s exactly the objective of this series of lessons. We’re going to identify when using the delay function makes sense, and when instead using the millis function for timing events makes more sense.

Topics covered in this lesson

  • The simple timed event
  • The not so simple timed event
  • A variant of the ancient Mayan calendar

The Simple Timed Event

Let’s imagine for a second that you’re throwing a party. This party is going to awesome, we’ve got tiki torches, we’re gonna have a pig on a spit, a magician and we’ve even contracted a live Guns N’ Roses cover band. Ah, it’s gonna be sweet.Arduino block partyTo welcome guests at the door we’ve decided to get a life-sized cardboard cutout of you that we’re going to put right at the front door. To make it more fun we went ahead and drilled out the eyes and we replaced them with these over-sized green LEDS to make it look like you’re possessed by an alien.

We’ve taken those two LEDs and connected them to our Arduino board with just two simple LED circuits. Green LED eyes using Arduino

Before we dive into our Arduino sketch, let’s write out our algorithm. This algorithm is will be very simple: turn LEDs on. We will need the pin mode function and the digital write function to do this. Now that we’ve mapped out our program let’s jump in to the Arduino IDE.

Let’s start by designating the pins where we have the LED circuits attached. We need to declare and initialize two constants.

Declaring constants in Arduino IDE

One is for the left eye (pin 7) and one is for the right eye (pin 8). We’ve made them constants because they’re not going to change.

As review, we also have the setup and the loop functions in here. Setup runs once and loop runs over and over and over.

In the setup we’re going to use the pin mode function and set the mode for those two pins as outputs because we want to source voltage to those pins.

Next let’s use the digital write function to turn the LEDs on. We only want the LEDs to turn on once. If we put the digital write function in the setup they will be on as the program gets to the loop section.

If we upload this code to the Arduino and we step back, your cardboard cutout eyes should be shinning bright.

Arduino LED eyes set to on

That looks pretty cool! But you know what would be cooler? If those eyes flickered. So we decide to have them flicker, or have the LEDs turn off then back on, every 100 milliseconds.

Said another way, we want to create a simple, timed repetitive event. So let’s think through our algorithm one more time. We want the LED to be on for 100 milliseconds and then we want it to be off for 100 milliseconds. So really our algorithm’s still pretty easy.Arduino algorithm for LED repetitive eventIt’s only 5 steps: LED on, wait, LED off, wait, and repeat. To do this we can use the digital write function to turn the LED on and off. For the wait sections we can use the delay function. We put the code inside the loop because we know that the loop will run over and over again.

Let’s take a look at the code:Arduino sketch that flashes LEDsWe also increased the delay to 500 milliseconds (half a second). To summarize, we turn on the LEDs, wait 500 ms, turn OFF the LEDs, wait 500 ms, then we start the loop all over again.

If you upload your sketch to the Arduino you will indeed see we have created a simple, timed repetitive events. Those eyes are blinking in unison, and it looks like you’re possessed by an alien!

What else can we do to make our project stand out? What if the eyes blink on and off in unison, but then they alternate blinking (left then right) very quickly? Let’s sketch this out:Arduino algorithm/ plan

Let’s accomplish the fast alternating using a for loop. We’ll alternately write high and low voltages to each of the corresponding “left” and “right” pins that control the LEDs.

For 10 iterations we’ll have them alternate back and forth, and then once the for loop is done, the whole sketch will begin again.

Arduino for loop code

So we upload the code, step back, look at our project and it’s behaving exactly as advertised. It blinks on, then off, then for 10 iterations it quickly alternates left and right.

Now we have two timed, repetitive events. Each one happens one after the other, or sequentially. The delay function seems to be working just fine!

Arduino timed events

Let’s continue to add some complexity. Let’s get rid of the first timed event and just use the alternating blinking event. Let’s also have your hand waiving back and forth. To do this we’ll install a servo motor at your elbow.

Let’s grab our piece of paper and we write our algorithm:

Arduino algorithm for servo arm

We start to have this sneaky feeling that something isn’t going to work quite right. Let’s test it and find out. Going back to the code, the first thing we do is include the servo library.

Next we create a servo object and we also create a variable that will hold the position of the servo. Then we attach the servo to pin nine. Down in the loop, we delete the “blinking in unison event” and just keep the alternating LED effect, which was our second timed event.

Next we add a for loop that’s going to move the position of the servo, sweeping it left and right. If you’re not familiar with using servos don’t sweat the servo code too much. We’re really just trying to use this example to show you some of the issues we run into with delay.

#include 

/* LEDcircuits attached here */
const byte LED_eye_L = 7;
const byte LED_eye_R = 8;

/* Servo object */
Servo myservo;
int pos = 0;

void setup() {

  myservo.attach(9);

  pinMode(LED_eye_L, OUTPUT);
  pinMode(LED_eye_R, OUTPUT);

}

void loop() {

  for (int i = 0; i < 10; i++) {
    digitalWrite(LED_eye_L, HIGH);
    digitalWrite(LED_eye_R, LOW);

    delay(100);

    digitalWrite(LED_eye_L, LOW);
    digitalWrite(LED_eye_R, HIGH);

    delay(100);
  }

  for (pos = 0; pos <= 180; pos += 1) { 
    myservo.write(pos); 
    delay(15); 
  } 
  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }
}


So we upload the code and now that sneaky feeling we had becomes very apparent. The LEDs do their alternating flickering effect, and then the arm waves. What we wanted is the LEDs to flicker while the arm waves.

Why is this happening? Because the delay is blocking the other code from running. We could put the servo event at the top of the loop and bottom of the loop (sandwiching the LED flickering event), but all that would result is the arm waving, then the eyes flickering, then the arm waving again.

It seems like delay is getting in the way of what we need to do. So if you have two timed events that are overlapping, that is you want one to happen while the other is happening, then the delay function is probably not going to be useful. An alternative is using the millis function.

Summary

If you have two, repetitive, timed events and those events overlap then you may find that using the delay function is not going to be the best solution. You will want to consider an alternative like the millis() function which we will explore in following lessons.

Arduino delay function bad

On the flip side, when we have two timed events and one happens after the other (i.e. they are sequential), then using the delay function is perfect! It’s simple solution to simple projects.

Arduino function good

In the next lesson we’ll explore another situation where using the delay function can start to cause troubles. See you then!

Arduino Mayan pyramid

3 Comments

  1. […] us understand what the millis() function does, and part 2 discusses tight loops and blocking code. Part 3 discusses some issues with the delay function. If you haven’t had a chance yet to look at the […]

  2. […] millis vs. delay Part 3 | A mini-series on Timing Events with Arduino Code […]

  3. […] Millis vs. Delay Part 3 | A mini-series on Timing Events with Arduino Code […]

Leave a Comment