SALES INQUIRIES: 1 (888) 767-9864

Doing multiple timed things with Arduino: Unleash the millis()!

Have you ever wanted to do MULTIPLE timed events with Arduino? What about multiple CONCURRENT timed events? We’re “upping” our game with this lesson, so buckle in and hold on tight!

The millis story so far

This is part of a mini-series we’ve been publishing that’s all about using the Arduino millis function to create timed events. For example, you may want a servo to move every 3 seconds, or to send a status update to a web server every 3 minutes.

If you haven’t seen the previous lessons in this series, we highly recommend that you go back and check them out either now or after this lesson. Here’s a quick rundown: In part 1 we described the basics of the millis function in general, in part 2 we talked about tight loops and blocking code, in part 3 and part 4 we discussed some issues that arise when using the delay function, and in part 5 we showed how to create “once-off” events and repetitive timed events using the millis function.

In this lesson

  • Map out a program with 2 INDEPENDENT timed events
  • Code from scratch a program using millis() to time 2 repetitive events
  • Drink Kool-Aid and watch a beautiful sunset

Framing the problem with an algorithm

Every good program has an even better algorithm to go along with it, so before we start typing away at the Arduino IDE, first we want to write out our plan of action. This is more or less what we’re trying to accomplish.

We’ve got two sensors, a light-dependent resistor (or LDR) and a temperature sensor. What we want to do is read these values and display them to the Serial Monitor window but we don’t want constant readings.

Instead, we want two separate intervals. We want the light-dependent resistor to read and display every second and the temperature sensor to read and display every five seconds.Arduino LDR and tempSo now we have our two separate events. Let’s write our algorithm. We want Event 1 to read the LDR and then display that value every 1 second. Event 2 will read the temperature sensor and display it’s value every five seconds.

  • Algorithm
    • Event 1: Read/Display LDR Value (every 1 sec)
    • Event 2: Read/Display Temp Value (every 5 sec)

 

Think of the algorithm as our plan of action. Looking at this it appears we could use the Arduino millis () function to set up the timing for these events, and we could use analogRead () to read the LDR and the temperature sensor values.

Then we could use functions from the Serial library, Serial.begin(), Serial.print(), and Serial.println(), to display those values to the Serial Monitor Window on our computer.

When you’re creating a program that has repetitive timed events it doesn’t hurt to lay out the timing of the events on a piece of paper. This is especially true when you have overlapping or concurrent events.

When we lay this out on our timeline, we see that we have two events that overlap every five seconds.

Luckily for us, we are using the millis function instead of the delay function, which would make this MUCH more difficult.

Please keep in mind the focus of this lesson is demonstrating how to code timed events with Arduino, so we won’t go into detail on how to set up your actual circuit for this experiment. We’ve included a schematic below as one possible way you could set it up, or even easier, you can use our Kit-on-a-Shield which makes programs and experiments like this super easy.

Arduino LDR and temp circuit

If you’re wondering how to wire a circuit like this, definitely check out the ProgrammingElectronics.com website for lessons on setting up different circuits. 

OK, assuming you have a functioning circuit (or not, you can follow along without one), let’s jump into the Arduino IDE and start coding this bad boy from scratch.

Code… From SCRATCH!

Before we get too crazy, let’s write ourselves a little “to-do list” in comments. We can work through these one by one. This is just one technique that’s useful to split the algorithm into chunks.

The first thing we need to do is set up some pins for where we’ve got our sensors attached.  The sensors are always going to be at these pins, i.e. they will never change, so let’s make these constants. We’ve assigned analog pin A2 for the LDR and analog pin A4 for temp sensor.

Next let’s setup variables for the timed events. We need to create two constants and two variables. The two constants are the eventTimes. This is the interval at which we want each of these events to occur.

