How to Use Arduino Interrupts to Detect User Inputs
2022-03-02 | By Maker.io Staff
Some Arduino programs need to react to specific important events in a timely manner. One example of such an event includes detecting button presses. Ideally, the Arduino should react to the input as soon as possible. However, reading the digital pin that the button is connected to repeatedly is not a good solution. A better way to accomplish this behavior is by using Arduino interrupts. This article discusses the different types of interrupts and how to use them in your custom Arduino programs.
The Two Types of Interrupts (and what they have in common)
On AVR-based development boards, such as the Arduino UNO, you can employ several interrupts in your custom Arduino sketches. Usually, you only use two, which are timer-interrupts and hardware-interrupts. You can learn more about the other types of interrupts and when the microcontroller (MCU) raises them in the datasheet of your Arduino's microcontroller.
Timer-interrupts are a fantastic way to avoid using the blocking delay()-function call in your Arduino program. Another article discusses the benefits and downsides of using timer-interrupts in your Arduino projects. The second type, called hardware-interrupts, allows you to react to external events that change the state of one of the Arduino’s General-Purpose Input/Output (GPIO) pins. Such events could be button presses, an external sensor signaling that it’s ready to read values, or the start of a data transmission sequence.
While you have to configure them differently, all interrupts work similarly. First, you define what event the hardware should listen for. In the case of timer-interrupts, which could be that a specified period has elapsed. For hardware interrupts, which could be a GPIO pin switching from HIGH to LOW. Then, tell the Arduino what to do once it detects this event. Typically, that would be a function call, which in this context is commonly referred to as an Interrupt Service Routine (ISR). Once the hardware detects the event, it automatically calls the ISR, and the MCU executes your custom code.
How to Define Hardware-Interrupts on an Arduino
First, it’s important to note that some Arduino boards cannot use interrupts on all of their GPIO pins. The following table shows which pins are available for interrupt detection on AVR Arduino boards. Please refer to the datasheet of your development board if you use a non-AVR board, for example, an ESP32, to find interrupt-capable pins.
Arduino Board/Digital pins usable for interrupts
- Uno, Nano, Mini, and other ATMega328-based boards - 2, 3
- Uno WiFi Rev. 2, Nano Every - All digital pins
- Mega, Mega2560, MegaADK - 2, 3, 18, 19, 20, 21 (20 and 21 are not available when they are used for I2C communication)
- Micro, Leonardo, and other 32u4-based boards - 0, 1, 2, 3, 7
- Zero - All digital pins, except 4
- MKR Family - 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
- Nano 33 IoT - 2, 3, 9, 10, 11, 13, A1, A5, A7
- Nano 33 BLE, Nano 33 BLE Sense - All pins
- Due - All digital pins
- 101 - All digital pins (only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE)
Once you determine which pins your Arduino can use for detecting interrupts, it’s time to create a custom ISR and attach an interrupt to one of the pins. In this example, I’ll use a standard Arduino Uno board. Therefore, I can define custom interrupts using digital pins two and three:
volatile bool execute = false; void setup() { pinMode(2, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(2), onDetectInterrupt, FALLING); } void onDetectInterrupt() { /* The Arduino calls this function when it detects a falling edge on pin 2. */ execute = true; } void loop() { /* Other code */ if(execute) { // Don't forget to reset the flag execute = false; } }
The first line in the setup()-method initializes digital pin two as an input, and it also uses the Arduino’s internal pull-up resistors. That means the pin remains in a HIGH state unless it’s actively connected to GND, for example, by pushing a button that pulls the pin LOW.
The next line in the setup()-function attaches an interrupt to pin two. Note how I set it to detect falling edges. The pin will normally be in a HIGH state unless pulled low, and when that happens, I want the Arduino to call a custom function to react to that state change. In this case, the custom function is the onDetectInterrupt()-method that you can find between the setup() and loop() functions. Here, I only set a single flag whenever the Arduino detects an input. The loop()-method takes care of all other tasks that should happen when the Arduino detects an interrupt.
Different Types of Events
In the example above, I instructed the Arduino to react to FALLING edges - that is, whenever the signal on digital pin two goes from HIGH to LOW. Alternatively, you can also use LOW, CHANGE, and RISING on all Arduino boards. The Due, Zero, and MKR1000 boards also have a HIGH mode.
LOW triggers the interrupt as long as the selected pin remains LOW. The HIGH option works analogously. CHANGE, FALLING, and RISING trigger the ISR whenever the selected pin’s state changes:
This diagram outlines when the Arduino calls an ISR depending on the selected mode. Red arrows indicate when the Arduino calls the ISR. The blue line represents a signal on digital pin two.
Summary
Interrupts are a great way to detect external events and make an Arduino react promptly. There are two types of interrupts, hardware interrupts and timer-interrupts. This article focused on hardware interrupts that are useful for detecting state changes on an Arduino’s digital input pins. Those changes can, for example, occur when a user presses a button that’s connected to the Arduino.
To create an interrupt, you first need to define a function that the Arduino can call whenever it detects an event. Then, you must tell the Arduino which pin to observe and what events you want it to recognize. In this article's example, I made the Arduino listen for a FALLING edge on digital pin two.
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum