Pinterest Stumbleupon Whatsapp
Ads by Google

When you first started learning how to develop Getting Started With Arduino: A Beginner's Guide Getting Started With Arduino: A Beginner's Guide Arduino is an open-source electronics prototyping platform based on flexible, easy-to use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments. Read More for the Arduino What Is Arduino & What Can You Do With It? [Technology Explained] What Is Arduino & What Can You Do With It? [Technology Explained] If you're like me, tinkering with electronics is something you'd really like to be able to do - in theory at least - but the realities of time constraints, lack of knowledge and few rewards... Read More , you probably built a product that works a little bit like this:

Connected to your Arduino would be a single LED light. This would turn and off every second or so, and will continue until the Arduino is turned off. This is the “Hello World” program of Arduino, and perfectly illustrates how just a few lines of code can create something tangible.

arduino-led

I’m also willing to bet you used the delay() function to define the intervals between the light turning on and off. But here’s the thing: while delay is handy for basic demonstrations of how Arduino works, you really shouldn’t be using it in the real world. Here’s why – and what you should use instead.

How Delay() Works

The way the delay() function works is pretty simple. It accepts a single integer The Basics Of Computer Programming 101 - Variables And DataTypes The Basics Of Computer Programming 101 - Variables And DataTypes Having introduced and talked a little about Object Oriented Programming before and where its namesake comes from, I thought it's time we go through the absolute basics of programming in a non-language specific way. This... Read More (or number) argument. This number represents the time (measured in milliseconds) the program should wait until moving on to the next line of code.

But the problem is, the delay() function isn’t a good way to make your program wait, because it’s what’s known as a “blocking” function.

Ads by Google

The Difference Between Blocking and Non-Blocking Functions

To illustrate why blocking functions are bad, I want you to imagine two different chefs in a kitchen: Henry Blocking, and Eduardo NonBlocking. Both do the same job, but in wildly different ways.

When Henry makes breakfast, he starts by putting two rounds of bread in the toaster. When it finally pings, and the bread pops out golden brown, Henry puts it on a plate and cracks two eggs into a frying pan. Again, he stands by as the oil pops, and the whites begin to harden. When they’re finished, he plates them up and starts frying two rashers of bacon. Once they’re sufficiently crispy, he takes them off the frying pan, puts them on the plate and starts eating.

arduino-chef

Eduardo works in a slightly different way. While his bread is toasting, he’s already started to fry his eggs and bacon. Instead of waiting for one item to finish cooking before moving onto next one, he’s cooking multiple items concurrently. The end result is Eduardo takes less time to make breakfast than Henry does – and by the time Henry Blocking has finished, the toast and eggs have gone cold.

It’s a silly analogy, but it illustrates the point.

Blocking functions prevent a program from doing anything else until that particular task has completed. If you want multiple actions to happen at the same time, you simply cannot use delay().

In particular, if your application requires you to constantly acquire data from attached sensors, you should take care to avoid using the delay() function, as it pauses absolutely everything.

Fortunately, delay() isn’t the only way to make your program wait when coding for Arduino.

Meet Millis()

The millis() function performs a single task. When called, it returns (as a long datatype) the number of milliseconds that have elapsed since the program was first launched. So, why is that useful?

Because by using a little bit of simple math, you can easily “time” aspects of your program without impacting how it works. The following is a basic demonstration of how millis() works. As you’ll see, the program will turns the LED light on for 1000 milliseconds (one second), and then turns it off. But crucially, it does it in a way that’s non-blocking.

Now let’s look at how it works with Arduino.

arduino-millis-example

This program – which is heavily based on one from the official Arduino documentation – works by subtracting the previous recorded time from the current time. If the remainder (ie. time elapsed since the time was last recorded) is greater than the interval (in this case, 1000 milliseconds), the program updates the previousTime variable to the current time, and either turns the LED on or off.

And because it’s a non-blocking, any code that’s located outside of that first if statement should work normally.

Simple, isn’t it? Note how we we created the variable currentTime as an unsigned long. An unsigned value simply means that it can never be negative; we do this so that the maximum number we can store is larger. By default, number variables are signed, which means one “bit” of memory for that variable is used to store whether the value is positive or negative. By specifying it’ll only be positive, we have one extra bit to play with. 

Interrupts

So far, we’ve learned about one way to approach timing in our Arduino program which is better than delay(). But there’s another, much better way, but more complex: interrupts. These have the advantage of allowing you to precisely time your Arduino program, and respond quickly to an external input, but in an asynchronous manner.

That means that it runs in conjunction with the main program, constantly waiting for an event to occur, without interrupting the flow of your code. This helps you efficiently respond to events, without impacting the performance of the Arduino processor.

When an interrupt is triggered, it either stops the program, or calls a function, commonly known as an Interrupt Handler or an Interrupt Service Routine. Once this has been concluded, the program then goes back to what it was going.

The AVR chip powering the Arduino only supports hardware interrupts. These occur when an input pin goes from high to low, or when triggered by the Arduino’s built-in timers.

It sounds cryptic. Confusing, even. But it isn’t. To see how they work, and see some examples of them being used in the real world, hit the Arduino documentation.

Don’t Get Blocked

Using millis() admittedly takes a little bit of extra work when compared to using delay(). But trust me, your programs will thank you for it, and you can’t do multitasking on the Arduino without it.

If you want to see an example of millis() used in a real-world Arduino project, check out James Bruce’s Arduino Night Light and Sunrise Alarm. Arduino Night Light and Sunrise Alarm Project Arduino Night Light and Sunrise Alarm Project Today, we'll be making a sunrise alarm clock, which will gently and slowly wake you without resorting to an offensive noise-making machine. Read More

Found any other blocking functions we should be wary of? Let me know in the comments below, and we’ll chat.

Photo Credits: Arduino (Daniel Spiess)Chef (Ollie Svenson)

  1. pranav
    August 27, 2016 at 8:33 am

    good one....
    but what if i want to operate one led with two pushbutton.
    one push button is for on blinking of the led for some time
    and 2 nd is for off the led

  2. Tim
    August 12, 2016 at 1:49 pm

    If you want to use intervalls and have a specific amount of time you want to wait you can also code something like this:
    if(millis()%1000 = 0) {
    //type your code here
    }
    I hope you understand what I want to say.. If anything is incorrect or I have a big problem in my way of thinking, let me know this.

  3. Tyler
    March 17, 2016 at 6:47 pm

    Hi! I'm a high school student and I just ordered arduino. I have worked with notepad programing, and with RobotC, which is c based language for specific robotics parts. How different would the language be and what would be the biggest learning curve? Thanks

  4. David Refoua
    March 9, 2016 at 4:21 am

    I was looking for a way to convince my friend not to use delay(). This article and its well-illustrated examples helped me to achieve it. Thanks!

  5. Mohmmad Maruf Uddin
    March 7, 2016 at 5:21 pm

    That's really awesome. Hats-off for the nice explanation.

  6. Ben Thacker
    August 5, 2015 at 10:26 am

    Hey Matt, that looks an awful lot like a Sengled Boost infinity logo in the title picture. Cool

    • Matthew Hughes
      August 17, 2015 at 8:24 pm

      Ha, not sure about that, but cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *