📖 Scenario: You want to make a simple Arduino project where pressing a button changes the state of an LED immediately, without waiting for the main program loop. This is useful when you want your Arduino to react quickly to button presses.
🎯 Goal: Build an Arduino program that uses an interrupt to detect when a button is pressed and toggles an LED on or off right away.
📋 What You'll Learn
Create a variable to store the LED pin number
Create a variable to store the button pin number
Set up the LED pin as output and the button pin as input with pull-up resistor
Create a volatile variable to hold the LED state
Attach an interrupt to the button pin to detect button presses
Write an interrupt service routine (ISR) to toggle the LED state
In the main loop, set the LED to the current state
Print the LED state to the Serial Monitor when it changes
💡 Why This Matters
🌍 Real World
Interrupt-driven button handling is used in devices where quick response to user input is important, like remote controls, game controllers, or safety switches.
💼 Career
Understanding interrupts and hardware input handling is essential for embedded systems developers, IoT engineers, and anyone working with microcontrollers.
Progress0 / 4 steps
1
Set up LED and button pins
Create two integer variables called ledPin and buttonPin. Set ledPin to 13 and buttonPin to 2. In the setup() function, set ledPin as an output and buttonPin as an input with the internal pull-up resistor enabled.
Arduino
Hint
Use pinMode to set the pin modes inside setup().
2
Create LED state variable and attach interrupt
Create a volatile bool variable called ledState and initialize it to false. In the setup() function, attach an interrupt to buttonPin using attachInterrupt(digitalPinToInterrupt(buttonPin), toggleLED, FALLING). Define an empty function called toggleLED() that will be the interrupt service routine.
Arduino
Hint
Use attachInterrupt in setup() and define toggleLED() as the ISR.
3
Toggle LED state inside the interrupt
Inside the toggleLED() function, toggle the value of ledState by setting it to its opposite using ledState = !ledState;. In the loop() function, set the LED output to ledState using digitalWrite(ledPin, ledState ? HIGH : LOW);.
Arduino
Hint
Toggle ledState inside toggleLED() and update the LED in loop().
4
Print LED state changes to Serial Monitor
In the setup() function, start the serial communication with Serial.begin(9600);. Create a non-volatile boolean variable called lastLedState initialized to false. In the loop() function, check if ledState is different from lastLedState. If yes, print "LED is ON" or "LED is OFF" accordingly using Serial.println(), then update lastLedState to ledState. Keep the LED output code as before.
Arduino
Hint
Use Serial.begin(9600); in setup() and print messages in loop() when the LED state changes.
Practice
(1/5)
1. What is the main advantage of using interrupts for button handling on an Arduino?
easy
A. The Arduino can react immediately when the button is pressed without waiting.
B. It makes the button press slower but more reliable.
C. It allows the button to be pressed multiple times at once.
D. It disables other parts of the program while the button is pressed.
Solution
Step 1: Understand what interrupts do
Interrupts pause the main program to run a special function immediately when an event happens, like a button press.
Step 2: Compare interrupt behavior to normal checking
Without interrupts, the program must keep checking the button, which can delay response. Interrupts react instantly.
Final Answer:
The Arduino can react immediately when the button is pressed without waiting. -> Option A
Quick Check:
Interrupts = Immediate reaction [OK]
Hint: Interrupts react instantly, no waiting needed [OK]
Common Mistakes:
Thinking interrupts slow down button response
Believing interrupts disable other code permanently
Confusing interrupts with polling multiple presses
2. Which of the following is the correct syntax to attach an interrupt to pin 2 that calls the function buttonPressed on a FALLING edge?
easy
A. attachInterrupt(digitalPinToInterrupt(2), buttonPressed, FALLING);
B. attachInterrupt(2, buttonPressed, RISING);
C. attachInterrupt(buttonPressed, 2, FALLING);
D. attachInterrupt(2, FALLING, buttonPressed);
Solution
Step 1: Recall attachInterrupt syntax
The correct syntax is attachInterrupt(digitalPinToInterrupt(pin), ISR_function, mode).
Step 2: Match parameters to the question
Pin is 2, function is buttonPressed, mode is FALLING edge.
Final Answer:
attachInterrupt(digitalPinToInterrupt(2), buttonPressed, FALLING); -> Option A
B. Modifying a multi-byte variable without disabling interrupts
C. Incrementing a non-volatile variable in ISR
D. attachInterrupt() called with wrong pin number
Solution
Step 1: Check variable type and ISR safety
'count' is volatile int (multi-byte). Incrementing it in ISR and reading in loop can cause inconsistent values.
Step 2: Understand atomicity issue
Incrementing multi-byte variables is not atomic; main code reading 'count' may see partial updates causing errors.
Final Answer:
Modifying a multi-byte variable without disabling interrupts -> Option B
Quick Check:
Multi-byte variable access must be atomic [OK]
Hint: Use atomic operations or disable interrupts for multi-byte vars [OK]
Common Mistakes:
Ignoring atomicity of multi-byte variables
Thinking delay() blocks interrupts
Assuming attachInterrupt pin is wrong without checking
5. You want to count how many times a button connected to pin 4 is pressed, but only if the button is pressed and held for at least 2 seconds. Which approach best uses interrupts to achieve this?
hard
A. Poll the button state in loop without interrupts and count presses.
B. Use attachInterrupt on RISING edge to increment count immediately on press.
C. Use attachInterrupt on FALLING edge to start a timer, then check duration in loop before incrementing count.
D. Use attachInterrupt on CHANGE edge and increment count inside ISR.
Solution
Step 1: Understand requirement for press duration
Counting only if pressed for 2 seconds means timing the press length, not just detecting press.
Step 2: Use interrupt to detect press start and timer in loop
Interrupt on FALLING edge detects press start; loop checks if button held 2 seconds before counting.
Final Answer:
Use attachInterrupt on FALLING edge to start a timer, then check duration in loop before incrementing count. -> Option C
Quick Check:
Interrupt detects press start; loop checks hold time [OK]
Hint: Interrupt starts timer; loop checks hold duration [OK]
Common Mistakes:
Incrementing count immediately without timing
Using CHANGE edge causing multiple triggers
Polling without interrupts misses instant detection
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.