Skip to content

MicroPython

Wokwi

main.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from machine import Pin
import time

led = Pin(0, Pin.OUT)  # Set GP0(=Xiao's D6 Pin) as output

while True:
    led.value(1)  # Turn on the LED
    time.sleep(1)  # Wait for 1 second
    led.value(0)  # Turn off the LED
    time.sleep(1)  # Wait for 1 second

Note

This code doesn’t work in Wokwi, and not tested in a board

main.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from machine import Pin
import time
import _thread # Import the _thread module to enable multi-threading (for running tasks on both cores)

# Define LEDs
led0 = Pin(0, Pin.OUT)  # Set GP0 (Xiao RP2040's D6 Pin) as output
led1 = Pin(1, Pin.OUT)  # Set GP1 (Xiao RP2040's D7 Pin) as output

# Function to blink the LED
def blink_led(led): 
    while True: # Infinite loop to keep blinking the LED indefinitely
        led.value(1)  # Turn on the LED
        time.sleep(1)  # Wait for 1 second
        led.value(0)  # Turn off the LED
        time.sleep(1)  # Wait for 1 second

# Start a new thread to run blink_led on core 1 for led1
_thread.start_new_thread(blink_led, (led1,))

# Run blink_led on core 0 for led0
# Since this is the main thread, it will continuously execute blink_led for led0.
blink_led(led0)

Ref. Recitation

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import rp2
from machine import Pin

# Define a PIO program for blinking an LED
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW) # Initialize the pin as LOW at startup
def blink():
    wrap_target() # Define the start of the PIO loop
    set(pins, 1)   [31]     # Set the pin "on", then wait 31 instructions
    nop()          [31]     # Do nothing, then wait 31 instruction (total 32 instructions)
    nop()          [31]     
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    set(pins, 0)   [31]     # Set the pin "of", then wait 31 instructions
    nop()          [31]     # Do nothing, then wait 31 instruction (total 32 instructions)
    nop()          [31]     
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]
    nop()          [31]     # Maximum 32 instructions lines in PIO!
    wrap() # Define the end of the PIO loop (it will restart from wrap_target())


# Instantiate a state machine with the blink program, at 2000Hz, with set bound to Pin(0)
# - State machine 0
# - Uses the `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 0 (typically the built-in LED on Raspberry Pi Pico)
sm = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))

# Activate the state machine (start blinking)
sm.active(1)

Note

nop() is a “No Operation” instruction that does nothing.
[31] specifies that the instruction should wait for 31 cycles after execution.

If the PIO state machine clock is 2000 Hz (2 kHz), then one cycle takes:
$$
\frac{1}{2000} = 0.0005 \text{ seconds (0.5ms)}
$$

Waiting for 31 cycles results in:
$$
0.5 \times 31 = 15.5 \text{ ms}
$$

→ This creates a delay of approximately 15.5ms.

nop() は 「何もしない (No Operation)」命令
[31] は 「この命令の実行後に 31 サイクル待機する」 という指定

PIO ステートマシンのクロックが 2000 Hz (2 kHz) なら、1サイクルは $$
\frac{1}{2000} = 0.0005 \text{ 秒 (0.5ms)}
$$ 31 サイクル待機すると
$$
0.5 \times 31 = 15.5 \text{ ms}
$$ → 約 15.5ms の遅延 を作れる。

 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
38
39
40
41
42
43
44
45
46
47
48
49
50
import rp2
from machine import Pin

# Define a PIO program for blinking an LED
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)  # Initialize the pin as LOW at startup
def blink():
    wrap_target()  # Define the start of the PIO loop

    # Turn the pin ON (HIGH)
    set(pins, 1)   # Set the pin HIGH

    # Set the X register to 31 (used for the delay loop)
    set(x, 31)  

    # Delay loop while the pin is HIGH
    label("loop_on")  
    nop()         [31]   # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop_on")  # Decrement X and jump back to "loop_on" if X is not zero

    # Turn the pin OFF (LOW)
    set(pins, 0)  # Set the pin LOW

    # Set the X register to 31 again for the OFF delay loop
    label("wait")
    set(x, 31)

    # Delay loop while the pin is LOW
    label("loop")  
    nop()         [31]   # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop")  # Decrement X and jump back to "loop" if X is not zero

    wrap()  # Define the end of the PIO loop (it will restart from wrap_target())

# Instantiate a state machine with the blink program
# - State machine 0
# - Uses the `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 0
sm0 = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))

# Instantiate another state machine for a second LED
# - State machine 1
# - Uses the same `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 1
#sm1 = rp2.StateMachine(1, blink, freq=2000, set_base=Pin(1))

