How to Use Arduino Interrupts
Table of Contents
Interrupt is extremely useful when dealing with all kinds of processes that need attention at unexpected times or when expecting a certain event or signal at indefinite and unknown times.
For example, you send a chat message to your crush. You are very excited but also nervous. So every second you are checking your messenger if she already replied. This is tiring and it takes most of your time and energy. You will not be able to do other important tasks and responsibilities. In microcontroller jargon, it is called polling.
What you can do is to turn on the notification and go on with your normal life, do your chores and routines. When someone sends you a chat message, you will hear a notification sound. That is the time for you to check your mobile phone.
The notification sound serves as interrupt call and checking of mobile phone is the Interrupt Service Routine. Efficient, right?
So how does the interrupt really work?
When an event occurs which triggers the interrupt, the current process will be put on hold and the ISR or Interrupt Service Routine will be executed. All other interrupts will be disabled.
When the ISR finishes executing, the previous process before the interrupt will continue and all other interrupts will be re-enabled.
It is highly recommended to make the ISR as short as possible because an ISR that takes, let's say, 5 seconds to execute, means 5 seconds of uncertainty. WHY? Because all other processes are disabled during ISR execution. As a rule of thumb, just set a variable flag or save a sensor value inside the ISR and do the other remaining processes inside the main loop.
There are two kinds of interrupt:
Internal interrupt - or software interrupt, is triggered by internal peripherals like timers.
External interrupt - or hardware interrupt, is triggered by an external device.
External Interrupt pins:
Board | Interrupt Pins |
---|---|
Arduino Uno | 2, 3 |
Arduino Nano | 2, 3 |
Arduino Mini | 2, 3 |
Arduino Mega | 2, 3, 18, 19, 20, 21 |
How to set interrupt:
attachInterrupt(INTERRUPT_NUM, ISR_FUNCTION, TRIGGER_MODE)
INTERRUPT_NUM
- is the interrupt number associated with the interrupt pin.
ISR_FUNCTION
- is the ISR function to be executed when the interrupt is detected.
TRIGGER_MODE
- is the type of detection of interrupt. It could be RISING, FALLING, CHANGE, or LOW.
RISING
- triggers when the pin goes from low to high.
FALLING
- triggers when the pin goes from high to low.
CHANGE
- triggers whenever the pin changes value.
LOW
- triggers when the pin is low.
Keep in mind the following rules when using interrupts:
- Keep it short. As discussed earlier.
- Do not use delay functions, as it prolongs ISR execution.
- Do not use serial inside ISR, as it can interfere with interrupt handling.
- Make global variables volatile. This is per C standard; variables should be declared volatile when used outside the normal execution flow (outside the main loop, which is the ISR function). Volatile disables variable optimization.
VIDEO DEMONSTRATION
SOURCE CODE
#define INTERRUPT_PIN 2
#define INDICATOR_PIN 3
volatile int LED_state = 1;
void setup() {
// put your setup code here, to run once:
pinMode(INTERRUPT_PIN, INPUT);
pinMode(INDICATOR_PIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), Button_ISR, RISING);
}
void loop() {
// put your main code here, to run repeatedly:
}
void Button_ISR () {
LED_state = !LED_state;
digitalWrite(INDICATOR_PIN, LED_state);
}
CALL TO ACTION
If you found this tutorial useful, kindly share this to your friends.
Thank you and have a good day.