Skip to main content

Seeed Studio XIAO SAMD21 with MicroPython

Introduction of MicroPython

MicroPython is a Python interprer with a partial native code compilation feature. It provides a subset of Python 3.5 features, implemented for embedded processors and constrained systems. It is different from CPython and you can read more about the differences here.

Getting Started

First, we are going to connect the Seeed Studio XIAO SAMD21 to the computer and upload a simple code from MicroPython to check whether the board is functioning well.

Hardware Setup

Flash the Firmware

For XIAO SAMD21

  • Step 1. Press and hold the BOOT button and then connect the Seeed Studio XIAO SAMD21 to the PC through the Type-C cable. If it works well, there is an Arduino disk shown on the PC.
  • Step 2. Flash the firmware

Just go to the official XIAO SAMD21 MicroPython Firmware and download the latest firmware

It is also possible to compile your own firmware in order to ensure security and support for the latest features, but this is not necessary.


For XIAO SAMD21 Plus

  • Step 1. Connect the XIAO SAMD21 Plus to your PC with a Type‑C cable, then press the Reset button twice consecutively. If everything works correctly, an Arduino disk will appear on your PC.

Software Setup

  • Step 1. Download and Install the latest version of Thonny editor according to your operating system
  • Step 2. Launch the Thonny

  • Step 3. Click Tools-->Options to open the settings.

  • Step 4. Chose the Interpreter interface and select the device as MicroPython(generic) and the port as Board CDC @ Port

Software Development

SEEED XIAO SAMD21 Series pin assignment table

MicroPython Pin NameXIAO SAMD21 GPIO (ID)XIAO SAMD21 Plus GPIO (ID)IRQ
SAMD21 / Plus
ADCFunction
D0 / A0 / A0_D0PA02 (2)PA02 (2)2 / 20GPIO, ADC, DAC
D1 / A1 / A1_D1PA04 (4)PA04 (4)4 / 44GPIO, ADC
D2 / A2 / A2_D2PA10 (10)PA10 (10)10 / 1018GPIO, ADC
D3 / A3 / A3_D3PA11 (11)PA11 (11)11 / 1119GPIO, ADC
D4 / A4 / A4_D4 / SDAPA08 (8)PA08 (8)NMI / NMI16GPIO, ADC, I2C SDA
D5 / A5 / A5_D5 / SCLPA09 (9)PA09 (9)9 / 917GPIO, ADC, I2C SCL
D6 / A6 / A6_D6 / TXPB08 (40)PB08 (40)8 / 82GPIO, ADC, UART TX
D7 / A7 / A7_D7 / RXPB09 (41)PB09 (41)9 / 93GPIO, ADC, UART RX
D8 / A8 / A8_D8 / SCKPA07 (7)PA07 (7)7 / 77GPIO, ADC, SPI SCK
D9 / A9 / A9_D9 / MISOPA05 (5)PA05 (5)5 / 55GPIO, ADC, SPI MISO
D10 / A10 / A10_D10 / MOSIPA06 (6)PA06 (6)6 / 66GPIO, ADC, SPI MOSI
D11 / TX_LEDPA19 (19)3 / —Original-board TX LED
D12 / RX_LEDPA18 (18)PA28 (28)2 / 8Original RX LED; Plus expansion GPIO
D13 / USER_LED / SCL1PA17 (17)PA17 (17)1 / 1Original user LED; Plus I2C1 SCL
D14 / SDA1PA16 (16)— / 0Plus I2C1 SDA
D15PA15 (15)— / 15Plus expansion GPIO
D16PA14 (14)— / 14Plus expansion GPIO
D17PA13 (13)— / 13Plus expansion GPIO
D18PA12 (12)— / 12Plus expansion GPIO
D19 / I2S_SDPA19 (19)— / 3Plus GPIO and I2S data
D20 / I2S_SCKPA20 (20)— / 4Plus GPIO and I2S clock
D21 / I2S_WSPA21 (21)— / 5Plus GPIO and I2S word select
D22PB10 (42)— / 10Plus expansion GPIO
D23PB11 (43)— / 11Plus expansion GPIO
D24PB23 (55)— / 7Plus expansion GPIO
D25PA23 (23)— / 7Plus expansion GPIO
D26PA22 (22)— / 6Plus expansion GPIO
D27PA18 (18)— / 2Plus expansion GPIO
RGB_LEDPA27 (27)— / 15Addressable RGB LED data
BUTTONPB22 (54)— / 6Plus user button
SWCLKPA30 (30)PA30 (30)10 / 10SWD clock
SWDIOPA31 (31)PA31 (31)11 / 11SWD data
note

The number inside parentheses in GPIO (ID) refers to the MicroPython SAMD Pin ID, not the physical MCU package pin number.

Upload your code