As previously mentioned, we want to read and display the light-dependent resistor value every 1,000 milliseconds. We want to read and display the temperature sensor every 5,000 milliseconds. Those intervals aren’t going to change, so we can make them constants. Let’s make them unsigned long constants as well.Arduino unsigned longsThe variables we’ve created are named previousTime_1 and previousTime_2 and again they’re both unsigned longs. The reason we’re using the unsigned long data type is because the value for millis gets really big. We want to ensure that we’ve got enough storage in that variable data to hold that really big number.

So, these “pervious time” variables allow us to help track the time as these events occur. If any of this is looking foreign to you, please make sure to check out the previous lessons because a lot of this code has already been explained.

Next, we need to setup Serial communication. We will use the Serial.begin() function from the Serial library to initiate Serial communication. Let’s use the standard 9600 baud rate.

Now let’s get into the loop. We want to update the current time, and we want to do it frequently, hence why we’re using the loop section. We’re going to create a currentTime variable and it’s going to be constantly updated via the millis function.

So, we’ve created a variable named currentTime and it is equal to the return value of millis. Therefore, currentTime holds a snapshot value of millis, which will always be counting up from when you powered up the Arduino board.

Every time through the loop it’s going to be updating it again and again. Because it’s an unsigned long it can hold a really big number, like we’ve talked about before.

Next, we are going to set up the timing for the first event. The key to this event timing is the first ‘if statement’ condition.

What we’re doing here is comparing the difference between the current time and the previous time with our event interval. Remember our eventTime_1 is constant and will always be 1,000.

Essentially, what we’re doing is looking at the currentTime, which is always updating, and the ‘if statement’ is waiting until the difference between these two is equal to (or greater than) 1,000.

Once this condition becomes true we then run our event code, displaying the current analogRead of the LDR to the serial monitor.

At the bottom of  our code is a very important statement. This is how we are updating our previousTime so that in another 1,000 milliseconds, we can get this code to run again.

If we don’t do this, then previousTime_1 will always be set to 0, and from here forward our if statement will always be true, and the LDR will just continuously be read and displayed.

By setting the previousTime equal to the currentTime we restore the gap between currentTime and previousTime, allowing for a sustainable repetitive event.

If this first line of code is confusing try running some numbers through it. See what happens when millis returns 0, 100, 500, and 1000.

If you’re still confused, definitely check out our last lesson, Arduino Sketch with Millis () instead of Delay (), which explains this explicitly.

Arduino serial monitor screenshot

So let’s upload this and test it out.

It looks like about every second we’re getting a reading from our light-dependent resistor. If we shine a light on it we can see an increase in readings, so it looks like it’s working as advertised. Excellent, we have our first timed event.

Next, we want to add another timed event. How are we going to do that?

Really, we’re just going to repeat the code from Event 1 almost exactly, just changing the names of the variables.

So let’s upload the sketch and test it out. We open the Serial Monitor and we can see that again this is working as advertised. This is pretty sweet!

We’re getting five light-dependent resistor readings and we’re also getting temperature sensor readings and the events are happening at the time we wanted them to. So, we’ve got two independent repetitive events working concurrently.

Arduino IDE and monitor screenshot2

 

As you can see this wasn’t too painful to write out. The toughest part is just wrapping your head around the ‘if statement’ condition.

If you can nail that down and understand the comparison that’s happening, then you’ll officially have this in your tool bag and you can use this in future programs.

To ensure you’ve got it down pat, try coming up with another program with different events, maybe turning LEDs on and off at different intervals.

Summary

First, we mapped out what we were doing just by writing out our algorithm before we actually get into the code.

Then, we went into the Arduino IDE and wrote a program that created two separate timed events from scratch.

We hope you enjoyed this lesson. Again, there’s a whole series on using this millis function. Definitely check out the other videos in the series. We look forward to seeing you next time!

Arduino drinking cocktails with sunset

2 Comments

  1. Avatar Susabhan on May 7, 2019 at 10:28 am

    Very nice teaching style, any one can get clear conception.

Leave a Comment