📖 Scenario: You are building a simple Arduino project where a button press triggers an immediate action without waiting for the main loop. This is useful for reacting quickly to events like button presses or sensor signals.
🎯 Goal: Create an Arduino sketch that uses the attachInterrupt() function to detect a button press on pin 2 and toggle an LED on pin 13 each time the button is pressed.
📋 What You'll Learn
Create a variable to store the LED pin number (13).
Create a variable to store the button pin number (2).
Set the LED pin as output and the button pin as input in setup().
Use attachInterrupt() to call an interrupt service routine when the button is pressed.
In the interrupt service routine, toggle the LED state.
Print the LED state to the Serial Monitor each time it changes.
💡 Why This Matters
🌍 Real World
Interrupts are used in real devices to react quickly to events like button presses, sensor signals, or communication data without waiting for the main program loop.
💼 Career
Understanding interrupts is important for embedded systems programming, robotics, and hardware interfacing jobs where timely responses to hardware events are critical.
Progress0 / 4 steps
1
Set up LED and button pins
Create two integer variables called ledPin and buttonPin with values 13 and 2 respectively. In the setup() function, set ledPin as an output and buttonPin as an input.
Arduino
Hint
Use pinMode() inside setup() to set the pin modes.
2
Create variables for LED state and interrupt setup
Create a boolean variable called ledState and set it to false. In the setup() function, initialize serial communication at 9600 baud using Serial.begin(9600);.
Arduino
Hint
Use Serial.begin(9600); to start serial communication.
3
Attach interrupt and write ISR to toggle LED
Write an interrupt service routine function called toggleLED() that toggles the ledState variable and sets the ledPin output accordingly. In the setup() function, use attachInterrupt() with interrupt number digitalPinToInterrupt(buttonPin), the function toggleLED, and mode RISING to detect button presses.
Arduino
Hint
Use attachInterrupt(digitalPinToInterrupt(buttonPin), toggleLED, RISING); inside setup().
4
Print LED state changes in loop
In the loop() function, print the current LED state as "LED is ON" or "LED is OFF" to the Serial Monitor whenever the state changes. Use a static variable to track the previous state and only print when the state changes.
Arduino
Hint
Use a static variable inside loop() to detect changes in ledState and print accordingly.
Practice
(1/5)
1. What is the main purpose of the attachInterrupt() function in Arduino?
easy
A. To start the main program loop
B. To set the baud rate for serial communication
C. To run a function automatically when a specific pin changes state
D. To declare a variable as volatile
Solution
Step 1: Understand the role of attachInterrupt()
The function attachInterrupt() 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 C
Quick Check:
attachInterrupt() triggers functions on pin changes [OK]
Hint: attachInterrupt() runs code on pin change instantly [OK]
Common Mistakes:
Confusing attachInterrupt() with serial communication setup
Thinking it starts the main loop
Mixing it with variable declarations
2. Which of the following is the correct syntax to attach an interrupt on pin 2 that triggers on a rising edge and calls the function handleInterrupt?
easy
A. attachInterrupt(2, handleInterrupt, RISING);
B. attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, RISING);
C. attachInterrupt(handleInterrupt, 2, RISING);
D. attachInterrupt(2, RISING, handleInterrupt);
Solution
Step 1: Recall correct attachInterrupt() syntax
The correct syntax uses digitalPinToInterrupt(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 B
Quick Check:
Use digitalPinToInterrupt(pin) for correct interrupt number [OK]
Hint: Use digitalPinToInterrupt(pin) for correct interrupt number [OK]
Common Mistakes:
Passing pin number directly without digitalPinToInterrupt()
Mixing parameter order
Using pin number instead of interrupt number
3. What will be the output on the serial monitor after pressing the button connected to pin 2 once, given this code?
A. The count will increase continuously without button presses
B. The count will stay 0 because interrupts are not enabled
C. The program will crash due to volatile misuse
D. The count will increase by 1 each time the button is pressed
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 triggers incrementCount(), increasing count by 1, which is printed repeatedly in loop.
Final Answer:
The count will increase by 1 each time the button is pressed -> Option D
Quick Check:
Interrupt increments count on button press [OK]
Hint: FALLING triggers on button press with INPUT_PULLUP [OK]
Common Mistakes:
Ignoring INPUT_PULLUP logic and edge type
Assuming count won't change without delay
Thinking volatile causes crashes
4. Identify the error in this code snippet using 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;
}
medium
A. Pin number 3 is used directly instead of digitalPinToInterrupt(3)
B. Interrupt mode CHANGE is invalid
C. Flag variable should not be volatile
D. Interrupt handler function must return int
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 A
Quick Check:
Use digitalPinToInterrupt(pin) for correct interrupt number [OK]
Hint: Always convert pin to interrupt number with digitalPinToInterrupt() [OK]
Common Mistakes:
Passing pin number directly to attachInterrupt()
Misunderstanding valid interrupt modes
Incorrect return type for interrupt handler
5. You want to count how many times a sensor connected to pin 4 triggers a LOW signal, but only if the sensor stays LOW for at least 50 milliseconds to avoid false triggers. Which approach using attachInterrupt() is best?
hard
A. Use attachInterrupt() on CHANGE, record the time in ISR, and check duration in loop()
B. Use attachInterrupt() on FALLING edge and increment count immediately without delay
C. Use attachInterrupt() on RISING edge and increment count immediately
D. Use attachInterrupt() on FALLING edge and in the ISR check if LOW lasts 50ms using delay()
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
Using delay() 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 A
Quick Check:
Record time in ISR, check duration in loop for debounce [OK]
Hint: Never use delay() in ISR; check timing in main loop [OK]
Common Mistakes:
Using delay() inside interrupt routine
Ignoring debounce timing
Incrementing count immediately on edge
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.