MicroPython
Install Thonny (for MicroPython)
See https://wiki.seeedstudio.com/XIAO-RP2040-with-MicroPython/ or jump to the next - TL;DR; - section.
TL; DR;
- https://thonny.org/
pip install thonny
- launch thonny
Tools
>Options...
>Interpreter
: MicroPython(RP2040)- reboot rp2040 in boot mode (boot button pressed while reset released)
- click install or update MicroPython (bottom)
- ok => you’re now talking/interpreting python from the rp2040
- select pico as target (pico and xiao-rp2040 act the same)
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
Print variables
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