Electronic – arduino – How does the Arduino NANO deal with simultaneous external interrupts

arduinointerrupts

I am a beginner with Arduino NANO and this is something I've been trying to figure out for a few hours now. Say, in setup(), I have the following snippet of code:

pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), do_this, RISING);
pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(3), do_that, RISING);

and there are two ISR functions do_this() and do_that() that are called when two push-button switches are pressed. I understand how the program is supposed to behave when the switches are pushed and released separately. But, what if the RISING action happens, hypothetically, at the same point in time? (Actually, if digital pin 2 and 3 are connected to the same push-button then the 'stimulus', so to speak, will occur at the exact same moment). Which one of the ISRs, if any, will take precedence in this case? I have checked the ATMega328 datasheet, but have not been able to come up with anything satisfactory.

Thanks in advance 🙂

Edit: Thanks for the detailed insights. I understand that the ISRs have priorities and even if the change is triggered at the same time, the ISRs will be executed one after another depending according to the said priority.

As for the push-button part of the question, I came to the conclusion that when the two interrupt pins are connected together through the push-button, pressing the switch does not trigger any change because one of the External Interrupt Flags gets cleared by the other. I know that's a rough conclusion and I am probably missing a lot of technical nuances but is that idea at least correct? Many thanks

Best Answer

Contrary to anther answer, two interrupts can happen at exactly the same time as far as the microcontroller is concerned. This is because the MCUs concept of time is its clock signal. Anything that happens after one clock edge and before the next clock edge happened at the exactly the same time as far as the MCU is concerned.

What happens when two sources fire simultaneously depends on the microcontrollers interrupt handler design, and whether or not it is doing something else.


In the case of an AVR, if two different interrupt sources happen at the same time, the one that gets processed first depends on its hardware priority. This is typically whichever comes first in the interrupt vector table. The first interrupt handler will be called, any other interrupts will still set their corresponding hardware flag, but will not immediately trigger their interrupt handler (unless you call sei in an ISR, which is bad for many reasons).

Once the current ISR returns (reti instruction), the hardware flag for that interrupt source will be cleared. This means that if, say, while INT0 was being handled INT0 happened again, it would be ignored, because the flag gets cleared on return.

If after the ISR has returned, one or more hardware interrupt flag for other sources are set, the same process will repeat, with the source being executed whichever has the highest hardware priority.


In the case of the Arduino Nano, Digital 2 corresponds to INT0, whilst Digital 3 corresponds to INT1. In the ATMega328, INT0 has priority over INT1, so if both sources occurred during the exact same clock cycle, then do_this would happen first.

If however INT1 occurred a clock cycle before INT0, then do_that would in theory happen first. However as there are other interrupts at play, such as the timer 0 interrupt used for the millis() function which complicates things. If INT1 happened before INT0, but both happened whilst the ISR for Timer 0 was being handled, then do_this would happen first because on return from the timer ISR, it would have priority.