Bird
Raised Fist0
Arduinoprogramming~10 mins

attachInterrupt() function in Arduino - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - attachInterrupt() function
Setup interrupt pin
↓
Call attachInterrupt()
↓
Wait for interrupt event
↓
Interrupt triggers ISR
↓
ISR runs quickly
↓
Return to main program
The attachInterrupt() function sets up a pin to watch for a signal change and runs a small special function (ISR) when that happens.
Execution Sample
Arduino
volatile int count = 0;
void setup() {
  attachInterrupt(digitalPinToInterrupt(2), increment, RISING);
}
void increment() {
  count++;
}
This code increases 'count' by 1 every time pin 2 detects a rising signal.
Execution Table
StepActionPin StateInterrupt Triggered?ISR Called?count Value
1Setup startsLOWNoNo0
2attachInterrupt called on pin 2 for RISING edgeLOWNoNo0
3Pin 2 signal changes from LOW to HIGHHIGHYesYes0
4ISR 'increment' runsHIGHYesYes1
5ISR finishes, main continuesHIGHNoNo1
6Pin 2 signal stays HIGHHIGHNoNo1
7Pin 2 signal changes from HIGH to LOWLOWNoNo1
8Pin 2 signal changes from LOW to HIGH againHIGHYesYes1
9ISR 'increment' runs againHIGHYesYes2
10ISR finishes, main continuesHIGHNoNo2
💡 No more signal changes, program continues running main loop.
Variable Tracker
VariableStartAfter Step 4After Step 9Final
count0122
Key Moments - 3 Insights
Why does the ISR run only when the pin signal changes from LOW to HIGH?
Because attachInterrupt() was set with the RISING mode, it triggers the ISR only on a LOW to HIGH change, as shown in steps 3 and 8 in the execution_table.
Why must the variable 'count' be declared volatile?
Because 'count' is changed inside the ISR and read outside, declaring it volatile tells the compiler it can change anytime, preventing wrong optimizations. This is important as seen in variable_tracker.
What happens if the ISR takes too long to run?
The main program pauses during the ISR, so long ISRs can cause delays or missed interrupts. Here, the ISR just increments 'count' quickly (step 4 and 9), keeping the program responsive.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'count' after the ISR runs the second time?
A1
B0
C2
D3
💡 Hint
Check the 'count Value' column at step 9 where ISR runs again.
At which step does the interrupt trigger for the first time?
AStep 2
BStep 3
CStep 5
DStep 7
💡 Hint
Look at the 'Interrupt Triggered?' column to find the first 'Yes'.
If the attachInterrupt mode changed from RISING to FALLING, when would the ISR run?
AWhen pin changes from HIGH to LOW
BWhen pin stays HIGH
CWhen pin changes from LOW to HIGH
DWhen pin stays LOW
💡 Hint
RISING triggers on LOW to HIGH; FALLING triggers on HIGH to LOW signal changes.
Concept Snapshot
attachInterrupt(pin, ISR, mode)
- Sets an interrupt on 'pin'
- Runs ISR function when 'mode' condition met
- Modes: RISING, FALLING, CHANGE, LOW
- ISR should be short and fast
- Use volatile for variables shared with ISR
Full Transcript
The attachInterrupt() function in Arduino sets up a pin to watch for signal changes. When the specified event happens, it runs a small special function called an ISR (Interrupt Service Routine). In the example, the program watches pin 2 for a rising edge (signal going from LOW to HIGH). When this happens, the ISR 'increment' runs and increases the 'count' variable by one. The variable 'count' is declared volatile because it changes inside the ISR and is used outside. The ISR runs quickly so the main program can continue without delay. The execution table shows each step: setting up, waiting, detecting signal changes, running ISR, and updating 'count'. This helps beginners see how interrupts work step-by-step.

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

  1. 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.
  2. Step 2: Identify the correct purpose

    It triggers a specific function automatically on pin state changes, unlike other options which are unrelated to interrupts.
  3. Final Answer:

    To run a function automatically when a specific pin changes state -> Option C
  4. 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

  1. Step 1: Recall correct attachInterrupt() syntax

    The correct syntax uses digitalPinToInterrupt(pin) to convert the pin number to an interrupt number.
  2. Step 2: Match parameters order

    The order is: interrupt number, function name, mode (like RISING). Only attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, RISING); follows this correctly.
  3. Final Answer:

    attachInterrupt(digitalPinToInterrupt(2), handleInterrupt, RISING); -> Option B
  4. 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?
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++;
}
medium
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

  1. 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.
  2. Step 2: Understand interrupt effect on count

    Each button press triggers incrementCount(), increasing count by 1, which is printed repeatedly in loop.
  3. Final Answer:

    The count will increase by 1 each time the button is pressed -> Option D
  4. 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

  1. Step 1: Check attachInterrupt() parameter usage

    The first parameter must be the interrupt number, obtained by digitalPinToInterrupt(pin), not the pin number directly.
  2. Step 2: Verify other parts

    CHANGE is a valid mode, flag should be volatile, and interrupt handlers return void, so no other errors.
  3. Final Answer:

    Pin number 3 is used directly instead of digitalPinToInterrupt(3) -> Option A
  4. 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

  1. 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.
  2. 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.
  3. 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.
  4. Final Answer:

    Use attachInterrupt() on CHANGE, record the time in ISR, and check duration in loop() -> Option A
  5. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard