100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Interrupts in Arduino

Use hardware interrupts to respond instantly to events without constant polling, with attachInterrupt(), trigger modes, volatile variables, and safe ISR design.

I/O & SensorsAdvanced10 min readJul 10, 2026
Analogies

Polling Versus Interrupts

In a normal sketch, loop() repeatedly checks inputs — this is polling. Polling is simple, but if your loop is busy doing other work it can miss a brief event, like a fast button press or a rotary encoder pulse. An interrupt flips the model: instead of asking 'has it happened yet?' over and over, the hardware notifies the processor the instant an event occurs, immediately pausing loop() to run a special function. This guarantees a timely response to critical or fast events and frees your main code from constantly watching a pin.

🏏

Cricket analogy: Polling is like a fielder glancing at the batsman every few seconds and possibly missing a quick single; an interrupt is like a slip fielder reacting the instant of the nick — notified immediately rather than checking on a schedule.

Attaching an Interrupt

You register an interrupt with attachInterrupt(digitalPinToInterrupt(pin), ISR, mode). The ISR (interrupt service routine) is a function you write that runs when the event fires. Not every pin supports interrupts: on the Uno only pins 2 and 3 do, while boards like the Mega or the 32-bit ATSAMD and ESP boards support many more. The mode argument defines the trigger: RISING fires on a LOW-to-HIGH transition, FALLING on HIGH-to-LOW, CHANGE on any transition, and LOW fires continuously while the pin is held low. Always wrap the pin number in digitalPinToInterrupt() for portability.

🏏

Cricket analogy: Choosing a trigger mode is like setting a fielding trap for a specific shot — RISING for one stroke, FALLING for another; attachInterrupt arms the response for exactly the event you expect, like a plan for a particular delivery.

cpp
const int buttonPin = 2;          // interrupt-capable pin on the Uno
volatile unsigned long pressCount = 0;
volatile bool newPress = false;

void handlePress() {              // the ISR: keep it short!
  pressCount++;
  newPress = true;
}

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), handlePress, FALLING);
}

void loop() {
  if (newPress) {                 // handle the event in loop(), not the ISR
    newPress = false;
    Serial.print("Presses: ");
    Serial.println(pressCount);
  }
}

Any variable shared between an ISR and the rest of your code must be declared volatile, or the compiler may cache it in a register and your main loop will never see updates the ISR makes. For multi-byte shared variables, disable interrupts briefly (noInterrupts()/interrupts()) while reading them to avoid reading a half-updated value.

Writing Safe Interrupt Service Routines

An ISR should be as short and fast as possible because it blocks everything else while it runs. Avoid delay() (it relies on interrupts and won't advance), avoid lengthy Serial prints, and don't expect millis() or micros() to increment inside an ISR since the timer interrupt that drives them is paused. The recommended pattern is to do the minimum in the ISR — set a volatile flag or increment a counter — and perform the real work back in loop() when it next runs. This keeps interrupts responsive and prevents subtle timing bugs.

🏏

Cricket analogy: A short ISR is like a wicketkeeper's split-second take then a quick throw — do the minimum instantly and defer the rest; you flag the event and let loop() do the heavy work, just as fielders complete the play afterward.

Interrupts are perfect for reacting to fast, sporadic events: rotary encoders, tachometers counting pulses, emergency stop buttons, and waking a sleeping board to save power. For slow or predictable timing, ordinary polling in loop() is usually simpler and perfectly adequate.

  • Polling checks inputs repeatedly; interrupts notify the CPU the instant an event occurs.
  • Register with attachInterrupt(digitalPinToInterrupt(pin), ISR, mode).
  • On the Uno only pins 2 and 3 support external interrupts; other boards support more.
  • Trigger modes are RISING, FALLING, CHANGE, and LOW.
  • Share data with the ISR using volatile variables.
  • Keep ISRs short: no delay(), no long Serial prints, and millis()/micros() don't advance inside them.
  • Set a flag in the ISR and do the real work back in loop().

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ArduinoProgrammingStudyNotes#InterruptsInArduino#Interrupts#Arduino#Polling#Versus#StudyNotes#SkillVeris#ExamPrep