Overview
An interrupt makes the processor pause the main program and run a short function (an interrupt service routine, ISR) the moment a pin changes. On the Uno, pins 2 and 3 support external interrupts. They suit events too short or too frequent to catch by polling: encoder pulses, fast sensors, wake-up signals.
You will need
- Arduino Uno R3
- Momentary pushbutton
- Jumper wires
Wiring
| Uno pin | Connects to | Notes |
|---|---|---|
| 2 | Button, one side | INPUT_PULLUP, interrupt on FALLING edge |
| GND | Button, other side |
Rules for ISRs
- Keep them short: set a flag or update a counter and return.
- Declare variables shared with the main program
volatile. - When reading a shared value larger than one byte, briefly disable interrupts so it cannot change halfway.
- Do not use
delay()orSerialprinting inside an ISR.
The sketch
const int BUTTON_PIN = 2; // pins 2 and 3 support interrupts on the Uno
volatile unsigned int pressCount = 0;
volatile unsigned long lastPressMs = 0;
void onButtonFalling() {
unsigned long now = millis(); // millis() can be read, but does not advance, inside an ISR
if (now - lastPressMs > 50) { // ignore bounce
pressCount++;
lastPressMs = now;
}
}
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), onButtonFalling, FALLING);
Serial.begin(9600);
}
void loop() {
static unsigned int lastReported = 0;
noInterrupts(); // copy multi-byte shared data safely
unsigned int count = pressCount;
interrupts();
if (count != lastReported) {
Serial.print("Presses: ");
Serial.println(count);
lastReported = count;
}
delay(200); // presses are still counted during this delay
}How the code works
Even with the delay(200) in the loop, no press is lost, because the ISR runs the moment
the pin falls. For ordinary buttons polling is usually simpler; interrupts earn their complexity when timing
really matters.
What you should observe
- Each press increases the count printed in the Serial Monitor by one.
- Rapid presses during the delay are all counted.