This MicroPython library allows boards with BLE to broadcast (advertise) and observe (scan) small amounts of data without setting up any connections.
This allows very simple many-to-many communication between broadcasters and multiple observers. Each board can broadcast on one channel (0-255), and observer on multiple channels.
The starting order does not matter, and you can add or remove boards to and from the network as you go.
It matches the protocol used on LEGO hubs that run Pybricks. This means you can also communicate with these LEGO hubs from any MicroPython board with BLE.
You can send signed integer values, floating point numbers, booleans, strings, or bytes. Or a list/tuple of these objects.
For example, you can broadcast one of the following:
data = 12345
data = "Hello, world!"
data = b"\x01\x02\x03"
data = (123, 3.14, True, "Hello World")
Boolean values are packed into one byte. All other types are packed into their respective sizes plus one byte for the type.
Since advertisements payloads are limited to 31 bytes by the Bluetooth spec and there are 5 bytes of overhead, the combined size of all type headers and values is limited to 26 bytes.
When no data is observed, the observe
method returns None
.
To stop broadcasting, use broadcast(None)
.
The full specification is available in the protocol file.
Due to the nature of communication, this technique works best for sending states, not events. Values are broadcast all the time until you change the data, but there is no guarantee that one single value will be received.
For example, if you want to use a button to incrementally turn a motor by 90
degrees, you should not broadcast a message for each button press. Instead, you could
maintain the target angle on the broadcaster, and broadcast 90
, 180
, 270
,
and so on, incrementing every time the button is pressed.
Copy bleradio.py to your board manually.
Or use the mpremote
tool to install it directly from GitHub:
mpremote mip install https://raw.githubusercontent.com/pybricks/micropython-bleradio/master/bleradio.py
# Basic usage of the radio module.
from time import sleep_ms
from bleradio import BLERadio
# A board can broadcast small amounts of data on one channel. Here we broadcast
# on channel 5. This board will listen for other boards on channels 4 and 18.
radio = BLERadio(broadcast_channel=5, observe_channels=[4, 18])
# You can run a variant of this script on another board, and have it broadcast
# on channel 4 or 18, for example. This board will then receive it.
counter = 0
while True:
# Data observed on channel 4, as broadcast by another board.
# It gives None if no data is detected.
observed = radio.observe(4)
print(observed)
# Broadcast some data on our channel, which is 5.
radio.broadcast(["hello, world!", 3.14, counter])
counter += 1
sleep_ms(100)
from bleradio import BLERadio
radio = BLERadio(observe_channels=[5])
old_data = None
while True:
new_data = radio.observe(5)
strength = radio.signal_strength(5)
if new_data == old_data:
continue
print(strength, "dBm:", new_data)
old_data = new_data
See examples/custom_irq to see how you can set up the observe IRQ manually so you can mix it with other BLE code.
You can use this library to communicate with LEGO hubs that run Pybricks. For example, you can use a MicroPython board to control a LEGO hub.
Hubs running Pybricks already have this functionality built in so you won't need to install this library on those hubs. The API is mostly the same, but the channels are specified during hub setup.
See this video for an example. Any hub shown here could be replaced by a MicroPython board with BLE.
If you use vscode
, run the build task (Ctrl+Shift+B
) to automatically
upload the local library to the board and then run the currently open example.
This method requires mpremote
.
You can use the library as shown here, but we kindly ask you to suggest changes to the protocol here in an issue so we don't end up with too many incompatible versions.