Sometimes, your Arduino needs to save power by sleeping. It can wake up when something important happens, like pressing a button. This is done using interrupts.
Wake-up from sleep with interrupt in Arduino
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); // pin: the pin number to watch // ISR: the function to run when interrupt happens // mode: when to trigger (LOW, CHANGE, RISING, FALLING)
The ISR function must be very short and fast.
Use digitalPinToInterrupt(pin) to get the correct interrupt number for the pin.
attachInterrupt(digitalPinToInterrupt(2), wakeUp, RISING);attachInterrupt(digitalPinToInterrupt(3), wakeUp, FALLING);This program puts the Arduino to sleep to save power. When you press the button on pin 2, it triggers an interrupt that wakes the Arduino. The program then prints "Woke up!" and goes back to sleep.
#include <avr/sleep.h> volatile bool wokeUp = false; void wakeUp() { wokeUp = true; // This runs when interrupt happens } void setup() { pinMode(2, INPUT_PULLUP); // Button on pin 2 Serial.begin(9600); attachInterrupt(digitalPinToInterrupt(2), wakeUp, FALLING); Serial.println("Going to sleep. Press button on pin 2 to wake up."); } void loop() { if (!wokeUp) { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); // Arduino sleeps here sleep_disable(); } if (wokeUp) { Serial.println("Woke up!"); wokeUp = false; // Reset flag delay(1000); // Wait a bit before sleeping again } }
Interrupts can wake the Arduino from deep sleep modes.
Keep the interrupt service routine (ISR) very short to avoid problems.
Use INPUT_PULLUP for buttons to avoid floating pins.
Use interrupts to wake Arduino from sleep when an event happens.
Attach interrupt to a pin with attachInterrupt() and define a short ISR.
Put Arduino to sleep with sleep_mode() and it wakes on interrupt.
Practice
Solution
Step 1: Understand sleep mode purpose
Arduino sleep mode reduces power consumption by stopping most activities.Step 2: Role of interrupts in sleep mode
Interrupts allow the Arduino to wake up immediately when an external event occurs, saving power while staying responsive.Final Answer:
To allow the Arduino to respond immediately to an external event while saving power -> Option AQuick Check:
Interrupt wakes Arduino from sleep to save power [OK]
- Thinking interrupts speed up normal running
- Confusing interrupts with reset functions
- Believing interrupts increase memory
Solution
Step 1: Use digitalPinToInterrupt() for pin mapping
Pin 2 must be converted using digitalPinToInterrupt(2) for portability.Step 2: Set correct trigger mode
RISING triggers interrupt when signal goes from LOW to HIGH.Final Answer:
attachInterrupt(digitalPinToInterrupt(2), ISR, RISING); -> Option BQuick Check:
Correct pin and RISING trigger = attachInterrupt(digitalPinToInterrupt(2), ISR, RISING); [OK]
- Using pin number directly without digitalPinToInterrupt()
- Choosing wrong trigger mode like FALLING or LOW
- Attaching interrupt to wrong pin number
void ISR() {
Serial.println("Woke up!");
}
void setup() {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), ISR, RISING);
sleep_enable();
sleep_mode();
Serial.println("Sleeping...");
}
void loop() {
// Empty loop
}Solution
Step 1: Analyze print locations
"Sleeping..." prints after sleep_mode(), so it executes after waking up.Step 2: ISR execution order
ISR prints "Woke up!" immediately upon interrupt, before resuming code after sleep_mode().Final Answer:
Sleeping...\nWoke up! -> Option DQuick Check:
Code after sleep_mode() runs after ISR, so output order is Sleeping... then Woke up! [OK]
- Thinking "Sleeping..." prints before sleep
- Believing no output after wake
- Expecting Sleeping... before ISR
void ISR() {
// Empty ISR
}
void setup() {
attachInterrupt(3, ISR, FALLING);
sleep_enable();
sleep_mode();
}
void loop() {
// Empty
}Solution
Step 1: Check attachInterrupt() usage
Pin number must be converted with digitalPinToInterrupt(pin) for correct interrupt mapping.Step 2: Validate other parts
Empty ISR is allowed; sleep_mode() can be in setup; sleep_enable() must be before sleep_mode().Final Answer:
attachInterrupt() uses pin number directly instead of digitalPinToInterrupt() -> Option AQuick Check:
Pin mapping requires digitalPinToInterrupt() [OK]
- Not using digitalPinToInterrupt() for pin mapping
- Thinking ISR must have code
- Misplacing sleep_enable() call
Solution
Step 1: Attach interrupt correctly
Use digitalPinToInterrupt(4) and FALLING trigger for button press (assuming active LOW button).Step 2: Enable sleep and enter sleep mode
Call sleep_enable() before sleep_mode() to allow waking on interrupt.Final Answer:
attachInterrupt(digitalPinToInterrupt(4), wakeISR, FALLING); sleep_enable(); sleep_mode(); -> Option CQuick Check:
Correct pin, trigger, and sleep calls = attachInterrupt(digitalPinToInterrupt(4), wakeISR, FALLING); sleep_enable(); sleep_mode(); [OK]
- Using sleep_disable() before sleep_mode()
- Wrong trigger mode like LOW or CHANGE for button press
- Not enabling sleep before entering sleep_mode()
Ready to prove it?
Pass the test and this pattern moves unknown
