In the video lesson above, we show how to incorporate IRQ interrupts on the Pi Pico PIO State Machines. The state machines will monitor the buttons, watching for button presses. When a button is pressed, an interrupt is set. That interrupt can then be used by that same state machine, a different state machine on the same PIO, or in the main micropython program. Our first example will be to toggle the LED in the main python program, based on the interrupt from the state machine. In the second example, one state machine monitors the button, and the second state machine controls the LED. This is a schematic for the circuit we will be using.
This first code controls the LED from the main python program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import rp2 from machine import Pin import time # Define PIO program for SM0 to trigger an interrupt on button press @rp2.asm_pio() def button_irq(): wrap_target() wait(1, pin, 0) [31] # Wait for the button press (low signal on GPIO 11) nop() [31] nop() [31] nop() [31] nop() [31] irq(block, 0) # Trigger interrupt 0 wait(0, pin, 0) # Wait for the button release (high signal on GPIO 11) nop() [31] nop() [31] nop() [31] nop() [31] wrap() # Initialize State Machine 0 for the button (GPIO 11) button_pin = Pin(11, Pin.IN, Pin.PULL_DOWN) sm_button = rp2.StateMachine(0, button_irq, freq=2000, in_base=button_pin) # GPIO pin for the LED (GPIO 18) led_pin = Pin(18, Pin.OUT) # Interrupt handler for the button press def button_handler(sm): led_pin.value(not led_pin.value()) # Toggle LED state # Attach the interrupt handler to the State Machine's IRQ sm_button.irq(button_handler) # Activate the state machine sm_button.active(1) # Keep the program running while True: time.sleep(1) |
This next program uses only the state machines. Interrupts and LED control are both done in the state machines.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import rp2 from machine import Pin import time @rp2.asm_pio() def button_irq(): wrap_target() wait(1, pin, 0) [31] nop() [31] nop() [31] nop() [31] nop() [31] irq(block,0) wait(0,pin,0) nop() [31] nop() [31] nop() [31] nop() [31] wrap() @rp2.asm_pio(out_init=rp2.PIO.OUT_LOW) def led_control(): set(x,0b00000) wrap_target() wait(1, irq, 0) mov(x,invert(x)) mov(pins,x) irq(clear, 0) wrap() button_pin = Pin(11,Pin.IN,Pin.PULL_DOWN) sm_button=rp2.StateMachine(0,button_irq, freq=2000, in_base=button_pin) led_pin = Pin(18, Pin.OUT) sm_led=rp2.StateMachine(1, led_control, freq=2000, out_base=led_pin) sm_button.active(1) sm_led.active(1) |