- WeDo 2.0 – reverse engineering
- WeDo 2.0 Battery Service
- WeDo 2.0 LED Button Service
- LEGO WeDo 2.0 – playing sound
- WeDo 2.0 colors with python (again)
- WeDo 2.0 Tilt Sensor
This post tries to gather all the information I collected in the last weeks related to the WeDo 2.0.
I’m not a programmer but I’m a very stubborn guy so after I managed to get my linux systems (my Ubuntu laptop, some Raspberry Pi’s and my two Mindstorms EV3) controlling the SBrick I told to myself: I’m gonna make the same with this new WeDo 2.0 system no matter what it takes.
So first things first: let’s use my Android mobile to inspect the WeDo 2.0 Hub. Nordic has a very good (and free) app that I like to use: nRF Master Control Panel (recently renamed to nRF Connect). After connecting to the Hub we find 6 services:
Some of this services, like “Battery Service” are known BLE services so [hopefully] it will be easy to use.
There’s also a very important finding at the top:
“U0001 A0:E6:F8:1E:58:57
“A0:E6:F8:1E:58:57” is the Bluetooth address of my Hub (similar to the MAC Address of every network device). It will be used *a lot* in the rest of this post.
And “U0001” is the friendly name that the Hub advertises – that’s the name that shows up in the LEGO Education WeDo 2.0 App when connecting to the Hub:
A note about this name: before I finally managed to make the LEGO Education WeDo 2.0 App work in my Android phone, my Hub advertised itself as “LPF2 Smart Hub 2 I/O”. So the LEGO App changed it to “u0001”, probably at the first time it connected to it (but since my Hub was first used by 3 other AFOL’s at Paredes de Coura I’m not sure if the process is automatic or the user is given some kind of option).
So the default (factory set) name of the Hub is “LPF2 Smart Hub 2 I/O” – LEGO Power Functions 2 Smart Hub 2 I/O”. Not much to speculate here: LEGO announced that Power Functions and Mindstorms will adopt a new plug type so new devices are expected, this is just the first one. But “Smart Hub 2 I/O” is interesting… does that means that there will be other Smart Hubs? Perhaps even a “Smart Hub 4 I/O”? That would answer some of the points I have been discussing with Fernando Conchas like “what’s the use for a 4.5 Volt device in LEGO Technic unless there’s also another device with better power features just waiting to come out”?
Now let’s look deeper to those BLE services…
I can use the nRF App and take a lot of screenshots but now that I know the BT address I will switch to my Ubuntu laptop and use 2 of the available BlueZ (the native Linux Bluetooth stack) functions, ‘hcitool’ and ‘gatttool’
$ sudo hcitool -i hci0 lescan LE Scan ... A0:E6:F8:1E:58:57 (unknown) A0:E6:F8:1E:58:57 LPF2 Smart Hub 2 I/O
sudo gatttool -i hci0 -b A0:E6:F8:1E:58:57 --primary attr handle = 0x0001, end grp handle = 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb attr handle = 0x0008, end grp handle = 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb attr handle = 0x000c, end grp handle = 0x002f uuid: 00001523-1212-efde-1523-785feabcd123 attr handle = 0x0030, end grp handle = 0x003e uuid: 00004f0e-1212-efde-1523-785feabcd123 attr handle = 0x003f, end grp handle = 0x0045 uuid: 0000180a-0000-1000-8000-00805f9b34fb attr handle = 0x0046, end grp handle = 0xffff uuid: 0000180f-0000-1000-8000-00805f9b34fb
The ‘gatttool’ command is a powerfull tool for BLE – in the past, without a proper BLE library for python, I used it (through python system calls) to talk with the SBrick. Clumsy but… hey, I said I’m not a programmer 😉
The ‘gatttool’ can run in an interactive mode that allows us to establish a connection and keep it until we disconnect instead of making a new connection each time we want to test a command:
$ sudo gatttool -i hci0 -I [ ][LE]> connect A0:E6:F8:1E:58:57 Attempting to connect to A0:E6:F8:1E:58:57 Connection successful [A0:E6:F8:1E:58:57][LE]>
In this “interactive” session we just send ‘primary’ to get the same output as using the command with ‘–primary’ option [but sometimes the commands differ a bit, so use ‘help’ and ‘–help’ to know what to use.
So the ‘primary’ command gets a list of the primary services offered by the WeDo 2.0 Hub. Of course, those are the same 6 services found by the Nordic app but that screenshot looks much better as Nordic developers added lots of intelligence to it.
First service:
attr handle = 0x0001, end grp handle = 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
The Nordic app shows just:
Generic Access
UUID: 0x1800
PRIMARY SERVICE
So this service has 7 handles assigned (from 0x0001 to 0x0007) and serves a well know service (the ‘Generic Access‘) so it’s UUID is shortened to just 0x1800 instead of ‘00001800-0000-1000-8000-00805f9b34fb’.
Bluetooth specification for ‘Generic Access’ defines 5 properties:
- Device Name (0x2A00)
- Appearance (0x2A01)
- Peripheral Privacy Flag (0x2A02)
- Reconnection Address (0x2A03)
- Peripheral Preferred Connection Parameters (0x2A04)
From these list, only ‘Device Name’ and ‘Appearance’ are defined as ‘Mandatory’.
With the gatttool we read these properties with command ‘char-read-uuid’:
[A0:E6:F8:1E:58:57][LE]> char-read-uuid 0x2A00 handle: 0x0003 value: 75 30 30 30 31 [A0:E6:F8:1E:58:57][LE]> char-read-uuid 0x2A01 handle: 0x0005 value: 00 00 [A0:E6:F8:1E:58:57][LE]> char-read-uuid 0x2A02 Error: Read characteristics by UUID failed: No attribute found within the given range [A0:E6:F8:1E:58:57][LE]> char-read-uuid 0x2A03 Error: Read characteristics by UUID failed: No attribute found within the given range [A0:E6:F8:1E:58:57][LE]> char-read-uuid 0x2A04 handle: 0x0007 value: 50 00 a0 00 00 00 e8 03
So ‘Peripheral Privacy Flag’ and ‘Reconnection Address’ were not implemented by LEGO. But what’s the meaning of this hexadecimal values?
‘Device Name‘ is a string so we just convert it to ASCII (we can use an online tool like RapidTables):
75 30 30 30 31 -> u0001
Ah-ha!
‘Appearance‘ is two-byte value “composed of a category (10-bits) and sub-categories (6-bits)” that classifies the device. Since it is ‘0’, it’s not classified in any known category (so it is ‘Unknown’).
‘Peripheral Preferred Connection Parameters‘ is an 8-byte value containing 4 parameters (each one is 2-byte):
Minimum Connection Interval
Maximum Connection Interval
Slave Latency
Connection Supervision Timeout Multiplier
Each value is written in reverse order so
Minimum Connection Interval =005h = 80d
Maximum Connection Interval = 000ah = 160
Slave Latency = 0
Connection Supervision Timeout Multiplier = 03e8h=1000d
According to definition, the Min/Max Connection Interval values should be multiplied by 1.25 so the range is in fact 100~200 [ms].
So let’s return to the Android and validate these:
Yes, it certainly looks good!
Next post we’ll see another well-know service: the ‘Battery Service’.