BLE: micro:bit UART

Experimenting with the micro:bit's Bluetooth UART support.

This will explore the lower level guts of how Nordic's Bluetooth Low Energy UARTs work. There are tools to make this easier and less full of guts, but they hide the details.

Device one: micro:bit, code: https://makecode.microbit.org/_PTFKUM4Eo0tP

micro:bit

Device two: Raspberry Pi 3 (which has built-in Bluetooth)

pairing the micro:bit and Pi 3

I put the micro:bit in Bluetooth pair mode

On the Pi 3, I started the bluetooth device scan

$ bluetoothctl
[NEW] Controller B8:27:EB:F4:24:59 pi3.lan [default]
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:F4:24:59 Discovering: yes

And it found the micro:bit's address.

[NEW] Device CD:06:39:E6:6A:A7 BBC micro:bit [vepug]

So I turned the scan off and told the Pi 3 to pair with the micro:bit

[bluetooth]# scan off
[CHG] Device CD:06:39:E6:6A:A7 RSSI is nil
[CHG] Device B8:78:2E:10:01:86 RSSI is nil
Discovery stopped
[CHG] Controller B8:27:EB:F4:24:59 Discovering: no
[bluetooth]# pair CD:06:39:E6:6A:A7
Attempting to pair with CD:06:39:E6:6A:A7
[CHG] Device CD:06:39:E6:6A:A7 Connected: yes
[CHG] Device CD:06:39:E6:6A:A7 Connected: no
[CHG] Device CD:06:39:E6:6A:A7 Paired: yes
Pairing successful

I have the Pi 3 connect to it

[bluetooth]# connect CD:06:39:E6:6A:A7
Attempting to connect to CD:06:39:E6:6A:A7
[CHG] Device CD:06:39:E6:6A:A7 Connected: yes
[CHG] Device CD:06:39:E6:6A:A7 Name: BBC micro:bit
[CHG] Device CD:06:39:E6:6A:A7 Alias: BBC micro:bit
Connection successful
[CHG] Device CD:06:39:E6:6A:A7 UUIDs:
        00001800-0000-1000-8000-00805f9b34fb
        00001801-0000-1000-8000-00805f9b34fb
        0000180a-0000-1000-8000-00805f9b34fb
        6e400001-b5a3-f393-e0a9-e50e24dcca9e
        e95d93af-251d-470a-a062-fa1922dfa9a8
        e95d93b0-251d-470a-a062-fa1922dfa9a8
[CHG] Device CD:06:39:E6:6A:A7 Appearance: 0x0200

I get some basic info from the device

[bluetooth]# info CD:06:39:E6:6A:A7
Device CD:06:39:E6:6A:A7
        Name: BBC micro:bit
        Alias: BBC micro:bit
        Appearance: 0x0200
        Paired: yes
        Trusted: no
        Blocked: no
        Connected: yes
        LegacyPairing: no
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
        UUID: Vendor specific           (6e400001-b5a3-f393-e0a9-e50e24dcca9e)
        UUID: Vendor specific           (e95d93af-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95d93b0-251d-470a-a062-fa1922dfa9a8)

Nordic's UART service UUID is 6e400001-b5a3-f393-e0a9-e50e24dcca9e, keep that in mind for later.

Now I disconnect so I can connect with the gatt tool

[bluetooth]# disconnect CD:06:39:E6:6A:A7
Attempting to disconnect from CD:06:39:E6:6A:A7
Successful disconnected
[CHG] Device CD:06:39:E6:6A:A7 Connected: no
[bluetooth]# quit
[DEL] Controller B8:27:EB:F4:24:59 pi3.lan [default]

Connect using the GATT tool

$ gatttool -I -b CD:06:39:E6:6A:A7 -t random
[CD:06:39:E6:6A:A7][LE]> connect
Attempting to connect to CD:06:39:E6:6A:A7
Connection successful

This changes the logo on LEDs

micro:bit, connected

Taking a look at the UART service detail

[CD:06:39:E6:6A:A7][LE]> primary 6e400001-b5a3-f393-e0a9-e50e24dcca9e
Starting handle: 0x0021 Ending handle: 0xffff
[CD:06:39:E6:6A:A7][LE]> char-desc 0x0021 0xffff
handle: 0x0021, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0022, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0023, uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
handle: 0x0024, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0025, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0026, uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e

Two important descriptors in this service: 6e400002-b5a3-f393-e0a9-e50e24dcca9e is TX (bit-to-pi3), 6e400003-b5a3-f393-e0a9-e50e24dcca9e is RX (pi3-to-bit).

Descriptor 00002902-0000-1000-8000-00805f9b34fb is Client Characteristic Configuration, and lets you subscribe to notifications/indications from the device.

The other three descriptors are Primary Service and Characteristic Declaration. I'll skip over those for now.

I'm going to set the Client Characteristic Configuration to 0x0200 to subscribe to TX events.

[CD:06:39:E6:6A:A7][LE]> char-write-req 0x0024 0200
Characteristic value was written successfully

Now I get messages every time I press button A on the bit:

Indication   handle = 0x0023 value: 01
Indication   handle = 0x0023 value: 02
Indication   handle = 0x0023 value: 03
Indication   handle = 0x0023 value: 04
Indication   handle = 0x0023 value: 05

I can also read it directly:

[CD:06:39:E6:6A:A7][LE]> char-read-hnd 0x0023
Characteristic value/descriptor: 05

I can also write to the bit's UART:

[CD:06:39:E6:6A:A7][LE]> char-write-cmd 0x0026 0a

This changes the LEDs again

micro:bit, newline

Lastly, I disconnect

[CD:06:39:E6:6A:A7][LE]> disconnect
[CD:06:39:E6:6A:A7][LE]> quit

micro:bit, disconnect