1

Using the delay function inside of an ISR is frowned upon when programming in an Arduino. The general response to solve this desire is to design the program to delay in a more cleanly way outside of the interrupt.

My question is simply why. Why does putting a delay() inside of an ISR cause wonky behavior with the Arduino. Whats going on under the hood?

3

Why is putting a delay() inside of an ISR cause wonky behavior with the Arduino. Whats going on under the hood?

The first problem is that delay() is a busy loop monitoring millis(). The value that millis() returns will not change inside an ISR as interrupts are turned off inside an ISR; this is why ISRs must be as short and fast as possible, or they will interfere with other interupts

So if you call delay() within an ISR your poor AVR is now deadlocked! It is waiting for something to happen that can now never happen.

A second problem is that if your ISR takes too long, you can miss other interrupts; millis() and micros() can miss ticks and become inaccurate!

0

Because a delay inside an interrupt causes that interrupt and other (lower priority) interrupts not to execute anymore until the delay is over.

Assume in an ISR you handle the incoming bytes from a UART. If you add a delay in the ISR, and the buffer of the UART gets full, it will overflow and you miss bytes.

0

This is an addition to esoterik's answer.

Most of the times, that people try to use delay() inside an ISR it is a poor design choice to even use it in a general way, that will lead to the described problems (waiting forever or missing other interrupts). delay() is a simple function mainly for beginners with very simple programs. It is a simple starting point. Mostly the use of it in any program is not a good choice, since you are busy waiting without being able to do something else (like responding to user input). There are better ways, involving millis() itself, that keep your program extendable (so that, if you want to add a functionality, this will not be blocked by the first part of the code). And when your program reaches the complexity of using own ISRs, you should avoid delay(), unless you really know, what you are doing.

IMO at some (rather early) point, every Arduino programmer has to learn how to use millis() to do timed code execution. You can look at the BlinkWithoutDelay example, that comes with the Arduino IDE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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