Video summary

Arduino UNO R4 Lesson13 - Hardware Interrupts | Debouncing a Button

Main summary

Key takeaways

Educational

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:
    1. Interrupt pin (digital pin mapped to an interrupt input; example given: pin 2)
    2. ISR function to call
    3. 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.
  • volatile tells 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.print inside 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
    • Example debounce interval used in subtitles: ~250 ms (adjustable per project/button).

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

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 attachInterrupt behavior)

Original video