Using Bluetooth Low Energy on the Raspberry Pi Pico - Part 1/4: Introduction to BLE
Introduction to BLE on the Raspberry Pi Pico W using MicroPython, building up to creating a custom BLE service for provisioning a Pico's WiFi settings through a web-page.
Just want a TL;DR to get it working?
Subscribers get access to TL;DR versions of all my blog series!
The Raspberry Pi Pico is a microcontroller that can be used in a variety of different ways: home automation, personalised gifts, information displays, and lots more! The Raspberry Pi Pico W is another version that comes with WiFi and Bluetooth, which greatly expands the possibilities, especially for IoT use-cases.
A common method of setting up headless WiFi-enabled devices is through Bluetooth, and usually a corresponding web or mobile app. For example, if you're setting up a WiFi-connected light bulb, you might first download the manufacturer's app to connect to the bulb via Bluetooth, to provide your WiFi credentials (SSID and password). It's a user-friendly way to enable dynamic WiFi configuration of headless devices, and allow users of your product to get connected to the Internet quickly and easily.
We can do the same with a Raspberry Pi Pico W (or, any other Bluetooth-enabled device)!
This series is intended for readers with some experience in Python, but not necessarily any experience with programming for Bluetooth, MicroPython, or the Raspberry Pi Pico! It is split into 4 parts; feel free to skip ahead to sections most relevant for you:
- Introducing important Bluetooth Low Energy (BLE) concepts
- [Coming Soon] Using MicroPython on a Raspberry Pi Pico W
- [Coming Soon] Creating a custom BLE Service in MicroPython, to allow users to send their WiFi details (network SSID and password)
- [Coming Soon] Creating a basic web-app with JavaScript and HTML to easily allow users to input their WiFi details and send it to your Pico
Disclaimer: I, myself, am constantly learning more about this area, and whilst I've tried to be as accurate and concise as possible, there may be mistakes. If you spot something that looks wrong, I would love to hear from you in the comments so we can all learn together!
Introduction to BLE
Bluetooth Low Energy is a special version of Bluetooth, specifically designed for lower power consumption. This makes it ideal to use in small smart-home appliances, homemade gifts, battery-operated gadgets, and so on.
From the outside, BLE can appear quite overwhelming, but we can break it down into a few core concepts and entities:
The base specification, or framework, that enables BLE connections is the Generic Access Profile (GAP). This defines how devices can be discovered and connected to. It includes advertising the device, where advertisement packets might include things like the device name (e.g., "Mia's Earbuds").
A peripheral device is the one that advertises its presence via GAP – in our case, the Pico. This can be considered as the server (even though it's usually much less powerful than a traditional server!).
A central device is one that connects to the peripheral and uses the data/features provided – in our case, the device running the web app to input the WiFi details. This can be considered as the client (even though it's usually much more powerful than the peripheral/server).
Once a connection has been established between two devices, the Generic Attribute Profile (GATT) is used. This defines the specification around what data can now be communicated between the devices.
A GATT profile defines services. This can also be thought of as 'features' – they define specific functionality that a device provides. For example, a smartwatch might have a 'Heart Rate Service'. In our case, we might have a 'WiFi Provisioning Service'.
Each service defines characteristics. A characteristic is a specific data entity that may be readable and/or writeable. For example, a WiFi Provisioning service could have a writable 'password' characteristic, which a user writes to via a mobile app or web interface. A characteristic can optionally define a descriptor, which describes the purpose of the characteristic, such as with a string.
Every entity described above (profile, service, characteristic, descriptor) is identified by a 128-bit UUID (universally unique identifier). The Bluetooth SIG (Special Interest Group) publish 100s of 'official' UUIDs that correspond to these types of entities – see the Bluetooth Assigned Numbers.
The UUIDs published by the Bluetooth SIG enable interoperability between devices; for example, your device may advertise the "Heart Rate Service" which has pre-defined characteristics like "Heart Rate Measurement" – now, anyone who connects to your device will know what they can expect to find and how to interact with your device.
You are not limited to only using the Assigned Numbers. Anyone is free to use a custom UUID for their own BLE entities, if an existing one isn't suitable! However, the UUID must be outside if the Base UUID range described above. You can use a tool like https://bleid.netlify.app/ to create your UUIDs.