The attachInterrupt() function lets your Arduino react immediately when something important happens, like a button press or a sensor signal, without waiting for the main program to check.
attachInterrupt() function in Arduino
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
pin is the Arduino pin number where the interrupt signal comes from.
ISR is the name of the function that runs when the interrupt happens.
mode tells when to trigger the interrupt: LOW, CHANGE, RISING, or FALLING.
blinkLED function when pin 2 signal goes from LOW to HIGH.attachInterrupt(digitalPinToInterrupt(2), blinkLED, RISING);countPresses function when pin 3 signal goes from HIGH to LOW.attachInterrupt(digitalPinToInterrupt(3), countPresses, FALLING);This program uses attachInterrupt() to detect when a button connected to pin 2 is pressed (signal goes LOW). Each press increases buttonPresses. The main loop lights the LED and prints a message when a press is detected.
#define buttonPin 2 #define ledPin 13 volatile int buttonPresses = 0; void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(buttonPin), countPresses, FALLING); Serial.begin(9600); } void loop() { if (buttonPresses > 0) { digitalWrite(ledPin, HIGH); delay(200); digitalWrite(ledPin, LOW); buttonPresses = 0; Serial.println("Button pressed!"); } } void countPresses() { buttonPresses++; }
The function called by attachInterrupt() (ISR) should be short and fast.
Use volatile for variables shared between the ISR and main code to avoid errors.
Not all pins support interrupts; check your Arduino model's documentation.
attachInterrupt() lets Arduino react instantly to events on specific pins.
Use it to handle buttons, sensors, or signals without missing any changes.
Keep interrupt functions short and use volatile for shared variables.
Practice
attachInterrupt() function in Arduino?Solution
Step 1: Understand the role of attachInterrupt()
The functionattachInterrupt()is used to make Arduino respond immediately when a pin changes, without waiting for the main loop.Step 2: Identify the correct purpose
It triggers a specific function automatically on pin state changes, unlike other options which are unrelated to interrupts.Final Answer:
To run a function automatically when a specific pin changes state -> Option CQuick Check:
attachInterrupt() triggers functions on pin changes [OK]
- Confusing attachInterrupt() with serial communication setup
- Thinking it starts the main loop
- Mixing it with variable declarations
handleInterrupt?Solution
Step 1: Recall correct attachInterrupt() syntax
The correct syntax usesdigitalPinToInterrupt(pin)to convert the pin number to an interrupt number.Step 2: Match parameters order
The order is: interrupt number, function name, mode (like RISING). Only attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, RISING); follows this correctly.Final Answer:
attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, RISING); -> Option BQuick Check:
Use digitalPinToInterrupt(pin) for correct interrupt number [OK]
- Passing pin number directly without digitalPinToInterrupt()
- Mixing parameter order
- Using pin number instead of interrupt number
volatile int count = 0;
void setup() {
Serial.begin(9600);
pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), incrementCount, FALLING);
}
void loop() {
Serial.println(count);
delay(500);
}
void incrementCount() {
count++;
}Solution
Step 1: Analyze interrupt setup and button wiring
The button is connected to pin 2 with INPUT_PULLUP, so pressing it pulls pin 2 LOW, triggering FALLING edge interrupt.Step 2: Understand interrupt effect on count
Each button press triggersincrementCount(), increasingcountby 1, which is printed repeatedly in loop.Final Answer:
The count will increase by 1 each time the button is pressed -> Option DQuick Check:
Interrupt increments count on button press [OK]
- Ignoring INPUT_PULLUP logic and edge type
- Assuming count won't change without delay
- Thinking volatile causes crashes
attachInterrupt():volatile int flag = 0;
void setup() {
pinMode(3, INPUT);
attachInterrupt(3, interruptHandler, CHANGE);
}
void loop() {
if (flag == 1) {
Serial.println("Interrupt triggered");
flag = 0;
}
}
void interruptHandler() {
flag = 1;
}Solution
Step 1: Check attachInterrupt() parameter usage
The first parameter must be the interrupt number, obtained by digitalPinToInterrupt(pin), not the pin number directly.Step 2: Verify other parts
CHANGE is a valid mode, flag should be volatile, and interrupt handlers return void, so no other errors.Final Answer:
Pin number 3 is used directly instead of digitalPinToInterrupt(3) -> Option AQuick Check:
Use digitalPinToInterrupt(pin) for correct interrupt number [OK]
- Passing pin number directly to attachInterrupt()
- Misunderstanding valid interrupt modes
- Incorrect return type for interrupt handler
attachInterrupt() is best?Solution
Step 1: Understand the need for debouncing or filtering
To avoid false triggers, you must check if the LOW state lasts at least 50ms, which requires timing logic outside the interrupt.Step 2: Evaluate options for timing and counting
Using CHANGE interrupt and recording time in ISR, then checking duration in loop() allows safe timing without delay() inside ISR, which is not allowed.Step 3: Reject unsafe or incorrect options
Usingdelay()inside the ISR is bad practice; incrementing the count immediately on an edge without checking duration ignores the 50ms requirement.Final Answer:
Use attachInterrupt() on CHANGE, record the time in ISR, and check duration in loop() -> Option AQuick Check:
Record time in ISR, check duration in loop for debounce [OK]
- Using delay() inside interrupt routine
- Ignoring debounce timing
- Incrementing count immediately on edge
Ready to prove it?
Pass the test and this pattern moves unknown
