What are interrupts in Arduino, and how are they used?


Interrupts in Arduino allow the microcontroller to immediately respond to external or internal events without constantly polling (checking) inputs. They pause the normal program flow, execute a special function (ISR), and then resume the original task.
1. Types of Interrupts in Arduino
A. Hardware Interrupts
Triggered by external signals (e.g., button press, sensor pulse).
Supported on specific pins (varies by board):
Arduino Uno/Nano: Pins
2
and3
(INT0
,INT1
).Arduino Mega: Pins
2, 3, 18, 19, 20, 21
.ESP32/ESP8266: Almost any GPIO supports interrupts.
B. Software Interrupts
Triggered by internal events (timers, ADC conversions).
Example:
timer1
interrupt for periodic tasks.
2. How to Use Interrupts in Arduino?
Step 1: Attach an Interrupt
Use attachInterrupt()
to link a pin to an ISR (Interrupt Service Routine).
cpp
void setup() {
pinMode(2, INPUT_PULLUP); // Interrupt pin (e.g., button)
attachInterrupt(
digitalPinToInterrupt(2), // Interrupt pin (2 on Uno)
buttonPressed, // ISR function name
FALLING // Trigger mode
);
}
Step 2: Define the ISR
Keep ISRs short and fast (no delay()
, Serial.print()
).
cpp
volatile bool buttonFlag = false; // 'volatile' for safe ISR access
void buttonPressed() {
buttonFlag = true; // Signal main loop
}
void loop() {
if (buttonFlag) {
// Handle the interrupt event
buttonFlag = false;
}
}
3. Interrupt Trigger Modes
Mode | Description |
LOW | Triggers when pin is LOW. |
CHANGE | Triggers on any voltage change (LOW→HIGH or HIGH→LOW). |
RISING | Triggers when pin goes from LOW → HIGH. |
FALLING | Triggers when pin goes from HIGH → LOW. |
4. Practical Applications
Button Press Detection (Avoid debouncing in ISR; use flags).
Encoder Reading (Fast pulse counting).
Wake from Sleep (ESP32 deep sleep wakeup via external interrupt).
Sensor Triggers (PIR motion sensors, ultrasonic echoes).
5. Important Rules for ISRs
✔ Use volatile
variables for shared data.
✔ Avoid delays, I/O operations (Serial
, millis()
).
✔ Disable interrupts briefly if needed (noInterrupts()
/ interrupts()
).
6. Example: RPM Measurement (Hardware Interrupt)
cpp
volatile unsigned long pulseCount = 0;
void countPulse() {
pulseCount++;
}
void setup() {
attachInterrupt(digitalPinToInterrupt(2), countPulse, RISING);
}
void loop() {
unsigned long rpm = (pulseCount / 2) * 60; // 2 pulses per rotation
pulseCount = 0;
delay(1000); // Update every second
}
7. Disabling Interrupts
cpp
noInterrupts(); // Disable all interrupts
// Critical code (e.g., timing-sensitive)
interrupts(); // Re-enable
Conclusion
Hardware interrupts are ideal for real-time events (buttons, sensors).
Keep ISRs minimal for stability.
Use flags to communicate with
loop()
.
Subscribe to my newsletter
Read articles from ampheo directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
