MicroPython



Install Thonny (for MicroPython)

See https://wiki.seeedstudio.com/XIAO-RP2040-with-MicroPython/ or jump to the next - TL;DR; - section.

TL; DR;

Hello World

For this “Hello World”, we will “just” make a LED blink.

The sections were created to help you starting with MicroPython and to give the Fab Academy 2025 programming recitation.

Please note that for the next code and simulations, examples will be given on PIN25, which is the blue builtin LED of your XIAO RP2040, or the green LED of your Raspberry Pico board. On the related Wokwi simulation, we will use PIN0 with a connected LED just because the (very) small LED represented on the board is a bit too discrete.


Loop : “Infinite” while

Blinking the onboard blue led, minimalistic code. Based on an inifinite while because the condition next to it is declared “always true”, so that it will last forever.

import machine
import time

# Set pin 25 (= blue led on XIAO RP2040, builtin led on RPi Pico) as an output
led = machine.Pin(25, machine.Pin.OUT)

# Infinite loop to blink the LED
while True:
    led.toggle()     # Change LED's status
    time.sleep(0.5)  # Wait for 0.5 seconds

Wokwi simulation : https://wokwi.com/projects/421430264769320961


Loop : “conditional” while

This code will set a variable “a” to the value 10, then decrement it (a-=1) on each loop until a becomes 0. The code will then stop. This will thus make your LED blink 5 times. (every loop toggle its status)

import machine
import time

# Set pin 25 (= blue led on XIAO RP2040, builtin led on RPi Pico) as an output
led = machine.Pin(25, machine.Pin.OUT)

a = 10

# Make your led blink 5 times (=10/2 because toggle)
while a > 0:
    a -= 1           # equivalent to a=a-1
    led.toggle()     # Change LED's status
    time.sleep(0.5)  # Wait for 0.5 seconds

Wokwi simulation : https://wokwi.com/projects/421430452019854337


Loop : for

import machine
import time

# Set pin 25 (= blue led on XIAO RP2040, builtin led on RPi Pico) as an output
led = machine.Pin(25, machine.Pin.OUT)

# Make your led blink 5 times (=10/2 because toggle)
for _ in range(10):
    led.toggle()     # Change LED's status
    time.sleep(0.5)  # Wait for 0.5 seconds

Wokwi simulation : https://wokwi.com/projects/421430516926718977


Function Call

import machine
import time

# Set pin 25 (= blue led on XIAO RP2040, builtin led on RPi Pico) as an output
led = machine.Pin(25, machine.Pin.OUT)

def blink_led(times):
    for _ in range(times):
        led.on()
        time.sleep(0.2)
        led.off()
        time.sleep(0.3)

for i in range(5):
    blink_led(i)         # Blink i times
    time.sleep(2)        # Wait for 2 seconds

Wokwi simulation : https://wokwi.com/projects/421430616754324481


Using arrays

This code will define an array containing five different values and then will make the LED blink that amount of times (using the blink_led() function).

import machine
import time

# Array with 5 pre-defined values
values = [3, 7, 2, 5, 1]

# Set pin 25 (= blue led on XIAO RP2040, builtin led on RPi Pico) as an output
led = machine.Pin(25, machine.Pin.OUT)

def blink_led(times):
    for _ in range(times):
        led.on()
        time.sleep(0.2)
        led.off()
        time.sleep(0.3)

for i in values:
    blink_led(i)         # Blink i times
    time.sleep(2)        # Wait for 2 seconds

Wokwi simulation : https://wokwi.com/projects/421517543955841025


Branching : if then else

import machine
import time

# Set pin 25 (= blue led on XIAO RP2040, builtin led on RPi Pico) as an output
led = machine.Pin(25, machine.Pin.OUT)

def blink_led(times):
    for _ in range(times):
        led.on()
        time.sleep(0.2)
        led.off()
        time.sleep(0.3)

