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. ![Arduino-interrupts-example](https://hackmd.io/_uploads/Syw3bYVbxg.png) **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** ![企业微信截图_20250516170541](https://hackmd.io/_uploads/SJm-gtE-xg.png) **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.