
Interrupts are used to handle events that do not happen during the normal execution of a program, but when a specific trigger occurs. For example, if we write a program to blink an LED, the microcontroller will execute each command one by one. But if we want to monitor a switch to start or stop the blinking, it will only be possible after all other tasks before the checking are completed, i.e., it won’t be real-time. That’s where interrupts come into play. With an interrupt, we do not need to continuously check the state of the digital input pin. When an interrupt occurs, the controller stops the execution of the main program, and a function is called upon known as ISR or the Interrupt Service Routine. The controller then executes the tasks inside the ISR and then gets back to the main program after the ISR execution is finished.
LED Control Using ESP32 GPIO Interrupt - Quick Overview
Build Time: 1-2 hours | Cost: $10-20 | Difficulty: Beginner
What You'll Learn: ESP32 GPIO interrupts, ISR programming, Digital I/O, Debouncing
Applications: Button-based LED control, Home automation, Event-driven systems, Real-time input monitoring
Table of Contents
- What are ESP32 Interrupts and How Do They Work?
- └ ESP32 Interrupt Pins and Capabilities
- Types of Interrupts in ESP32
- └ External or Hardware Interrupts
- └ Software Interrupts
- Commonly Asked Questions
- Pins and GPIO Configuration
- └ Using attachInterrupt() Function
- How to Disable ESP32 Interrupts?
- └ Interrupt Service Routine or ISR
- └ Practical ESP32 GPIO Interrupt Example
- ESP32 Touch Interrupt Implementation
- Programming Best Practices
- Troubleshooting Guide
- GitHub Repository
- Related Projects
What are ESP32 Interrupts and How Do They Work?
ESP32 interrupt classification is based on interrupt sources, leading to a distinction between hardware interrupts and software interrupts, essential knowledge for programming interrupts on the ESP32.
ESP32 Interrupt Pins and Capabilities
Pin Type | Pin Numbers | Interrupt Support | Special Features |
---|---|---|---|
All GPIO Pins | GPIO 0-39 | Digital Interrupt | Rising, Falling, Change, Low, High |
Touch Pins | GPIO 0, 2, 4, 12-15, 27, 32-33 | Touch Interrupt | Capacitive touch detection |
ADC Pins | GPIO 32-39 | Digital Interrupt | Analog + digital capability |
RTC Pins | GPIO 0, 2, 4, 12-15, 25-27, 32-39 | Wake-up Interrupt | Deep sleep wake-up support |
Types of Interrupts in ESP32
ESP32 interrupt classification depends primarily on interrupt sources, divided into hardware interrupts and software interrupts, for comprehensive ESP32 interrupt programming. All ESP32 interrupt pins can generate GPIO interrupts, and 10 of these pins can also provide touch interrupt capabilities.
External or Hardware Interrupts
Hardware interrupts occur in response to an external hardware event. For example, there is a Touch Interrupt, which happens when touch is detected and a GPIO interrupt when the state of a GPIO pin is changed. GPIO interrupts and touch interrupts come under this category. All ESP32 interrupt pins support GPIO interrupts, with 10 pins additionally supporting touch interrupt functionality. Timer interrupts are an example of the software interrupts described earlier in ESP32 interrupt programming; timer interrupts allow exhaustive timing control over applications that require operations to be scheduled on a "when" necessary basis.
Software Interrupts
This type of interrupt occurs when a software event is triggered, such as a timer overflow. Timer interrupts are an example of software interrupts. We will discuss more about Timers in the upcoming dedicated tutorial for ESP32 Timers.
Commonly Asked Questions about ESP32 Interrupts
⇥ How many interrupts can ESP32 handle?
The ESP32 offers up to 32 interrupt slots for each core.
⇥ How to use the external interrupt in ESP32?
You can attach the desired pin to an interrupt and assign an ISR for the same with the help of the attachInterrupt function.
⇥ In ESP32, which pins support an External interrupt?
All of them support GPIO interrupt, and 10 of them support touch interrupt.
⇥ What are the GPIO interrupt modes ESP32 have?
ESP32 has five types of interrupt events and are LOW, HIGH, CHANGE, FALLING, and RISING.
⇥ What pins on ESP32 are interrupt-capable and can drive external interrupts?
ESP32 GPIO pins have support for GPIO interrupts, which offers flexibility with interrupt-based applications. Ten of these pins will also have capacitive touch interrupts, GPIO 0, 2, 4, 12-15, 27 (touch pin), 32-33 (touch pins).
⇥ Can interrupts in ESP32 wake it from deep sleep mode?
Yes, ESP32 has deep sleep external interrupt capability on selected pins (RTC_GIO). When in deep sleep, touch interrupts, timer interrupts, or the ULP coprocessor can wake up the ESP32 to conserve battery power.
ESP32 Interrupt Pins and GPIO Configuration
Basics for ESP32 GPIO Interrupt Programming
ESP32 GPIO interrupts can be configured so that any GPIO pin can act as a hardware interrupt signal source. To enable interrupts on specific pins, the pins are wired to an associated ISR function with the ESP32 attachInterrupt function. This allows you to handle interrupts as needed and as flexibly as you want from all available ESP32 interrupt pins.
Using attachInterrupt() Function for ESP32
With ESP32, we can configure all the GPIO pins as hardware interrupt sources. We can enable an interrupt on any of these GPIO pins by attaching them to a corresponding ISR. To attach an interrupt, we will use the attachInterrupt () macro. The usage of the attachInterrupt() macro is as follows-
attachInterrupt(GPIOpin, ISR, Event);
The attachInterrupt() function takes in three arguments:
GPIOpin: This parameter indicates the GPIO PIN to which the interrupt is to be attached.
ISR: The second parameter is the name of the function that will be called every time the interrupt is triggered.
Event: The third parameter indicates at which event the interrupt should be triggered. The five possible events are the following.
LOW: Triggers interrupt whenever the pin is LOW
HIGH: Triggers interrupt whenever the pin is HIGH
CHANGE: Triggers interrupt whenever the pin changes value, from HIGH to LOW or LOW to HIGH
FALLING: Triggers interrupt when the pin goes from HIGH to LOW
RISING: Triggers interrupt when the pin goes from LOW to HIGH
So, for example, to trigger an interrupt whenever the state of GPIO4 changes, we can use the attachInterrupt function as follows:
attachInterrupt(4, ISR, CHANGE);
How to Disable ESP32 Interrupts?
In some situations, we will have to disable the interrupt temporarily. For such cases, we can use the detachInterrupt function. Once this function is called for a specific pin, the interrupt that is attached to that pin will be disabled until the attachInterrupt function is called again or the system is rebooted. The syntax for using it is as follows-
detachInterrupt(GPIOPin);
Interrupt Service Routine or ISR
This will be the function that will be called upon when the specific interrupt is triggered. The syntax is as follows:
void IRAM_ATTR ISR() {
Statements;
}
Where ISR is the function name, and the statements are the tasks that should be completed when this function is called. Since the ISR is blocking the main program, it is recommended to use it to do tasks that are as small as possible. The parameter IRAM_ATTR will ensure that the ISR function is placed in the IRAM area instead of the flash area. This will ensure that the ISR function loads faster.
Practical ESP32 GPIO Interrupt Example
LED Control Using ESP32 GPIO Interrupt
In this example, we will turn on and off an LED with a push-button switch. But instead of using polling, we will be using the GPIO interrupt. To do that, make the connections on a breadboard as shown in the circuit diagram below.
This demonstration provided a practical example of using ESP32 interrupt programming to control an LED with a push button input. This implementation demonstrates the correct usage of ESP32 attachInterrupt for real-world examples.
Here is the actual circuit connected on a breadboard as per the circuit diagram.
This code demonstrates efficient ESP32 GPIO interrupt implementation where button press triggers LED state changes without polling, showcasing the power of interrupt ESP32 programming.
#define pushButton_pin 33
#define LED_pin 32
void IRAM_ATTR toggleLED()
{
digitalWrite(LED_pin, !digitalRead(LED_pin));
}
void setup()
{
pinMode(LED_pin, OUTPUT);
pinMode(pushButton_pin, INPUT_PULLUP);
attachInterrupt(pushButton_pin, toggleLED, RISING);
}
void loop()
{
}
As soon as the pushbutton is pressed, the voltage at GPIO33 will fall to 0V. And when the button is released, the voltage will rise to VCC. When the voltage is rising, the interrupt will be triggered, and the corresponding ISR toggleLED will be called. Because the ISR will be only triggered at the rising edge, the debouncing will be eliminated.
ESP32 Touch Interrupt Implementation
Just like the GPIO interrupt, the ESP32 supports touch Interrupts on its 10 touch inputs. Using the touch interrupt is also similar. To attach a touch interrupt, we will use the touchAttachInterrupt function. Its syntax is as follows:
touchAttachInterrupt(GPIOPin, ISR, Threshold)
Here, the GPIOPin is the pin with touch input support and the ISR is the ISR function, and the Threshold is the touch value at which the interrupt should be triggered. Everything else is the same as the GPIO interrupt example.
Best Practices for ESP32 Interrupt Programming
Working with ESP32 interrupts can be a complex activity with interrupt priorities, multiple interrupts at the same time, and optimising the performance of your Interrupt Service Routines (ISRs); however, this is dead simple when successfully carried out. If interrupts are implemented correctly, you can expect your system to work correctly on all ESP32 interrupt pins without concerns about your system's response.
» Keep ISR functions fast and minimal for the best interrupt ESP32 performance
» Use the IRAM_ATTR directive for ALL ISR functions associated with ESP32 GPIO interrupts
» Do not use delay functions in the ISR code in ESP32 interrupt programming
» Use proper debouncing with mechanical switches attached to ESP32 interrupt pins
» Thoroughly test the interrupt functionality before deploying the system
ESP32 Interrupts Troubleshooting Guide
∗ Check pin configuration pinMode() for input (INPUT, INPUT_PULLUP)
∗ Check the pin in attachInterrupt for syntactical errors
∗ Check the syntax for attachInterrupt ISR
∗ Check the PIN passed into attachInterrupt, the ISR name and the trigger
∗ Add in IRAM_ATTR in front of the ISR function declaration
∗ Check hardware connections: wiring, pull-up/pull-down resistors
∗ Check triggering conditions: confirm signal - 0V/3.3V (check voltage threshold)
∗ Don't use blocking function: don't use delay(), Serial.print() in ISR.
∗ Check for conflicting interrupt resources: check other peripherals that are using that pin.
Technical Summary and GitHub Repository
The Technical Summary contains the basic design and working principles of the project, giving a brief technical summary. It is a short reference to understand how the system works and how it has been implemented. The linked GitHub repository contains all source code, schematics and documentation required when replicating or customising the system.
Projects Using ESP32 and Interrupts
There are some interesting projects done with the ESP32 and its Interrupt feature. If you want to know more about those topics, links are given below-
ESP32 Active Mode and Deep Sleep Mode Power Consumption
In this project, we will check the current consumption of the widely popular Wi-Fi and Bluetooth-enabled microcontroller unit ESP32 in normal working mode and deep sleep mode.
Biometric Attendance System with Google Sheet Integration
We built a Biometric Attendance System using ESP32 and OLED Display Module, which can store the attendance records in Google Sheets.