for i in range(5):
    if i % 2 == 0:       # if i is even
        blink_led(2)
    else:
        blink_led(1)     # if i is odd
    time.sleep(2)

Wokwi simulation : https://wokwi.com/projects/421430840111524865


Harder/“Hardware” Hello World : meet the PIO!

Basic PIO

import rp2
from machine import Pin

@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink():
    wrap_target()
    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]     # Etc.
    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]     # Etc.
    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()

# Instantiate a state machine with the blink program, at 2000Hz, with set bound to Pin(25)
sm = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(25))

# Activate the state machine
sm.active(1)

Wokwi simulation : https://wokwi.com/projects/421518072397326337


PIO LOOP

import rp2
from machine import Pin

@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink():
    wrap_target()

    set(pins, 1)

    set(x, 31)
    label("loop_on")
    nop()                   [31]
    jmp(x_dec,"loop_on")

    set(pins, 0)

    label("wait")
    set(x,31)
    label("loop")
    nop()                   [31]
    jmp(x_dec,"loop")

    wrap()

# Instantiate a state machine with the blink program, at 2000Hz, with set bound to Pin(0)
sm0 = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))

# Instantiate a state machine with the blink program, at 2000Hz, with set bound to Pin(25)
sm1 = rp2.StateMachine(1, blink, freq=2000, set_base=Pin(25))


# Activate the state machine 0 (external led)
sm0.active(1)

# Activate the state machine 1 (builtin led)
sm1.active(1)

Wokwi simulation : https://wokwi.com/projects/421590653500296193


PIO fast : meet the (logic) analyzer!

import rp2
from machine import Pin

@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink():
    wrap_target()
    set(pins, 1)
    set(pins, 0)
    wrap()

# Instantiate a state machine with the blink program, at 2000Hz, with set bound to Pin(0)
sm0 = rp2.StateMachine(0, blink, freq=2000, set_base=Pin(0))

# Activate the state machine 0 (external led)
sm0.active(1)

Wokwi simulation : https://wokwi.com/projects/421593134171453441


Using modules (~libraries)

To see all available modules : help('modules').

Modules helps you do more complex things with few lines of code.

from machine import Pin
from time import sleep
from neopixel import NeoPixel

np_power_pin = Pin(11, machine.Pin.OUT) # XIAO neopixel power is on Pin11
np_pin = Pin(12)                        # Pin to control neopixel (signal)

# Power the neopixel
np_power_pin.high()

pixels = NeoPixel(np_pin, 1) #only one pixel led

colors = [
  (0xff, 0x00, 0x00),  #RED
  (0x00, 0xff, 0x00),  #GREEN
  (0x00, 0x00, 0xff),  #BLUE
  (0xff, 0xff, 0x00),  #YELLOW
  (0x00, 0xff, 0xff),  #TURQUOISE
  (0xff, 0x00, 0xff)   #PURPLE
]

color_n = len(colors)
color_index = 0

while True :
  for color in colors:
    pixels.fill(color)
    pixels.write()
    sleep(0.5)

Wokwi simulation : https://wokwi.com/projects/422491154454050817


Debugging : basics

Were you surprised to see the LED blink only 1,2,3,4 times in the function call example? (instead of 1,2,3,4,5…) How can you check what was really happening to the “i” variable in this example?

You can simply “print” it. (to your terminal, or through a serial line, or …)

import machine
import time

# Set pin 0 as an output
led = machine.Pin(0, machine.Pin.OUT)

def blink_led(times):
    for _ in range(times):
        led.on()
        time.sleep(0.2)
        led.off()
        time.sleep(0.3)

print("Hello world!")
for i in range(5):
    print("Blink ", i, " times.")
    blink_led(i)         # Blink i times
    time.sleep(2)        # Wait for 2 seconds
print("Goodbye world!")

Yup you should have RTFM of python “range() function”.

Wokwi simulation : https://wokwi.com/projects/421600243316405249

Playground / sandbox board