🌐
Arduino Getting Started
arduinogetstarted.com › reference › arduino-micros
micros() | Arduino Getting Started
June 5, 2026 - Learn micros() example code, reference, definition. Returns the number of microseconds since the Arduino board began running the current program. Returns the number of microseconds since the Arduino board began running the current program.
🌐
Arduino
docs.arduino.cc › language-reference › en › functions › time › micros
micros() | Arduino Documentation
June 5, 2025 - This function returns the number of microseconds since the Arduino board began running the current program.
Discussions

Arduino micros function
Hi all I have a very specific question about the Arduino micros() function. Only purpose is to understand and learn, so I do NOT have a practical issue. But I hope someone will be able to enlighten me. The function (which I found on a forum): unsigned long micros() { unsigned long m; uint8_t ... More on forum.arduino.cc
🌐 forum.arduino.cc
4
0
May 9, 2020
programming - Explanation for micros function - Arduino Stack Exchange
I was trying to understand the working of micros() function internally and I had a look at the function in Arduino.h More on arduino.stackexchange.com
🌐 arduino.stackexchange.com
timers - Using millis() and micros() inside an interrupt routine - Arduino Stack Exchange
Edit: Regarding “why micros() "starts behaving erratically"”, as explained in an “examination of the Arduino micros function ” webpage, micros() code on an ordinary Uno is functionally equivalent to More on arduino.stackexchange.com
🌐 arduino.stackexchange.com
Help using the micros() function
micros() is a part of Arduino core code. Have you placed all the core code into Atmel Studio? Or, are you using any Atmel Studio plug-ins for Arduino? More on reddit.com
🌐 r/arduino
5
3
November 2, 2015
🌐
DeepBlue
deepbluembedded.com › home › blog › arduino micros() function – (millis vs micros)
Arduino Micros() Function - (millis vs micros)
August 17, 2023 - 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 ...
🌐
TutorialsPoint
tutorialspoint.com › arduino › arduino_micros_function.htm
Arduino - micros () function
The micros() function returns the number of microseconds from the time, the Arduino board begins running the current program. This number overflows i.e. goes back to zero after approximately 70 minutes.
🌐
Instructables
instructables.com › circuits › arduino
How to Get an Arduino Micros() Function With 0.5us Precision : 5 Steps - Instructables
October 17, 2017 - How to Get an Arduino Micros() Function With 0.5us Precision: I love Arduino microcontroller programming, and I regularly use it in aerospace research, as well as in home projects. As I work on my many home projects, however, I frequently find myself needing a very precise timer.
🌐
The Robotics Back-End
roboticsbackend.com › home › arduino millis() vs micros()
Arduino millis() vs micros() - The Robotics Back-End
October 11, 2021 - But if you want, you can read the source code for those functions directly on GitHub, as the Arduino project is completely open source. First of all, the functionality is the same: both millis() and micros() are keeping the time since the Arduino program started.
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Arduino micros function - Programming - Arduino Forum
May 9, 2020 - Hi all I have a very specific question about the Arduino micros() function. Only purpose is to understand and learn, so I do NOT have a practical issue. But I hope someone will be able to enlighten me. The function (which I found on a forum): unsigned long micros() { unsigned long m; uint8_t oldSREG = SREG, t; cli(); m = timer0_overflow_count; #if defined(TCNT0) t = TCNT0; #elif defined(TCNT0L) t = TCNT0L; #else #error TIMER 0 not defined #endif #ifde...
🌐
Wordpress
ucexperiment.wordpress.com › 2012 › 03 › 17 › examination-of-the-arduino-micros-function
Examination of the Arduino micros() Function | µC eXperiment
July 28, 2016 - Recall the typical Ardiuno runs on a 16MHz oscillator. Both the millis() and micros() functions base their calculations on the Arduino Timer #0, which is running with a prescale of 64. This results in the timer ticking at 64*1/16,000,000th of a second (which is 0.000004 seconds or evey 4 µs).
Find elsewhere
🌐
Arduino
docs.arduino.cc › language-reference › funções › time › micros
micros()
The official Arduino programming language structure reference pages.
Top answer
1 of 4
21

The other answers are very good, but I want to elaborate on how micros() works. It always reads the current hardware timer (possibly TCNT0) which is constantly being updated by the hardware (in fact, every 4 µs because of the prescaler of 64). It then adds in the Timer 0 overflow count, which is updated by a timer overflow interrupt (multiplied by 256).

Thus, even inside an ISR, you can rely on micros() updating. However if you wait too long then you miss the overflow update, and then the result returned will go down (i.e you will get 253, 254, 255, 0, 1, 2, 3 etc.)

This is micros() - slightly simplified to remove defines for other processors:

unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;
    cli();
    m = timer0_overflow_count;
    t = TCNT0;
    if ((TIFR0 & _BV(TOV0)) && (t < 255))
        m++;
    SREG = oldSREG;
    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

The code above allows for the overflow (it checks the TOV0 bit) so it can cope with the overflow while interrupts are off but only once - there is no provision for handling two overflows.


TLDR;

  • Don't do delays inside an ISR
  • If you must do them, you can time then with micros() but not millis(). Also delayMicroseconds() is a possibility.
  • Don't delay more than 500 µs or so, or you'll miss a timer overflow.
  • Even short delays may cause you to you miss incoming serial data (at 115200 baud you will get a new character every 87 µs).
2 of 4
9

It is not wrong to use millis() or micros() within an interrupt routine.

It is wrong to use them incorrectly.

The main thing here is that while you are in an interrupt routine "the clock isn't ticking". millis() and micros() won't change (well, micros() will initially, but once it goes past that magic millisecond point where a millisecond tick is required it all falls apart.)

So you can certainly call on millis() or micros() to find out the current time within your ISR, but don't expect that time to change.

It is that lack of change in the time that is being warned about in the quote you provide. delay() relies on millis() changing to know how much time has passed. Since it doesn't change delay() can never finish.

So essentially millis() and micros() will tell you the time when your ISR was called no matter when in your ISR you use them.

🌐
Mechatronics LAB
mechatronicslab.net › home › lessons › arduino programming handbook › 16 timers & delays › 16.4 using micros() for microsecond resolution in arduino programming
16.4 Using micros() for Microsecond Resolution in Arduino Programming - Mechatronics LAB
What Is micros() and Why Use It? The micros() function returns the number of microseconds since the Arduino board began running the current program. One microsecond is a millionth of a second.
🌐
Cach3
tutorialspoint.com.cach3.com › arduino › arduino_micros_function.htm
Arduino micros () function
The micros() function returns the number of microseconds from the time, the Arduino board begins running the current program. This number overflows i.e. goes back to zero after approximately 70 minutes. On 16 MHz Arduino boards (e.g. Duemilanove and Nano), this function has a resolution of ...
🌐
GitHub
github.com › ElectricRCAircraftGuy › eRCaGuy_TimerCounter
GitHub - ElectricRCAircraftGuy/eRCaGuy_TimerCounter: An Arduino micros()-like function (encapsulated in a library) with 0.5us precision (since the built-in Arduino micros() function has only 4us precision) · GitHub
I decided to write this code because I needed a really precise timer to be able to measure Radio Control pulse width signals using external interrupts and pin change interrupts, and the built-in Arduino micros() function only has 4 microsecond precision, which allows for a lot of variability, or "noise" in the readings.
Starred by 31 users
Forked by 12 users
Languages   C++
🌐
Reddit
reddit.com › r/arduino › help using the micros() function
r/arduino on Reddit: Help using the micros() function
November 2, 2015 -

I am using Atmel Studio to program my ATmega 328p microcontroller. I am trying to use the micros() function to get time stamps for certain events occurring in the program. I think I have to include a specific header file to use the function, but I don't know which one. Any help is appreciated

🌐
Circuit Geeks
circuitgeeks.com › home › arduino millis() and micros()
Arduino millis() and micros()
March 2, 2022 - micros() returns the number of microseconds passed since the Arduino started running the program. If you need more precise time you should use micros(). But keep it in mind that this number will overflow (go back to zero) very quickly, after ...
Top answer
1 of 3
10

Yes, depending your Arduino's basic clock rate. For example here are the counter-timer input frequencies and periods after pre-scaling, for an ATMega2560's counter-timer 2, and a basic clock rate of 16MHz. The timer has built in "prescaler" value options which determine frequency/period, shown in this table:

    TCCR2B bits 2-0    Prescaler    Freq [KHz], Period [usec] after prescale
          0x0          (TC stopped)      --         --
          0x1                1        16000.        0.0625
          0x2                8         2000.        0.500
          0x3               32          500.        2.000
          0x4               64          250.        4.000
          0x5              128          125.        8.000
          0x6              256           62.5      16.000
          0x7             1024           15.625    64.000

For better timing resolution, you use a value called TCNT2. There is build in counter that goes from 0 to 255 because the timer is 8 bit. When the counter reaches the value assigned by TCNT2 it triggers an interrupt. This interrupt is called TIMER2_OVF_vect.

given this information, the resulting interrupt rate would be: 16MHz / (prescaler * (255 - TCNT2))

You could get the timer to run at the full 16MHz (62.5nSec) though that's way faster than you need; 2MHz with an initial count of (255-2) would give you 1MHz interrupt rate. Divide that by 2 in your ISR:

extern uint32_t MicroSecClock = 0;

ISR(TIMER2_OVF_vect) {// this is a built in function that gets called when the timer gets to the overflow counter number
  static uint_8 count;            // interrupt counter

  if( (++count & 0x01) == 0 )     // bump the interrupt counter
    ++MicroSecClock;              // & count uSec every other time.

  digitalWrite(53,toggle);// pin 53 is arbitrary
  TCNT2 = 253;                    // this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
  TIFR2 = 0x00;                   // clear timer overflow flag
};

The data sheet for your MCU is the basic resource; this article will give you (and gave me!) a good head-start.

2 of 3
4

If dropping down to AVR Level is acceptable (as you mentioned in your question), you can set up a timer and even get the ticks of the AVR's clock.

You need to refer to your AVR's datasheet because it differs within the different ATMegas and ATTinys. But the procedure is always the same. What you need to do is:

  • decide which prescaler to use (for example set it to 1, i.e. no prescaling if you want the actual CPU clock speed), refer to the TCCR documentation
  • set up a timer overflow interrupt, an interrupt handler and activate interrupts globally
  • activate the timer in the Timer/Counter Control Register TCCR

That way can get the exact ticks from the timer register, however you need to count the overflows manually. This is as precise as possible by technology.

Here is some example code for the outdated AT90S2313, but it gives you good hints what to do basically:

/* uC: AT90S2313 */
#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
  // set up timer 0
  TCCR0 = (1<<CS01); // Prescaler 8

  // enable overflow interrupt
  TIMSK |= (1<<TOIE0);

  // activate interrupts
  sei();

  while(1)
  {
     /* Do whatever you like */
  }
}


ISR (TIMER0_OVF_vect)
{    
   /*
      This gets called everytime there in an overflow in the timer register  
   */
}
🌐
ElectricRCAircraftGuy
electricrcaircraftguy.com › 2014 › 02 › Timer2Counter-more-precise-Arduino-micros-function.html
ElectricRCAircraftGuy.com--RC, Arduino, Programming, & Electronics: Arduino micros() function with 0.5us precision - using my Timer2_Counter Library
February 9, 2014 - ...merging the world of Arduino and Radio Control, one tool at a time... ...CODE FOR A PRECISE MICROS() FUNCTION IS POSTED BELOW... "I wrote a libary to get 0.5us precision on a "micros()" replacement function, so that I can get repeatable results reading a PWM or PPM signal, to within 1us.