Arduino Micros() Function – (millis vs micros)

In this tutorial, we’ll learn how to use the Arduino micros() function instead of delay. We’ll discuss how the Arduino micros() function works and what are the use cases for it. And also the fundamental limitations of the micros() function and how to overcome the micros() overflow (rollover) issue in your Arduino projects. Without further ado, let’s get right into it!

Table of Contents

  1. Arduino micros() Function
  2. Arduino micros() Delay Example
  3. Arduino micros() Overflow (Rollover) Issue
  4. Remarks on micros() Function
  5. Arduino millis() vs micros()
  6. Wrap Up

Arduino micros() Function

The Arduino micros() is a function that returns to you the time elapsed (in microseconds) since the Arduino board was powered up. Which can be used to create a time base for various events in your applications (like LED blinking, short pulse generation, or whatever). All without using the delayMicroseconds() function.

Syntax

Return

The Arduino micros() function returns an unsigned long data type. Which is the time elapsed since the Arduino board was powered up until the micros() function was called.

Example

❕ Note

Be advised that the Arduino micros() function has a resolution of 4μs because it only returns a number that’s a multiple of 4. So keep this in mind and don’t assume it’ll give you a result that’s more accurate than this.


Arduino micros() Delay Example

In this example project, we’ll create a time delay using the Arduino micros() function instead of the delay() function. We’ll generate a short pulse or a digital signal that keeps switching every 100μs. In other words, we’ll toggle an output pin every 100μs (the output signal’s frequency is therefore 5kHz).

Code Example

Here is the full code listing for this example.

Code Explanation

First of all, we’ll need a couple of unsigned long variables to hold the time stamps (T1 & T2) that we’ll use to determine if the desired time interval has yet elapsed or not.

And we’ll also create a variable to hold the desired delay time interval for the output pin toggle event.

setup()

in the setup() function, we’ll set the pinMode to be output for the signal output (pin5).

loop()

in the loop() function, we’ll call the micros() function to take a time stamp that represents the current time for the Arduino board since it was powered up. And we’ll save that in T2 variable. Then, we’ll check the difference between T1 (time zero) and T2 (the current timestamp) and see if it’s equal to or greater than the desired delay time interval ( TimeInterval ).

If the 100μs time interval has elapsed, the if condition will be satisfied and we’ll toggle the output pin and save the current time stamp in the T1 variable. And keep repeating forever.

In this way, we’ve achieved the same functionality of a delay without even using a delay that blocks the CPU for no reason and also we’re using an efficient way that’s easily scalable for larger systems as we’ll see in the next project example.

TinkerCAD Simulation

Here is the simulation result for this project on the TinkerCAD simulator. You can run it as is, or make a copy and add your own code and start running the simulation to see how it’s going to behave.

Arduino-micros-delay-example-simulation

You can check this simulation project on TinkerCAD using this link.

Testing Results

Here is the result of testing this project on my Arduino UNO board. As shown on my oscilloscope screen, it’s not a perfect 100μs time interval as we’d expected. It’s coming to around 112μs due to some time wasted in context switching and function calls. This can be easily compensated for by adjusting the ( TimeInterval ) variable down to maybe 90μs or something.

Arduino-micros-delay-Example


Arduino micros() Overflow (Rollover) Issue

When the Arduino micros() internal counter variable reaches its maximum limit (232-1 which is 4,294,967,295) it will overflow and rollover back to zero and start counting up again.

This happens once every 4,294,967,295 μs (71.58 minutes) and most of your projects won’t be up and running for this long period of time. But after 71.58 minutes, the counter will overflow and the system will miss at least one action before it corrects itself and goes back to normal.

The behavior at the time of overflow will differ from one project to another depending on the purpose you’re using the micros() function for. Here is the basic micros() delay time interval example we’ll consider.

Always T2 (the current time stamp) will be larger than T1 (the previous timestamp). And your application will keep running smoothly and toggle the LED every TimeInterval as you’ve programmed it to. Let’s say it’s 100μs

However, at the overflow time, the T1 will have something like (4,294,967,280) and T2 has passed the (4,294,967,295) limit and rolled back to zero and now has a value of 84.

In this case, T2 is no longer larger than T1, and doing the subtraction (T2 – T1) is expected to result in a huge negative number. However, as we’re using unsigned numbers for both variables and the result is also an unsigned number, the subtraction will give the absolute difference between (T2 & T1).

Therefore, there is no need to worry about this issue at all because even when it happens, it won’t disrupt the logical or timing behavior of your system. And you can test this overflow situation on your own without waiting for 71.58 minutes by using the code example below. Which recreates the overflow scenario and prints the result that we were afraid it’d be messed up.