# Activate both state machines (start blinking both LEDs)
sm0.active(1)
#sm1.active(1)
 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
38
39
40
41
42
43
44
45
46
47
48
49
50
import rp2
from machine import Pin

# Define a PIO program for blinking an LED
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)  # Initialize the pin as LOW at startup
def blink():
    wrap_target()  # Define the start of the PIO loop

    # Turn the pin ON (HIGH)
    set(pins, 1)   # Set the pin HIGH

    # Set the X register to 31 (used for the delay loop)
    set(x, 31)  

    # Delay loop while the pin is HIGH
    label("loop_on")  
    nop()         [31]   # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop_on")  # Decrement X and jump back to "loop_on" if X is not zero

    # Turn the pin OFF (LOW)
    set(pins, 0)  # Set the pin LOW

    # Set the X register to 31 again for the OFF delay loop
    label("wait")
    set(x, 31)

    # Delay loop while the pin is LOW
    label("loop")  
    nop()         [31]   # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop")  # Decrement X and jump back to "loop" if X is not zero

    wrap()  # Define the end of the PIO loop (it will restart from wrap_target())

# Instantiate a state machine with the blink program
# - State machine 0
# - Uses the `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 0
sm0 = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))

# Instantiate another state machine for a second LED
# - State machine 1
# - Uses the same `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 1
sm1 = rp2.StateMachine(1, blink, freq=2000, set_base=Pin(1))

# Activate both state machines (start blinking both LEDs)
sm0.active(1)
sm1.active(1)

Note

This code doesn’t work in Wokwi, and not tested in a board

 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
import rp2
from machine import Pin

# Define a PIO program for blinking an LED
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW) # Initialize the pin as LOW at startup
def blink():
    wrap_target() # Define the start of the PIO loop

    set(pins, 1)          # Set the pin HIGH
    set(x, 31)            # Set the X register to 31 (used for the delay loop)
    label("loop_on")      # Delay loop while the pin is HIGH
    nop()         [31]    # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop_on") # Decrement X and jump back to "loop_on" if X is not zero

    set(pins, 0)          # Set the pin LOW
    set(x, 31)            # Set the X register to 31 (used for the delay loop)
    label("loop")         # Delay loop while the pin is LOW
    nop()         [31]    # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop")    # Decrement X and jump back to "loop" if X is not zero

    wrap()  # Define the end of the PIO loop (it will restart from wrap_target())

# Instantiate a state machine with the blink program
# - State machine 0
# - Uses the `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 0,1,2...
sm0 = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))
sm1 = rp2.StateMachine(1, blink, freq=2000, set_base=Pin(1))
sm2 = rp2.StateMachine(1, blink, freq=2000, set_base=Pin(2))

# Activate state machines (start blinking both LEDs)
sm0.active(1)
sm1.active(1)
sm2.active(1)
 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
38
39
40
41
42
43
44
import rp2
from machine import Pin
import time  # Required for the delay in the main loop

# Define a PIO program for blinking an LED
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)  # Initialize the pin as LOW at startup
def blink():
    wrap_target() # Define the start of the PIO loop

    set(pins, 1)          # Set the pin HIGH
    set(x, 31)            # Set the X register to 31 (used for the delay loop)
    label("loop_on")      # Delay loop while the pin is HIGH
    nop()         [31]    # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop_on") # Decrement X and jump back to "loop_on" if X is not zero

    set(pins, 0)          # Set the pin LOW
    set(x, 31)            # Set the X register to 31 (used for the delay loop)
    label("loop")         # Delay loop while the pin is LOW
    nop()         [31]    # Do nothing, then wait 31 instruction cycles
    jmp(x_dec, "loop")    # Decrement X and jump back to "loop" if X is not zero

    wrap()  # Define the end of the PIO loop (it will restart from wrap_target())

# Instantiate a state machine with the blink program
# - State machine 0
# - Uses the `blink` PIO program
# - Runs at 2000 Hz
# - Controls Pin 0,1,2...
sm0 = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))
sm1 = rp2.StateMachine(1, blink, freq=2000, set_base=Pin(1))

# Activate both state machines (start blinking both LEDs)
sm0.active(1)
sm1.active(1)

# Define led1 using standard GPI2 (software-controlled)
led1 = Pin(2, Pin.OUT)  # Set GP1 as an output

# Main loop to blink led1
while True:
    led1.value(1)  # Turn on LED1
    time.sleep(1)  # Wait for 1 second
    led1.value(0)  # Turn off LED1
    time.sleep(1)  # Wait for 1 second