So I know that millis() doesn't work how it's suppose to if you use it in an interrupt but lets say we have a code that looks like below, will millis() work properly or how it behaves in an interrupt? Do I need to use the delay() instead of millis() when I'm outside of void loop() ?

To clarify, I understand how millis() behaves in an interrupt and why delay() doesn't work in an interrupt.

const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;   

void setup() {
 pinMode(ledPin, OUTPUT);
void loop(){
void blink(){
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  • 2
    That is good code. You can use many more of those functions with different leds and different intervals, but each should have its own previousMillis variable. The interval can be an int or a long, but you can also make it an unsigned long, then the compiler does not have to convert it to unsigned long. Using millis in an interrupt can be used to remember the time, for example as a timestamp to decode a certain timing protocol. But don't use delay in a interrupt and don't use millis to create a delay in a interrupt.
    – Jot
    Mar 23, 2018 at 0:53
  • So the millis() will work fine in the void blink() ? it's not like an interrupt where the millis() is the last millis() used in the regular void loop() ?
    – Brit
    Mar 23, 2018 at 1:07
  • 1
    It will work fine. I don't understand your second question. The way you use millis in the sketch is checking if enough time has passed since the previousMillis, that is how to use millis. There is no waiting, no delay, the led is changed when it is time to do so.
    – Jot
    Mar 23, 2018 at 1:16
  • I think I'm confused with the term interrupt vs function, like void blink() isn't considered an interrupt is it? is an interrupt only when I actually declare it?
    – Brit
    Mar 23, 2018 at 1:22
  • Your blink function is a normal function. Everything that is called from the loop function is a normal function. An interrupt function is for example with the function attachInterrupt arduino.cc/reference/en/language/functions/external-interrupts/…
    – Jot
    Mar 23, 2018 at 1:41

1 Answer 1


Millis is driven by an interrupt. The reason it doesn't "work" from inside an interrupt is that you can't have two interrupts running at the same time. So when your interrupt is running the interrupt that makes millis count can't run.

Millis does work in an interrupt as long as all you want is to record a single point in time. If you do anything that relies on millis changing within the lifetime of the interrupt it will break. That is why delay is bad in interrupts.

So from that you can see that it's only when in an interrupt that things can go awry. Everywhere else, as long as interrupts are enabled, both millis and delay work fine.

After all, loop is just a function called by main, and main is just a function called by _startup... Etc...

  • Although that is a nice explanation of an interrupt my question isn't about what an interrupt does. To clarify is void blink() behaving as an interrupt or does something only behave as an interrupt when you declare it?
    – Brit
    Mar 23, 2018 at 1:23
  • Something only behaves like an interrupt when it is called by an interrupt. Blink is just a function. Like loop. Like millis. Like delay. Like setup. They are all just functions. Only interrupts are interrupts.
    – Majenko
    Mar 23, 2018 at 1:25
  • so it's only considered a interrupt only when i use attachInterrupt() right? so then in the void blink() function about millis() works fine, it doesn't behave like the way it would in an interrupt correct?
    – Brit
    Mar 23, 2018 at 1:26
  • An interrupt is a context not a function. A separate thread of execution if you like.
    – Majenko
    Mar 23, 2018 at 1:26
  • Only if you called blink from an interrupt would it behave like an interrupt.
    – Majenko
    Mar 23, 2018 at 1:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.