One simple way of communicating between two BLE devices is to use a simulated "UART". A UART provides a bi-directional byte stream, so that both ends of a connection can transmit and receive bytes with each other.
There are standard BLE UART services, such as the Nordic UART Service (NUS). The Adafruit Bluefruit Connect app uses NUS to talk to BLE boards.
Once you get the UART service working, it's easy to invent your own ad hoc protocol that sends and receives commands and data over the serial stream.
BLE UART Python eval()
Example
Here's a simple example that uses BLE UART to send a text string from a host computer to a CircuitPython board over BLE. The board calls the Python function eval()
on the string, to evaluate it as a Python expression, and sends the result back as a string to the host computer. For instance, the host might send 2+2
, and the board will send back 4
.
To try this example, first install this library from the latest library bundle on your BLE-capable CircuitPython board, such as a Feather nRF52840 or a Circuit Playground Bluefruit:
- adafruit_ble
Then copy the program below to CIRCUITPY on your CircuitPython board as code.py:
# SPDX-FileCopyrightText: 2020 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT # Provide an "eval()" service over BLE UART. from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService ble = BLERadio() uart = UARTService() advertisement = ProvideServicesAdvertisement(uart) while True: ble.start_advertising(advertisement) print("Waiting to connect") while not ble.connected: pass print("Connected") while ble.connected: s = uart.readline() if s: try: result = str(eval(s)) except Exception as e: result = repr(e) uart.write(result.encode("utf-8"))
Now copy the second program to your host computer, and run it. Wait for it to connect to your board, and then type some Python expressions at the Eval: prompt.
# SPDX-FileCopyrightText: 2020 Dan Halbert for Adafruit Industries # # SPDX-License-Identifier: MIT # Connect to an "eval()" service over BLE UART. from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement from adafruit_ble.services.nordic import UARTService ble = BLERadio() uart_connection = None while True: if not uart_connection: print("Trying to connect...") for adv in ble.start_scan(ProvideServicesAdvertisement): if UARTService in adv.services: uart_connection = ble.connect(adv) print("Connected") break ble.stop_scan() if uart_connection and uart_connection.connected: uart_service = uart_connection[UARTService] while uart_connection.connected: s = input("Eval: ") uart_service.write(s.encode("utf-8")) uart_service.write(b'\n') print(uart_service.readline().decode("utf-8"))
Here's an example of running the ble_eval_client.py program on a Raspberry Pi Zero W, talking to a Circuit Playground Bluefruit.
Note that errors, like division by zero, are caught and reported. Also note you can only type Python expressions, not statements. So a = 3
doesn't work.
Page last edited January 22, 2025
Text editor powered by tinymce.