In my last tutorial, TinyML Made Easy: Anomaly Detection & Motion Classification, we installed, tested, and explored the tiny device XIAO BLE Sense using the Arduino IDE. Here, we will repeat all the basic tests but code them using Python.
For that, we will use CircuitPython from Adafruit. CircuitPython is a programming language designed to simplify experimenting and to learn to program on low-cost microcontroller boards, such as the XIAO BLE Sense. It makes getting started more accessible than ever with no upfront desktop downloads. Once your board is set up, open any text editor and get started editing code. It's that simple.
CircuitPython is based on MicroPython, with a few differences; for example, concurrency within Python is not well supported because Interrupts and threading are disabled (some concurrency is achieved with native modules for tasks that require it, such as audio file playback). In short, CircuitPython is designed for simplicity, having beginners in mind. Here you can learn about those differences: CircuitPython vs MicroPython: Key Differences.
Connecting the XIAO BLE SenseIn terms of Hardware, the device's main features are:
- Bluetooth 5.0 with onboard antenna
- CPU: Nordic nRF52840, ARM® Cortex®-M4 32-bit processor with FPU, 64 MHz
- Ultra-Low Power: Standby power consumption is less than 5μA
- Battery charging chip: Supports lithium battery charge and discharge management
- 2 MB flash
- 256 KB RAM
- PDM microphone
- 6-axis LSM6DS3TR-C IMU
- Ultra Small Size: 20 x 17.5mm, XIAO series classic form-factor for wearable devices
- Rich interfaces: 1xUART, 1xI2C, 1xSPI, 1xNFC, 1xSWD, 11xGPIO(PWM), 6xADC
- Single-sided components, surface mounting design
When you connect your XIAO BLE Sense to your computer, start clicking the Reset Button
twice to put the device in Boot Mode.
Reset Button
is a tiny button located on the left of the USB connector
You will see an external drive named XIAO-SENSE on your file finder.
Download the official CircuiPython Bootloader for XIAO BLE Sense. First, a .uf2
file should be downloaded. Then, choose the latest stable release.
Drag the.uf2 file to the XIAO-SENSE
drive:
A new drive should appear, named CIRCUITPY
.
At this point, your device is ready to execute MicroPython scripts (.py). Scripts named code.py
(or main.py
) will be executed automatically when you press the Reset Button
(once).
The best way to program in Python is using an IDE; the simple one for CircuitPython is the MU Editor. Go to MU Editor Download page, choose your Operational System and follow the instructions.
Once the MU Editor is installed, open it, go to Mode
Button, select CircuitPython and press OK
.
In the program area, enter this python code:
print("Hello World")
Select Save
on Top Menu. A window will appear. Please give the name code.py
for your program and save it on the CIRCUITPY
drive.
Your program will be executed automatically on the device, but you can see the result on the Serial Console. For example, by selecting Serial
on Top Menu, you can see the result printed on the Serial Console:
You can change the code.py
script, and the program will run on the device by pressing Save automatically.
The serial console receives output from your CircuitPython board sent over USB and displays it so you can see it. This is necessary when you've included a print statement in your code and want to see what you printed. It is also helpful for troubleshooting errors because your board will send errors, and the serial console will display those too.
You can also use print statements for troubleshooting, called "print debugging". Essentially, if your code isn't working, and you want to know where it's failing, you can put print statements in various places to see where it stops printing.
The REPL
The other feature of the serial connection is the Read-Evaluate-Print-Loop, or REPL. The REPL allows you to enter individual lines of code and have them run immediately. So it's convenient if you're running into trouble with a particular program and can't figure out why. In addition, it's interactive, so it's great for testing new ideas.
To use the REPL, you must first be connected to the serial console. Usually, you will see the message:
Press any key to enter the REPL. Use CTRL-D to reload.
So, you need to press any key or CTRL+C
if a code is running.
You will know that you are in REPL, if the message below appears:
Adafruit CircuitPython 7.3.2 on 2022-07-20; Seeed XIAO nRF52840 Sense with nRF52840
>>>
At this point, you can enter python commands line by line. So, for example, you can run the "Hello World" again:
When ready to leave the REPL and return to the serial console, press CTRL+D
. This action will reload your board and reenter the serial console. You will restart the program you had running before entering the REPL. In the console window, you'll see any output from the program you had running. And if your program was affecting anything visual on the board, you'll see that start up again. You can return to the REPL at any time!
Perfect! Our device is working correctly, interpreting Python code generated on our Editor (in this case, the MU). Now, let's blink the XIAO BLE Sense Internal LED.
Be sure you are in Serial Console mode (not REPL), copy and paste this script to the MU editing area, and press Save
.
import time
import board
from digitalio import DigitalInOut, Direction
led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
while True:
led.value = False
time.sleep(1)
led.value = True
time.sleep(1)
The Serial Console will display:
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
And you will see Red LED blinking on the device:
The Library Board
will handle the devices connected to the XIAO BLE Sense. You can explore all board functions running this code:
"""CircuitPython Essentials Pin Map Script"""
import microcontroller
import board
board_pins = []
for pin in dir(microcontroller.pin):
if isinstance(getattr(microcontroller.pin, pin), microcontroller.Pin):
pins = []
for alias in dir(board):
if getattr(board, alias) is getattr(microcontroller.pin, pin):
pins.append("board.{}".format(alias))
if len(pins) > 0:
board_pins.append(" ".join(pins))
for pins in sorted(board_pins):
print(pins)
On the Serial Monitor, we can get:
board.A0 board.D0
board.A1 board.D1
board.A2 board.D2
board.A3 board.D3
board.A4 board.D4 board.SDA
board.A5 board.D5 board.SCL
board.CHARGE_STATUS
board.D10 board.MOSI
board.D6 board.TX
board.D7 board.RX
board.D8 board.SCK
board.D9 board.MISO
board.IMU_INT1
board.IMU_PWR
board.IMU_SCL
board.IMU_SDA
board.LED board.LED_RED
board.LED_BLUE
board.LED_GREEN
board.MIC_PWR
board.NFC1
board.NFC2
board.PDM_CLK
board.PDM_DATA
board.READ_BATT_ENABLE
board.VBATT
The above list is the pin/functions names related to this Pin diagram:
Note that board.LED
is in the same line as board.LED_RED
. This means that the Red LED is used as the "Builtin Led". Returning to Blink code, try changing the code line:
led = DigitalInOut(board.LED)
by
led = DigitalInOut(board.LED_RED)
You will realize that a few seconds after you press Save
, the Red LED is blinking as expected. Now change it to:
led = DigitalInOut(board.LED_GREEN)
Now, the Green LED is Blinking. Try changing to blue by yourself.
Some observations:
- The LED is ON when
led.value
isFalse
- The argument of
time.sleep(Seconds)
function is in seconds and not milliseconds, as we saw in the Arduino IDE.
Alternating Colors
We can expand the code for blinking alternated colors:
"""
Example for XIAO BLE. Blinks the built-in REG LED.
Marcelo Rovai @Aug22
"""
import time
import board
import digitalio
ledR = digitalio.DigitalInOut(board.LED_RED)
ledR.direction = digitalio.Direction.OUTPUT
ledG = digitalio.DigitalInOut(board.LED_GREEN)
ledG.direction = digitalio.Direction.OUTPUT
ledB = digitalio.DigitalInOut(board.LED_BLUE)
ledB.direction = digitalio.Direction.OUTPUT
def led_off():
ledR.value = True
ledG.value = True
ledB.value = True
led_off()
while True:
ledR.value = False
print("Red On")
time.sleep(1.0)
led_off()
time.sleep(1.0)
ledG.value = False
print("Green On")
time.sleep(1.0)
led_off()
time.sleep(1.0)
ledB.value = False
print("Blue On")
time.sleep(1.0)
led_off()
time.sleep(1.0)
And printing the color on Serial Console, as shown below:
Exploring CPU data:
CircuitPython has the library microcontroller
that, among several modules, has the one related to its CPU, the microcontroller.cpu
, which can bring information about its operation as clock frequency, voltage, and temperature:
Copy and paste the below code to code.py
script and press Save
:
"""
XIAO BLE Sense - CPU data
"""
import microcontroller
print("\n")
print("CPU Clock Freq: {} Mega Hertz".format(microcontroller.cpu.frequency/1000000))
print("CPU Voltage: {} volts".format(round(microcontroller.cpu.voltage, 1)))
print("CPU Temp: {} oC".format(microcontroller.cpu.temperature))
As a result, we can confirm that the CPU is running with 3.3V at 64MHz and with a temperature of around 20oC. Next, try pressing the XIAO BLE between your fingers and rerun the code (you only should press Save
). You will realize that the temperature will quickly go over 30oC.
So far, we have explored some system information and also tested the RGB LED. Now it is time to test the incorporated sensors, let's start with the PDM Microphone.
The XIAO BLE Sense has a PDM digital output MEMS microphone. For testing the internal Microphone, copy and paste the below script on code.py
:
'''
SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
SPDX-License-Identifier: MIT
Adapted to XIAO BLE Sense by Marcelo Rovai @August22
'''
import time
import array
import math
import board
import digitalio
import audiobusio
# turn on the microphone
micpwr = digitalio.DigitalInOut(board.MIC_PWR)
micpwr.direction = digitalio.Direction.OUTPUT
micpwr.value = True
time.sleep(0.1)
# Remove DC bias before computing RMS.
def mean(values):
return sum(values) / len(values)
# Calculate the Normalized RMS value of samples
def normalized_rms(values):
minbuf = int(mean(values))
samples_sum = sum(
float(sample - minbuf) * (sample - minbuf)
for sample in values
)
return math.sqrt(samples_sum / len(values))
# Main program
mic = audiobusio.PDMIn(board.PDM_CLK,
board.PDM_DATA,
sample_rate=16000,
bit_depth=16
)
samples = array.array('H', [0] * 160)
while True:
mic.record(samples, len(samples))
magnitude = normalized_rms(samples)
print((magnitude,))
time.sleep(0.1)
On Serial Console, you will see the Normalized RMS value of the audio captured by the Mic. Try to talk or make any sound. You will realize that the value will go up. It is also possible to use the plotter for data inspection. Press the Plotter
button on the top menu. Below is a screen-shot of the Mu Editor screen:
Digging the code
The way to use the PDM microphone with CircuitPython is with the built-in audiobusio
module and PDMIn
class. It allows you to record an input audio signal from the microphone using PDM.
The code is very simple. There are three board functions associated with the PDM microphone:
board.MIC_PWR
board.PDM_DATA
board.PDM_CLK
First, we must "turn on" the microphone:
micpwr = digitalio.DigitalInOut(board.MIC_PWR)
micpwr.direction = digitalio.Direction.OUTPUT
micpwr.value = True
time.sleep(0.1)
Next, we must sample audio (raw data), which will be done by mic
. For that, we will use the audiobusio.PDMIn()
function, where the sample rate and bit depth should be defined (in our case, 16KHz and 16 bits, respectively:
mic = audiobusio.PDMIn(
board.PDM_CLK,
board.PDM_DATA,
sample_rate=16000,
bit_depth=16
)
The raw data that will be captured (recorded) by mic.record()
will be stored in a buffer created from a fixed length integer array, samples
(in this case, length is 160):
samples = array.array('H', [0] * 160)
The 'H' means that the data in the array is int (2 bytes)
, having the initializer as: [0] * 160 ==> 160 positions of 2 bytes array, initialized with zeros. You can learn more about arrays here: array
— Efficient arrays of numeric values.
What we see at Serial Console and Plotter is the normalized RMS (Root Means Squared) value of those 160 samples stored each time in the buffer. Those calculations are done with those functions:
# Remove DC bias before computing RMS.
def mean(values):
return sum(values) / len(values)
# Calculate the Normalized RMS value of samples
def normalized_rms(values):
minbuf = int(mean(values))
samples_sum = sum(
float(sample - minbuf) * (sample - minbuf)
for sample in values
)
return math.sqrt(samples_sum / len(values))
A continuous loop will capture the 160 samples, and calculate their magnitude (normalized RMS), showing the result on Console:
while True:
mic.record(samples, len(samples))
magnitude = normalized_rms(samples)
print((magnitude,))
time.sleep(0.1)
Note that the Mu plotter looks for tuple values to print. Tuples in Python come in parentheses ()
with comma separators. Thus the extra parentheses and comma in print(
(
magnitude
,)
)
.
So far, all modules used (such as time,
array,
math,
board,
digitalio,
audiobusio,
etc.) were imported without the necessity of any external library.
You can lear more here: Adafruit CircuitPython API Reference
But, if you can read the values generated by a sensor, such as the IMU (Accelerometer and Gyroscope), you will need to install an external library, which will be stored on your CIRCUITPY
drive in a folder called lib
.
Your board may ship with a lib folder already, it's in the base directory of the drive. If not, simply create the folder yourself. When you first install CircuitPython, an empty lib directory will be created for you.
The CircuitPython libraries (named as library_name.mpy
) should be moved manually to this /lib
folder or using the utility CircUp, which I recommend.
CircUp
is a utility written by Nicholas Tollervey that looks at all the libraries inside of the lib
folder on your connected CircuitPython device. It can tell you what version each of them is and if there are any out-of-date libraries, and if they are out of date, it can automatically go to the repo, download, and update the library for you.
CircUp installation
Go to CircUp installation webpage and follow the instructions for your OS. In my case (MacOS), I simply opened my terminal, entering this command line:
pip install circup
You can check the version, verifying if the utility is installed correctly:
circup --version
If you already have an older version of CircUp
installed, you can update to the latest version by typing:
pip install --upgrade circup
Install a Library with CircUp
To install a library with CircUp, first, you need to know the name of the library. You can do that with the circup show
command.
First, make sure you have your XIAO BLE Sense plugged in, and then type in the following: circup install [library_name]
The XIAO BLE Sense has integrated a 6-Axis IMU, the LSM6DS3TR-C, a system-in-package 3D digital accelerometer, and a 3D digital gyroscope. So, let's use CircUP
for installing the library.
Using the circup show
command and rolling down the terminal, we will find: adafruit_lsm6ds
.
Now, with the command: circup install adafruit_lsm6ds
,
all proper dependencies will be automatically installed on Driver CIRCUITPY/lib
:
To test the IMU, copy and paste this script to code.py and press Save
:
'''
SPDX-FileCopyrightText: Copyright (c) 2020 Bryan Siepert for Adafruit Industries
SPDX-License-Identifier: MIT
Adapted by Marcelo Rovai @August22
XIAO BLE Sense IMU Test
NOTE: Important to install library lib/adafruit_lsm6ds/
You can use CircUp CLI Tool to install and update libraries on your device. Follow instructions:
https://learn.adafruit.com/keep-your-circuitpython-libraries-on-devices-up-to-date-with-circup
'''
import time
import board
import digitalio
import busio
from adafruit_lsm6ds.lsm6ds3trc import LSM6DS3TRC
# On the Seeed XIAO Sense the LSM6DS3TR-C IMU is connected on a separate
# I2C bus and it has its own power pin that we need to enable.
imupwr = digitalio.DigitalInOut(board.IMU_PWR)
imupwr.direction = digitalio.Direction.OUTPUT
imupwr.value = True
time.sleep(0.1)
imu_i2c = busio.I2C(board.IMU_SCL, board.IMU_SDA)
sensor = LSM6DS3TRC(imu_i2c)
# To see data on Serial Monitor:
while True:
print("Acceleration: X:%.2f, Y: %.2f, Z: %.2f m/s^2" % (sensor.acceleration))
print("Gyro X:%.2f, Y: %.2f, Z: %.2f radians/s" % (sensor.gyro))
print("")
time.sleep(0.5)
Note that on the Seeed XIAO Sense, the LSM6DS3TR-C IMU is connected on a separate I2C bus, and it has its own power pin that we need to enable (same we did with the PDM microphone)
On Serial Console, you will see every half of the second the values of the 3 axes of each sensor. Try move your device and see the changes in values.
You can also see the sensors individually on Plotter. To see the accelerometer signal on Plotter, change the While loop with those lines, press Save
and also Plotter
while True:
print(sensor.acceleration)
time.sleep(0.1)
The above code shows the accelerometer data. To see the Gyro, change the print line as below:
while True:
print(sensor.gyro)
time.sleep(0.
Playing with BLEThe XIAO BLE Sense uses Bluetooth Low Energy or BLE. BLE is a wireless communication protocol used by many devices, including mobile devices. We will communicate with our board using a mobile app designed by Adafruit, the Bluefruit LE Connect. Install the app on your smartphone from the Apple App Store or Google Play App Store.
To better understand the BLE concept, its operation can be divided into two categories: connection setup and communication.
- Connection Setup: deals with setting up connections between devices, such as between your mobile phone and the XIAO board.
- Communication deals with communication between the devices once they are connected.
Bluetooth Terms
- Central - The host computer. This is often a mobile device such as a phone or tablet, or it could be a desktop or laptop.
- Peripheral - The connected device, in this case, the XIAO BLE Sense and any sensor/actuator connected to it.
- Advertising - Information sent by the peripheral during connection set up. When a device advertises, it is transmitting the name of the device and describing its capabilities. The central (the smartphone app) looks for an advertising peripheral to connect (the XIAO) and uses that information to determine what the peripheral is capable of.
- Service - A function the peripheral provides. The peripheral advertises its services. Standard service is the UART service, which acts like a hardware UART and is a way of bidirectionally sending information to and from devices.
- Packet - Data transmitted by a device. BLE devices and host computers transmit and receive data in small bursts called packets.
Installing the BLE Library and finding your XIAO
The first library to install is the BLERadio. Go to your terminal and enter with this command line:
circup install adafruit_ble_adafruit
Entering REPL mode, you can discover how your device is named:
In my case, it is 'CIRCUITPYe9a3'.
We will receive commands from a PAD via BLE, using the app Bluefruit LE Connect. The Bluefruit LE Connect app has a control pad with 8 buttons:
UP
,DOWN
,LEFT
,RIGHT
,1
,2
,3
, and4
.
The below code will show you how to access those buttons and use them to print a message to the serial console.
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.button_packet import ButtonPacket
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
while True:
ble.start_advertising(advertisement)
while not ble.connected:
pass
# Now we're connected
while ble.connected:
if uart.in_waiting:
packet = Packet.from_stream(uart)
if isinstance(packet, ButtonPacket):
if packet.pressed:
if packet.button == ButtonPacket.BUTTON_1:
# The 1 button was pressed.
print("1 button pressed!")
elif packet.button == ButtonPacket.BUTTON_2:
# The 2 button was pressed.
print("2 button pressed!")
elif packet.button == ButtonPacket.BUTTON_3:
# The 3 button was pressed.
print("3 button pressed!")
elif packet.button == ButtonPacket.BUTTON_4:
# The 4 button was pressed.
print("4 button pressed!")
elif packet.button == ButtonPacket.UP:
# The UP button was pressed.
print("UP button pressed!")
elif packet.button == ButtonPacket.DOWN:
# The DOWN button was pressed.
print("DOWN button pressed!")
elif packet.button == ButtonPacket.LEFT:
# The LEFT button was pressed.
print("LEFT button pressed!")
elif packet.button == ButtonPacket.RIGHT:
# The RIGHT button was pressed.
print("RIGHT button pressed!")
# If we got here, we lost the connection. Go up to the top and start
# advertising again and waiting for a connection.
Put the MU on Serial Console Mode (CTRL+D
), copy and paste the above script to code.py, and press Save
. If it is the first time that you running this code, you will probably get an error saying that one of the libraries is not installed. In this case: adafruit_bluefruit_connect.
Install the library, running at the terminal this command line:
circup install adafruit_bluefruit_connect
Return the MU Editor to Serial Console Mode (CTRL+D
), and press Save
again.
Now, open your smartphone and start the app., following the actions shown below:
Pressing a button on the app Control Pad, you can see that it is recognized and will appear on Serial Console:
So, our device recognized the commands received from the app on a remote smartphone. Those commands can be used to control things, such as motors, LEDs, etc. Let's modify the code to control our board color LEDs as below:
- Command 1 ==> Turn On LED Red
- Command 2 ==> Turn On LED Green
- Command 3 ==> Turn On LED Blue
- Command 4 ==> Turn Off all LEDs
import time
import board
import digitalio
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.button_packet import ButtonPacket
# Initialize BLE
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
# Initialize LEDs
ledR = digitalio.DigitalInOut(board.LED_RED)
ledR.direction = digitalio.Direction.OUTPUT
ledG = digitalio.DigitalInOut(board.LED_GREEN)
ledG.direction = digitalio.Direction.OUTPUT
ledB = digitalio.DigitalInOut(board.LED_BLUE)
ledB.direction = digitalio.Direction.OUTPUT
def led_off():
ledR.value = True
ledG.value = True
ledB.value = True
led_off()
while True:
ble.start_advertising(advertisement)
while not ble.connected:
pass
# Now we're connected
while ble.connected:
if uart.in_waiting:
packet = Packet.from_stream(uart)
if isinstance(packet, ButtonPacket):
if packet.pressed:
if packet.button == ButtonPacket.BUTTON_1:
# The 1 button was pressed.
print("Button 1 - Red LED!")
led_off()
ledR.value = False
elif packet.button == ButtonPacket.BUTTON_2:
# The 2 button was pressed.
print("Button 2 - Red GREEN!")
led_off()
ledG.value = False
elif packet.button == ButtonPacket.BUTTON_3:
# The 3 button was pressed.
print("Button 3 - Blue LED!")
led_off()
ledB.value = False
elif packet.button == ButtonPacket.BUTTON_4:
# The 4 button was pressed.
print("Button 4 - LEDs OFF!")
led_off()
elif packet.button == ButtonPacket.UP:
# The UP button was pressed.
print("UP button pressed!")
elif packet.button == ButtonPacket.DOWN:
# The DOWN button was pressed.
print("DOWN button pressed!")
elif packet.button == ButtonPacket.LEFT:
# The LEFT button was pressed.
print("LEFT button pressed!")
elif packet.button == ButtonPacket.RIGHT:
# The RIGHT button was pressed.
print("RIGHT button pressed!")
Here is the result:
We will now do the reverse, we will send data from our device to the smartphone. The data to send are the CPU data that we have explored before.
First copy and past the below script on code.py and press Save
.
import microcontroller
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
ble = BLERadio()
uart_server = UARTService()
advertisement = ProvideServicesAdvertisement(uart_server)
while True:
print("WAITING...")
# Advertise when not connected.
ble.start_advertising(advertisement)
while not ble.connected:
pass
# Connected
ble.stop_advertising()
print("CONNECTED")
# Loop and read packets
while ble.connected:
# INCOMING (RX) check for incoming text
if uart_server.in_waiting:
raw_bytes = uart_server.read(uart_server.in_waiting)
text = raw_bytes.decode().strip().lower()
# print("raw bytes =", raw_bytes)
print("RX:", text)
if text == 'temperature':
text = "CPU Temp: {} oC\r\n".format(microcontroller.cpu.temperature)
print("TX:", text.strip())
elif text == 'voltage':
text = "CPU Voltage: {} volts\r\n".format(round(microcontroller.cpu.voltage, 1))
print("TX:", text.strip())
elif text == 'frequency':
text = "CPU Frequency: {} MHz\r\n".format(microcontroller.cpu.frequency/1000000)
print("TX:", text.strip())
uart_server.write(text.encode())
# Disconnected
print("DISCONNECTED")
On Serial Console, you will see WAITING...
Start the Adafruit Bluefruit LE Connect app, Connect
the device on the app, and then select UART
.
On Serial Console, you will see CONNECTED.
From this point, any text received from the app will also be displayed on Serial Console, but if the text received is:
temperature
, current CPU temperature will be sent to app via BLEvoltage
, current CPU voltage will be sent to app via BLE- -
frequency
, current CPU frequency clock will be sent to app via BLE
The data sent could also be the output of sensors such as the microphone or IMU. The UART application can also capture data sending them as a file in several formats such as.txt,.csv,.json and.bin.
ConclusionWe could realize that the Seeed XIAO BLE Sense can easily be programmed using python. Here we explored the most basic applications, but the XIAO can do much more! Try to connect the device using an Expansion Board that enables build prototypes and projects easily and quickly. The XIAO BLE Sense will be expanded to several peripherals, such as OLED, RTC, expandable memory, passive buzzer, RESET/User button, and 5V servo connector, among others.
On my GitHub repository, you will find the last version of all the codes used on this tutorial: Seeed-XIAO-BLE-Sense-Micropython
That's all, folks!
As always, I hope this project can help others find their way into the exciting world of Physical Computing and programming.
link: MJRoBot.org
Greetings from the south of the world!
See you at my next project!
Thank you
Marcelo
Comments