The millis() function only reads the variables already accumulated by the Timer0 overflow ISR and just returns their values. The micros() function reads the current counter value of Timer0 and calculates the elapsed time, because return value need even higher time resolution. Therefore, the execut… Answer from chrisknightley on forum.arduino.cc
🌐
Arduino
arduino.cc › en › Reference › micros
micros() | Arduino Documentation
June 5, 2025 - This function returns the number of microseconds since the Arduino board began running the current program.
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Why is micros() so much slower than millis()? - Programming - Arduino Forum
August 18, 2021 - I set up a sketch to test the hz of the main loop with millis() vs micros(). With millis() hz was giving a reading between 288,935 and 289,232 but with micros is was reading 174,730 which is substantially slower. Is is just because the arduino has to deal with bigger numbers or because it has ...
Discussions

Don't use millis() or micros(), or delay() or even delayMicroseconds() in your project
If you are doing a continuous use project, don't use millis() or micros(), or delay() or even delayMicroseconds() in your project, because the variable will experience a count reset (overflow), instead, use some timer or operating system. Automatically handles micros() and millis() overflows ... More on forum.arduino.cc
🌐 forum.arduino.cc
19
0
August 2, 2022
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
Arduino Micros() Question
All - I understand there are better places to ask questions referring to Arduinos than CD, although I have had good experiences in the past on CD, and also lack accounts to other popular technical forums. I am using a sensor to track data, and I am trying to be precise as possible. More on chiefdelphi.com
🌐 chiefdelphi.com
1
1
June 8, 2022
Using micros() over a lo..ng time?
I need to make a 10 ms one-shot. I thought about using a timer, but just about every page I go to use micros(). The problem is, that my code will run for a long time, and micros() will start over every 70 minutes or so. Meaning: Should I happen to start my one-shot just prior to the restart, ... More on forum.arduino.cc
🌐 forum.arduino.cc
19
0
March 31, 2022
🌐
The Robotics Back-End
roboticsbackend.com › home › arduino millis() vs micros()
Arduino millis() vs micros() - The Robotics Back-End
October 11, 2021 - The resolution for micros() is 4 microseconds on all 16MHz Arduino boards: Uno, Mega, Nano, etc. For example, if you read the time with micros() and get 10000, then the next value you get is 10004, and after that 10008, and so on.
🌐
Arduino Forum
forum.arduino.cc › community › general discussion
Don't use millis() or micros(), or delay() or even ...
August 2, 2022 - If you are doing a continuous use project, don't use millis() or micros(), or delay() or even delayMicroseconds() in your project, because the variable will experience a count reset (overflow), instead, use some timer or operating system. Automatically handles micros() and millis() overflows ...
🌐
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 ...
🌐
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.
Find elsewhere
🌐
Norwegian Creations
norwegiancreations.com › 2018 › 10 › arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros
Arduino Tutorial: Avoiding the Overflow Issue When Using millis() and micros() – Norwegian Creations
October 11, 2018 - What’s nice is that we don’t have to worry about this at all. Since both inputs to the calculation are of the unsigned long data type, the answer will also be an unsigned long, and thus the result will overflow in line with the return value of millis(). Remember that both millis() and micros() return unsigned long.
🌐
Arduino
store-usa.arduino.cc › collections › arduino micro
Arduino Micro with Headers | Compact USB Dev Board — Arduino Online Shop
Arduino Micro
Explore the Arduino Micro – a compact ATmega32u4 board with native USB support. Ideal for portable projects, HID devices, and fast prototyping. The Micro is a microcontroller board based on the ATmega32U4 (datasheet), developed in conjunction with Adafruit. It has 20 digital input/output pins (of which 7 can be used as PWM outputs and 12 as analog inputs), a 16 MHz crystal oscillator, a micro USB connection, an ICSP header, and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a micro USB cable to get started. It has a form facto
Rating: 4.6 ​
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.

🌐
Arduino Forum
forum.arduino.cc › projects › programming
Using micros() over a lo..ng time? - Programming - Arduino Forum
March 31, 2022 - I need to make a 10 ms one-shot. I thought about using a timer, but just about every page I go to use micros(). The problem is, that my code will run for a long time, and micros() will start over every 70 minutes or so. Meaning: Should I happen to start my one-shot just prior to the restart, ...
🌐
Reddit
reddit.com › r/arduino › using micros() as a source of random numbers
r/arduino on Reddit: Using micros() as a source of random numbers
December 8, 2023 -

I want a source of semi-random numbers for a dice-roller. I did consider using the random() and randomseed() functions but instead I decided to try and take the output of micros() when a button is pressed and just use the least significant digit.

This means I get a long number and have to throw away everything except for the one or two least significant digits. But does anyone know how to do that? If it was all in binary then it'd be easy as I could just AND the number with zeros to dispose of unwanted elements but in a raw long it's more tricky. I did consider converting the long to binary but I'm not 100% sure how to.

Does anyone have any advice?

🌐
Arduino Forum
forum.arduino.cc › official hardware › mega › due
Arduino Due micros() resolution - Due - Arduino Forum
May 16, 2013 - I haven't been able to find a definitive answer to this question. If the prescaler is 64 in the stock Arduino code, thereby making the micros() resolution on 16Mhz boards 4uS, would that make the 84Mhz Due micros() resolution about 0.762uS or 1uS?
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Doubt about the micros() function! - Programming - Arduino Forum
August 16, 2011 - I have an Arduino program that do some functions, control a dc motor and display some informations on the serial monitor, and one of them is the time difference of some readings of a light sensor. So, I have this piece of code that calculates the time difference: void info() { tempo = micros(); tempo = micros() - tempo; Serial.print("LDR 1: "); Serial.print(valor1); Serial.print(" LDR2: "); Serial.print(valor2); Serial.print(" Erro: "); Serial.print(dif); Serial.print...
🌐
Arduino Forum
forum.arduino.cc › projects › programming
Question about the "micros()" function - Programming - Arduino Forum
September 8, 2015 - Hi all, I'm running a "custom" Arduino board (with a MEGA2560 mcu) using a 22.1184 MHz. crystal instead of 16.000 I wrote a small test program to try to read the timing of received IR pulses and found that the readings were low by about a factor of about 1.3 Interestingly, the ratio between 22.1184 and 16.000 is also about 1.3 which leads me to ask: Is the [b]micros()[/b] function "hard coded" for a 16.0 MHz clock or does it account for F_CPU?
🌐
Arduino Forum
forum.arduino.cc › projects › programming
(Uno) My micros() function drifts horribly - Programming - Arduino Forum
November 29, 2022 - unsigned long m = 0; int second = 1; void setup() { Serial.begin(115200); } void loop() { m = micros(); if(m>second*1000000) { Serial.println(m); second++; } } Results in being an entire second too slo…
🌐
Zbotic
zbotic.in › home › arduino timer tutorial: millis(), micros() & hardware timers
Arduino Timer Tutorial: millis(), micros() & Hardware - Zbotic
March 11, 2026 - On a 16 MHz Arduino Uno, millis() has a resolution of approximately 1.024 ms (due to Timer0 prescaler settings). It does not tick exactly every 1.000 ms — there’s a small accumulated drift. For timing requirements tighter than ~1 ms, use micros() which has 4 µs resolution.