To stay on the safe side, we can also enforce the type casting for the subtraction result to make sure it doesn’t get messed up if a newer version of the compiler has been released or something. And here is how to do it.


Remarks on micros() Function

Those are some important notes that you need to know about the Arduino micros() function, so you can use it more efficiently in your projects.

Arduino micros() Max Value

The maximum value for the Arduino micros() function is 232-1 which is 4,294,967,295. This turns out to be 71.58 minutes before the micros() variable reaches overflow and rollovers back to zero and starts counting up again.

Arduino micros() To Seconds

You can take the micros() function reading and convert it to time in the (hours: minutes: seconds) format. Here is how to take the microsecond reading and parse out the desired time information.

And you’d be better off using the millis() function instead if you need a larger time interval in the milliseconds range.

Arduino micros() Accuracy

The Arduino micros() function accuracy is around 4μs as it only returns a value that is a multiple of 4. This is considering that your Arduino board is running at 16MHz. Because if your Arduino board’s target microcontroller is running at 8MHz, the accuracy will get even worse.

For larger time intervals, in the milliseconds’ range, you’d be better off using the millis() function instead.

Arduino micros() in Interrupt

When using the micros() function, please be aware that it depends on a timer interrupt. If you’ve, for whatever reason, disabled interrupts it won’t work temporarily until you re-enable it back again.

You can also use the micros() & millis() functions inside ISR (interrupt service routine) handlers. But be advised that it won’t update its reading as long as you’re still in the ISR context. If you’d like to poll the micros() function and wait for some time to pass within an ISR handler, the system will be stuck there forever. Because the micros() function output will not change as long as you’re still in the ISR handler context.

Moreover, using any sort of delay within the ISR handler is an undesirable practice that you should always avoid at any cost. This will introduce a lot of trouble in your system in the long run. Try using the methods introduced in this tutorial to avoid using any sort of “CPU-blocking” delay.


Arduino millis() vs micros()

If you’re just getting started with Arduino, it’s always easier to use the delay() function to insert a time interval delay to separate various events. However, it quickly gets messy if you’re dealing with many events and trying to achieve a certain timing behavior. As the delay() function does actually block the CPU and badly affects the responsiveness of your application at the end.

The Arduino micros() & millis() functions, on the other hand, can be used to get and compare time stamps to achieve different timing requirements as per your application needs. And this has no negative impact on the overall system behavior or responsiveness.

If you need high resolution or any timing requirement that is less than a millisecond, use the micros() function. Otherwise, you can just use the millis() function for larger time intervals (in the milliseconds range).

???? Also Read
Arduino millis Timer Tutorial

This tutorial will provide you with more in-depth information about the Arduino millis() function. How it works and how to use it. And discuss its various application use cases, fundamental limitations, and alternatives.


Parts List

Here is the full components list for all parts that you’d need in order to perform the practical LABs mentioned here in this article and for the whole Arduino Programming series of tutorials found here on DeepBlueMbedded. Please, note that those are affiliate links and we’ll receive a small commission on your purchase at no additional cost to you, and it’d definitely support our work.

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting my work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports our community.


Wrap Up

To conclude this project tutorial, we can say that it’s much better to use the Arduino micros() & millis() timer-based functions instead of using the delay() function. The micros() overflow (rollover) issue is nothing you need to worry about. And you need to be careful while using micros(), millis(), or delay() inside ISR handlers.

If you’re just getting started with Arduino, you need to check out the Arduino Getting Started [Ultimate Guide] here.

And follow this Arduino Series of Tutorials to learn more about Arduino Programming.

???? Also Read
Getting Started With Arduino Programming For Beginners

This is the ultimate guide for getting started with Arduino for beginners. It’ll help you learn the Arduino fundamentals for Hardware & Software and understand the basics required to accelerate your learning journey with Arduino Programming.


FAQ & Answers

What does micros () do in Arduino?

The Arduino micros() is a timer-based function that returns to you the time elapsed (in microseconds) since the Arduino board was powered up. Which can be used to create a time base for various events in your applications (like LED blinking, pulse generation, or whatever). All without using the delay() function.

What data type is micros () in Arduino?

The Arduino micros() function return an unsigned long data type variable. And the return value is always a multiple of 4, which means its accuracy is around 4μs.

How long does micros() take Arduino?

The Arduino micros() function takes approximately 71.58 minutes to reach overflow and roll over back to zero and start counting up all over again. Each function call and the returned values can have an error of 4μs.

How accurate is Arduino micros()?

the Arduino micros() has an accuracy of around 4μs as this function’s return value is always a multiple of 4. There is also some time wasted in function calls and context switching that will add up to a few microseconds.

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment