← Back to Lab Hub RP2040 JHS Lab

I2C Proximity & Hardware Interrupt (.irq) Simulator

Active-Low INT Line, Falling Edge Triggers & MicroPython ISR Callback

⚡ Polling vs. Interrupts: Instead of continuously querying the sensor over I2C in a while True loop (Polling), the sensor's physical INT pin pulls LOW when distance crosses the threshold (< 8 cm). The RP2040 detects the FALLING edge on GP14 and immediately pauses main code to execute the ISR Callback Function!
RP2040 MASTER SDA (GP4) SCL (GP5) INT (GP14) APDS-9960 SLAVE INT Pin
HARDWARE INTERRUPT TIMING (GP14) INT I2C
Proximity Threshold Setting: < 8 cm (Raw > 180)
GP14 Pin State: HIGH (3.3V - IDLE)
ISR Executed Count: 0 times
🐍 MicroPython Hardware IRQ Code Inspector
from machine import Pin, I2C
import utime

# 1. Setup I2C Bus & Interrupt Pin (GP14)
i2c = I2C(0, sda=Pin(4), scl=Pin(5))
int_pin = Pin(14, Pin.IN, Pin.PULL_UP)

# 2. Configure Sensor Threshold Registers (< 8 cm)
i2c.writeto_mem(0x39, 0x89, b'\xB4') # High threshold = 180

# 3. Interrupt Service Routine (ISR Callback Function)
def proximity_isr(pin):
  # Executed instantly when INT pin drops LOW!
  val = i2c.readfrom_mem(0x39, 0x1C, 1)[0]
  print("⚠️ ALERT: Object Detected!", val)

# 4. Attach IRQ handler on FALLING edge (HIGH -> LOW)
int_pin.irq(handler=proximity_isr, trigger=Pin.IRQ_FALLING)

# 5. Main application loop runs smoothly with NO I2C lag
while True:
  # RP2040 CPU is free to run other tasks...
  utime.sleep_ms(1000)
📝 Concept Check Quiz
Why is trigger=Pin.IRQ_FALLING used for the active-LOW INT pin instead of Pin.IRQ_RISING?