Notes on BLE communication with BRIO Smart Tech Sound train
Author: Chris Petrich, 25 Dec 2023.
License: CC-BY, https://creativecommons.org/licenses/by/4.0/
This repository is not affiliated with BRIO.
This document is about BRIO Smart Tech Sound as sold around 2023. The trains can be controlled
- via Bluetooth Low Energy (BLE) with the BRIO Smart Tech Sound App,
- 13.56 MHz RFID Action Tunnels such as those found in sets 33974 and 33972, or
- three buttons on the train (forward, stop, reverse).
A valid control event results in a sequence of one to ca. five BLE notifications in conjunction with a sequence of sound, light, and motion effects. These sequences are part of the firmware of the train, which can be updated with the app.
The trains are BLE peripherals (i.e. servers) that advertise themselves
as Smart 2.0
.
The service UUID is b11b0001-bf9b-4a20-ba07-9218fec577d7
,
and within this, the characteristic for commands to the train is
b11b0002-bf9b-4a20-ba07-9218fec577d7
, while
the characteristic for notifications from the train back to the BLE
client is b11b0003-bf9b-4a20-ba07-9218fec577d7
.
BLE commands and notifications are a string of unsigned 8-bit integers
framed by start byte 0xAA
and single-byte checksum, <C>
, at the end. The
checksum is calculated from the sum of the bytes of the command or notification
(i.e. without the start byte 0xAA
) as follows:
<C> = (0x100 - (Sum & 0xFF)) & 0xFF
Unknown commands or commands with checksum errors are silently ignored (i.e. no notifications are sent).
Among the list of recognized commands are
Command | Meaning |
---|---|
02:01:<speed> |
Set speed of train and play appropriate light and sound effects. |
03:56:AA:<effect> |
Stop train, set sound effect theme, and play sound. |
03:52:<b1>:<b2> |
App sends 5 startup messages with <b1> =M ,T ,Q ,W ,X , respectively, and <b2>=0x00 . |
06:06:00:00:<MSB>:<LSB> |
Start binary data transfer for firmware update. |
1x:50:<id>:<seq>:<type>:<payload> |
x={0 ,6 ,c }, <payload> =18 or 24 bytes. Firmware parameters of preceeding binary transfer. |
02:0a:0f |
End of firmware update. |
Commands are sent as Write Requests (CYBLE_EVT_GATTS_WRITE_REQ
),
except the 1x:50:...
commands and binary data, which are Write Commands (CYBLE_EVT_GATTS_WRITE_CMD_REQ
).
The train will send a notification in return to each command (i.e. not for binary data).
Train speed, <speed>
, is coded as
0x00
for "off",- values
0x01
to0x08
for forward, and - values
0x11
to0x18
for backward.
Currently, power with values 0x01
and 0x11
is too low to actually move the train.
The sound effect themes are coded depending on context:
Effect | <effect> |
<eff1> |
<eff2> |
<eff3> |
<eff4> |
---|---|---|---|---|---|
Honk | 0xf0 |
0x15 |
0x1d |
0x11 |
0x19 |
Whistle | 0xf1 |
0x16 |
0x1e |
0x12 |
0x1a |
Horn | 0xf2 |
0x17 |
0x1f |
0x13 |
0x1b |
Spaceship | 0xf3 |
0x18 |
0x20 |
0x14 |
0x1c |
Custom sound recordings are coded as, for example, 0x81
or 0x82
in <eff1>
.
The first notification message after pressing a button on the train is:
Button | First Notification |
---|---|
Stop | 02:80:01 |
Forward | 02:80:02 |
Backward | 02:80:03 |
The first notification when passing through an Action Tunnel is:
Action Tunnel | First Notification |
---|---|
"Stop" from forward | 08:81:02:00:00:<eff1>:91:3a:03 |
"Stop" from backward | 08:81:02:00:00:ef:0f:00:0f |
"Change direction" | 08:81:03:00:00:ef:0f:00:0f |
"Break" down from forward | 08:81:07:40:00:<eff2>:6f:31:20 |
"Break" down from backward | 08:81:07:40:00:<eff2>:6f:31:30 |
"Fix" without repair | 08:81:0c:00:00:<eff3>:f9:9a:<speed> |
"Fix" with repair, forward | 08:81:0c:00:00:ef:0f:00:03 |
"Fix" with repair, backward | 08:81:0c:00:00:ef:0f:00:0f |
double tunnel, top | 08:81:25:00:00:ef:df:aa:<speed> |
"Sound" (orange) | 08:81:39:00:00:87:01:3a:<speed> |
"Train Service Station", switch, forward | 08:81:4d:00:00:ef:df:aa:03 |
"Train Service Station", switch, backward | 08:81:4d:00:00:ef:3f:3a:13 |
"Train Service Station", washing, forward | 08:81:4e:00:00:ef:df:aa:03 |
"Train Service Station", washing, backward | 08:81:4e:00:00:ef:0f:00:0f |
"Train Service Station", repair, forward | 08:81:4f:00:00:ef:df:aa:03 |
"Train Service Station", repair, backward | 08:81:4f:00:00:ef:0f:00:0f |
"Rescue", forward | 08:81:54:00:00:ef:df:aa:03 |
"Rescue", backward | 08:81:54:00:00:ef:00:00:03 |
The fith byte (0x00
in all examples above) is a sequence number whenever
multiple notifications are emitted. The train action, number of notifications,
and the values from the sixth byte onward depend on the firmware version.
Action tunnel notifications are sent only if the train is in motion.
Apparently, notifications get sent after the actual action has already been initiated by the train, i.e. it does not seem to be possible to cleanly override the pre-programmed behavior by sending BLE commands (there may be train jerking and aborted sounds). Sending a command in response to a notification from an Action Tunnel may cause the train to detect the Action Tunnel again, leading to a loop that lasts until the train is out of range of the tunnel.
Byte String | Meaning |
---|---|
aa:02:01:08:f5 |
Full speed forward |
aa:02:01:02:fb |
Slowly forward |
aa:02:01:00:fd |
Stop the train |
aa:02:01:18:e5 |
Full speed backward |
aa:03:56:aa:f0:0d |
Set sound theme to "honk" (default) |
aa:03:56:aa:f1:0c |
Set sound theme to "whistle" |
In JavaScript, commands could be sent to the BLE peripheral like so:
characteristic.writeValue( new Uint8Array([0xaa,0x02,0x01,0x08,0xf5]) )
.
It follows a minimal code example to make the train move forward
using the Web Bluetooth API.
Read the Disclaimer at the end of this page before proceeding.
Copy text to a file with extension .html
and open in Chrome or Edge.
Turn on the BRIO Smart Tech Sound train, enable BLE on the computer
and click the button on the web page to initiate the pairing process.
Note that this will work only on Chrome and Edge.
<!DOCTYPE html>
<html>
<head>
<title>BLE test</title>
<meta name="author" content="Chris Petrich" />
</head>
<body>
<h1>BRIO Smart Tech Sound example for Chrome and Edge</h1>
<button onclick="connectBLE()">Click to Connect to Train and Start Driving</button>
<script>
const serviceUUID = "b11b0001-bf9b-4a20-ba07-9218fec577d7";
const commandCharacteristicUUID = "b11b0002-bf9b-4a20-ba07-9218fec577d7";
function connectBLE() {
navigator.bluetooth.requestDevice(
{ filters: [{ services: [serviceUUID] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService(serviceUUID))
.then(service => service.getCharacteristic(commandCharacteristicUUID))
.then(characteristic => characteristic.writeValue( new Uint8Array([0xaa,0x02,0x01,0x08,0xf5]) ));
}
</script>
</body>
</html>
Example notification sequence of a train going backward through the
"fix" tunnel while still being damaged from the "broken" tunnel.
Initial speed 0x18
, and sound effect 0xf0
(default).
aa:08:81:0c:00:00:ef:0f:00:0f:5e
aa:08:81:0c:00:01:ef:0f:00:03:69
aa:08:81:0c:00:02:21:c1:91:0f:e7
aa:08:81:0c:00:03:00:3f:3a:18:d7
aa:08:81:00:00:00:00:3f:3a:18:e6
I am not affiliated with BRIO. This is not an official documentation by BRIO. Information on this page are the result of some basic reverse engineering effort on my part, and results may contain errors. Information may be out of date as implementation and firmware of the trains could change at any time. Note that your train may get permanently unresponsive if you inadvertently initiate a firmware update. Use information in this repository at your own risk.
- Inspiration for this work came from the blog post Smart Track vs Smart Tech by
JohnM
from January 2020 at https://woodenrailway.info/blog/products/smart-track-vs-smart-tech - BLE sniffing for UUIDs and commands followed the instructions of Nordic Semiconductor for the nRF52840 Dongle.
- Notifications were received after connecting to a train with the Web Bluetooth API.