Interrupts are signals that pause the normal execution of an [Arduino](https://www.ampheo.com/c/development-board-arduino) program to handle urgent events (like a button press or sensor trigger) immediately. They allow the [microcontroller](https://www.ampheo.com/c/microcontrollers) (e.g., [ATmega328P](https://www.ampheo.com/search/ATmega328P) in [Arduino Uno](https://www.ampheo.com/product/a000046-25542493)) to respond to external or internal events without constant polling, saving power and CPU time.

**Types of Interrupts in Arduino**
**1. External Interrupts**
Triggered by hardware pins (e.g., a button press).
Supported pins (varies by board):
* Arduino Uno/[Arduino Nano](https://www.ampheo.com/product/a000005-25542476): Pins 2 and 3 (INT0, INT1).
* [Arduino Mega](https://www.ampheo.com/product/a000067-25542697): Pins 2, 3, 18, 19, 20, 21.
**2. Pin Change Interrupts**
* Triggered by any pin state change (less immediate than external interrupts).
* Available on most pins but require more setup.
**3. Timer Interrupts**
Triggered by internal timers (e.g., periodic tasks like reading sensors).
**4. Software Interrupts**
Triggered by code (e.g., volatile flags).
**How to Use Interrupts in Arduino**
**1. Attach an Interrupt**
Use attachInterrupt() to link a pin to an Interrupt Service Routine (ISR).
```
cpp
void setup() {
pinMode(2, INPUT_PULLUP); // Button on pin 2 (with internal pull-up)
attachInterrupt(digitalPinToInterrupt(2), buttonPressed, FALLING);
}
void loop() {
// Main code runs uninterrupted
}
// ISR (Keep it short!)
void buttonPressed() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Toggle LED
}
```
**2. Interrupt Modes**
* RISING: Trigger when pin goes from LOW → HIGH.
* FALLING: Trigger when pin goes from HIGH → LOW.
* CHANGE: Trigger on any state change.
* LOW (Arduino-specific): Trigger while pin is LOW.
**3. Critical Notes**
* ISRs should be short (avoid delay(), Serial.print()).
* Use volatile for variables shared between ISR and main code:
```
cpp
volatile bool buttonFlag = false;
```
* Disable interrupts temporarily with noInterrupts()/interrupts() for critical sections.
**Example: Debouncing a Button with Interrupts**
```
cpp
volatile bool buttonPressed = false;
unsigned long lastInterruptTime = 0;
void setup() {
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), debounceInterrupt, FALLING);
}
void debounceInterrupt() {
if (millis() - lastInterruptTime > 200) { // 200ms debounce
buttonPressed = true;
}
lastInterruptTime = millis();
}
void loop() {
if (buttonPressed) {
// Handle button press
buttonPressed = false;
}
}
```
**When to Use Interrupts**
✔ Real-time events (e.g., emergency stop, rotary encoder pulses).
✔ Low-power applications (wake MCU from sleep on interrupt).
❌ Avoid for slow/complex tasks (use flags + loop() instead).
**Interrupts vs. Polling**

**Supported Arduino Boards**
* Uno/Nano: 2 external interrupts.
* Mega: 6 external interrupts.
* ESP32/8266: Nearly all pins support interrupts.
For advanced use (e.g., timer interrupts), see the TimerOne or PCINT libraries.