How to use millis() and micros() – Arduino tutorial


In this tutorial we learn about How to use millis() and micros(), Arduino is a popular platform for building electronic projects, and one essential aspect of programming Arduino is managing time. When working on projects that require precise timing or time-based actions, it’s crucial to have a reliable method to measure and control time. In Arduino, the millis() and micros() functions play a vital role in accomplishing this.

Understanding the concept of time in Arduino

In Arduino programming, the delay() function is commonly used to introduce delays or pause the execution of code for a specific period. However, the delay() function has limitations. It pauses the entire program and prevents other actions from taking place during the delay. Additionally, it becomes challenging to perform multiple tasks simultaneously while using delay().

To overcome these limitations, Arduino provides the millis() and micros() functions. These functions are based on the internal timer of the Arduino board and provide a way to measure time without blocking the program’s execution.

Hardware Required

Components#Buy From Amazon
Arduino UNO1Buy Now
LED 5mm1Buy Now
Resistor 220​Ω1Buy Now
Jumper Wires2Buy Now
Breadboard1Buy Now

Working with millis()

The millis() function returns the number of milliseconds that have passed since the Arduino board started running its current program. It allows you to track time and execute code based on specific time intervals.

The syntax for using millis() is straightforward. You can assign its value to a variable and use it in conditional statements to trigger actions. For example:

unsigned long currentTime = millis();

if (currentTime - previousTime >= interval) {
  // Execute code after a specific interval
  previousTime = currentTime;

Using millis() has several benefits. It allows you to create non-blocking delays, enabling multitasking in your projects. You can perform different actions concurrently by checking the elapsed time using millis().

Working with micros()

While millis() provides a resolution in milliseconds, micros() offers a higher level of precision by measuring time in microseconds. It is particularly useful when working with time-sensitive applications or tasks that require accurate timing.

The usage of micros() is similar to millis(). You can store its value in a variable and use it for conditional statements or calculations.

unsigned long currentMicros = micros();

if (currentMicros - previousMicros >= intervalMicros) {
  // Execute code after a specific microsecond interval
  previousMicros = currentMicros;

Micros() finds applications in tasks such as controlling servos, reading sensor data at high frequencies, or generating precise timing signals.

Comparing millis() and micros()

Both millis() and micros() are valuable functions for managing time in Arduino, but they differ in their resolution and use cases. Millis() has a resolution of 1 millisecond, while micros() provides a resolution of 1 microsecond.

When choosing between the two functions, consider the required precision and the specific needs of your project. For most applications, millis() is sufficient, as it offers a good balance between accuracy and simplicity. However, if you require more precise timing, micros() is the better choice.

Examples and code snippets

To illustrate the usage of millis() and micros(), here are a couple of simple examples:

Example 1: Blinking an LED using millis()

Here is the Led blink example and also the 2 example codes using the millis() function.

Circuit diagram



const int ledPin = 13;
unsigned long previousTime = 0;
unsigned long interval = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);

void loop() {
  unsigned long currentTime = millis();
  if (currentTime - previousTime >= interval) {
    digitalWrite(ledPin, !digitalRead(ledPin));
    previousTime = currentTime;

In this example, an LED connected to pin 13 is blinked on and off using millis(). The LED toggles its state every second.

Example 2: Measuring time intervals with micros()

unsigned long previousMicros = 0;
unsigned long intervalMicros = 100;

void setup() {
  // Set up your project

void loop() {
  unsigned long currentMicros = micros();
  if (currentMicros - previousMicros >= intervalMicros) {
    // Perform time-sensitive actions
    previousMicros = currentMicros;

In this example, you can execute time-sensitive actions based on microsecond intervals. The code compares the current time with the previous time and triggers the action if the specified interval has passed.

Best practices and tips for using millis() and micros()

  • Avoid using delay() in time-critical projects and prefer millis() or micros() instead.
  • Use unsigned long variables to store the return values of millis() and micros().
  • Initialize the previous time variable appropriately to prevent unwanted behavior.
  • Remember that millis() and micros() values will eventually overflow and restart from zero. Plan your code accordingly.
  • Consider using libraries or abstraction layers that simplify time management in Arduino.

Troubleshooting common issues

  • Ensure that you have included the necessary header files for millis() and micros() to work.
  • Check your code for any potential conflicts or logical errors that may affect the timing of your program.
  • Verify that your Arduino board’s clock speed is correctly set if you’re experiencing timing inconsistencies.


How to use millis() and micros() – Arduino tutorial, the functions provide a valuable way to manage time in Arduino projects. They offer precise timing capabilities without blocking the program’s execution, allowing for multitasking and time-sensitive actions. By understanding how to use millis() and micros() effectively, you can enhance your projects and achieve better control over timing-related tasks.

Leave a Comment