Video summary
Arduino UNO R4 Lesson13 - Hardware Interrupts | Debouncing a Button
Main summary
Key takeaways
Main Ideas / Lessons
- Use of hardware interrupts on Arduino UNO R4 to respond immediately to external events (e.g., a button press) without waiting for the main loop to finish.
- Why interrupts matter even when code contains delays or blocking operations: an ISR (Interrupt Service Routine) runs right when the interrupt event occurs, preempting the current execution flow.
- Interrupt configuration and modes:
- How to attach an ISR to a specific pin.
- How different trigger modes—LOW, falling edge, rising edge, and change—determine when the ISR runs.
- Writing proper ISRs:
- ISRs should be short and fast.
- ISRs cannot take parameters and do not return values.
- Use global variables to share data between the ISR and the main code.
- Use of
volatile:- Needed for variables shared between ISR and main code so the compiler doesn’t optimize them away or reorder access unexpectedly.
- Debouncing a mechanical button:
- Buttons can “bounce” and cause multiple interrupts for one press.
- Solution shown: time-based debouncing using
millis()(ignore interrupts occurring within a short window after the first trigger).
Concepts and Workflow (Methodology / Instructions)
1) Interrupt Basics (Conceptual Steps)
- An interrupt is a signal that tells the processor to pause the current program and run a specific code block immediately.
- The immediate code block is the ISR (Interrupt Service Routine).
- After the ISR finishes, the program resumes exactly where it left off in
loop().
2) Implementing Hardware Interrupts in Code (Step-by-Step)
Materials / Circuit Context
- LEDs connected to pins:
- 5 (green)
- 6 (yellow)
- 7 (red) (with current-limiting resistors)
- Servo: signal wire to pin 9
- Button module: connected to pin 2, configured with pullup
- Idle is HIGH
- Press changes to LOW
Step A: Write an ISR Function
- Create a dedicated ISR function (example name mentioned: something like
redLEDOnISR). - Inside the ISR:
- Turn on the red LED.
- Set a shared variable (e.g.,
pause = 180) so the servo can be repositioned when main code continues. - For debouncing, add a time-gate using
millis()to prevent repeated triggers.
Step B: Attach the ISR to the Interrupt Pin
- Use
attachInterrupt(...)with three arguments:- Interrupt pin (digital pin mapped to an interrupt input; example given: pin 2)
- ISR function to call
- Interrupt mode defining when to trigger:
- LOW: triggers whenever the pin is LOW (may trigger repeatedly while held low)
- FALLING: triggers on transition HIGH → LOW (button press with pullup wiring)
- RISING: triggers on transition LOW → HIGH (button release)
- CHANGE: triggers on either transition (press and release)
3) Demonstrated Behavior with Different Interrupt Modes
- LOW mode
- The ISR executes immediately when the pin becomes LOW and keeps firing as long as it remains LOW (depending on implementation).
- The video explains moving the button-response logic from
loop()into the ISR.
- FALLING mode
- ISR triggers at the moment the button is pressed (HIGH → LOW).
- In the example, the ISR includes a short
delay, so the red LED appears briefly (subtitles suggest ~40 ms).
- RISING mode
- ISR triggers when the button is released (LOW → HIGH).
- CHANGE mode
- ISR triggers twice per full action: once on press (HIGH → LOW) and once on release (LOW → HIGH).
4) ISR Constraints (Rules of Thumb)
- Keep ISRs short and fast to avoid delaying the rest of the program.
- ISR rules:
- cannot have parameters
- does not return a value
- Use global variables to communicate between ISR and main code.
- Mark shared variables as
volatile.
5) Why volatile Is Emphasized
- The subtitles explain that compiler optimizations might remove or reuse variable values incorrectly if a variable is only modified in an ISR and not “seen” through normal code flow.
volatiletells the compiler the variable can change unexpectedly (e.g., from ISR context).
6) Debouncing (Hardware Interrupt + Button Bounce Problem)
Problem Shown
- A single press can produce multiple ISR executions because button contacts bounce before reaching a stable state.
Important Warning
- Avoid
Serial.printinside an ISR (it could be too slow and cause hard-to-debug issues).
Solutions Mentioned
- Hardware: add an RC filter to smooth the signal and reduce bouncing.
- Software (implemented in subtitles): time-based debounce using
millis():- Declare:
- a global volatile counter (to illustrate repeated calls)
- timing variables like
prevTime
- In the ISR:
- only run the “real” interrupt action if:
currentTime - prevTime >= debounceInterval
- then update:
prevTime = currentTime
- only run the “real” interrupt action if:
- Example debounce interval used in subtitles: ~250 ms (adjustable per project/button).
- Declare:
7) Challenge Activity (Additional Instruction)
- Add another button on pin 3 as a second hardware interrupt:
- When pin 2 button is pressed:
- red LED on
- servo resets to 180° when released
- When pin 3 button is pressed:
- green LED on
- servo resets to 90° when released
- When pin 2 button is pressed:
Speakers / Sources Featured
- Joed go (host/teacher; mentions “hey everyone… it is me joed go”)
- Sunfounder / Sounder (source of the Arduino UNO R4 Minima ultimate sensor kit; referenced as “Sounder” and the related button/traffic-light module)
- Arduino (Uno R4 / Arduino documentation concepts) (used as the basis for interrupt pin/modes and
attachInterruptbehavior)