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

ampheoampheo
3 min read

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 and 3 (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

ModeDescription
LOWTriggers when pin is LOW.
CHANGETriggers on any voltage change (LOW→HIGH or HIGH→LOW).
RISINGTriggers when pin goes from LOW → HIGH.
FALLINGTriggers when pin goes from HIGH → LOW.

4. Practical Applications

  1. Button Press Detection (Avoid debouncing in ISR; use flags).

  2. Encoder Reading (Fast pulse counting).

  3. Wake from Sleep (ESP32 deep sleep wakeup via external interrupt).

  4. 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().

0
Subscribe to my newsletter

Read articles from ampheo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ampheo
ampheo