Upload the codes by clicking the "Run current script" button. For the first time, Thonny will ask where you want to save your codes file. Both This Computer and MicroPython device are fine.

If you want to use the program offline, you should save the program to XIAO SAMD21

Press and hold Ctrl + Shift + S at the same time , then select save to MicroPython device

GPIO TEST (LED)

We need to prepare:

Copy the following codes to Thonny.

We can see that the blue RX_LED is lit up and blinks once per second

from machine import Pin, Timer

led = Pin(18, Pin.OUT)
Counter = 0
Fun_Num = 0

def fun(tim):
global Counter
Counter = Counter + 1
print(Counter)
led.value(Counter%2)

tim = Timer(-1)
tim.init(period=500, mode=Timer.PERIODIC, callback=fun)

GPIO Control Relays

We need to prepare:

from machine import Pin, Timer

output_4 = Pin(8, Pin.OUT)
detect_1 = Pin(4, Pin.IN, Pin.PULL_UP)
output_value = Pin(2, Pin.OUT)
Counter = 0

def fun(tim):
global Counter
Counter = Counter + 1
output_4.value(Counter%2)
print(Counter%2,detect_1.value())
if detect_1.value() :
output_value.value(1)
else:
output_value.value(0)

tim = Timer(-1)
tim.init(period=200, mode=Timer.PERIODIC, callback=fun)

Human detection for automatic control

We need to prepare:

from machine import Pin, Timer

led = Pin(8, Pin.OUT)

input_value_1 = Pin(4, Pin.IN, Pin.PULL_UP)
input_value_2 = Pin(10, Pin.IN, Pin.PULL_UP)
output_value = Pin(2, Pin.OUT)

Counter = 0
Fun_Num = 0

def fun(tim):
global Counter
Counter = Counter + 1
led.value(Counter%2)
print(input_value_1.value(),input_value_2.value())
if input_value_1.value() :
output_value.value(1)
else:
output_value.value(0)

tim = Timer(-1)
tim.init(period=50, mode=Timer.PERIODIC, callback=fun)

I2C Support

from machine import Pin, SoftI2C

i2c = SoftI2C(scl=Pin(9), sda=Pin(8), freq=100000)
devices = i2c.scan()
for device in devices:
print("Decimal address: ",device," | Hexa address: ",hex(device))

i2c.writeto(0x51, 'b')
print(i2c.readfrom(0x51, 4)) # read 4 bytes from device with address 0x51
i2c.writeto(0x51, 'a') # write 'a' to device with address 0x51
print(i2c.readfrom(0x51, 4)) # read 4 bytes from device with address 0x51
i2c.writeto(0x51, 'b')
print(i2c.readfrom(0x51, 4))

Familiarity with micropython allows you to do more , we are looking forward to creating more value for you. Feel free to share your projects with us too!

DAC Support

Thank you to Aleksei Tertychnyi for submitting the code, all related functionalities were developed and contributed by him.

from machine import Pin, Timer, DAC

led = Pin(18, Pin.OUT)
counter = 0

dac = DAC(0) #DAC on A0 output

def loop(tim):
global counter
led.value(counter%2)
print('DAC value: ', end =" ")
print(counter)
dac.write(counter%1024)
counter = counter + 1

tim = Timer(-1)
tim.init(period=1000, mode=Timer.PERIODIC, callback=loop)

Voltage on pin A0 will start to gradually increase, after reaching maximum at appoximately 3.3V, will drop to 0V and cycle will repeat.

ADC Support

ADC example MicroPython code:

from machine import Pin, Timer, ADC
led = Pin(18, Pin.OUT) # digital output for blinking
counter = 0 # simple counter for LED toggle

ADC_CONVERT_V = 1.0 / 65535.0 # conversion factor: raw ADC (16-bit) → voltage (vref=1.0V)

adc = ADC(4, vref=0) # ADC reads on pin A4, using internal 1.0V reference
adcVoltage = 0.0 # variable to store measured voltage

def fun(tim):
global counter, adcVoltage # make sure we update the global variables
counter += 1 # increment counter
adcVoltage = adc.read_u16() * ADC_CONVERT_V # read ADC and convert to voltage
print(adcVoltage) # print voltage to REPL
led.value(counter % 2) # toggle LED every callback (blink)

tim = Timer(-1) # create a virtual timer
tim.init(period=1000, # callback period in milliseconds (1000 ms = 1 s)
mode=Timer.PERIODIC, # periodic callback
callback=fun) # function to call

MicroPython Device Console

Our partner Neil has written a command line console program for XIAO using MicroPython. With this programme you can easily upload, download and delete files. We thank him for his contribution to XIAO!

Tech Support & Product Discussion

Thank you for choosing our products! We are here to provide you with different support to ensure that your experience with our products is as smooth as possible. We offer several communication channels to cater to different preferences and needs.

Loading Comments...