- The new LEGO Powered Up Remote Control
- The BLE properties
First things first: the Remote Control BT Address and friendly name:
A4:34:F1:CE:DC:A2 “Handset”
The BT address is not a LEGO one like the BOOST (00:16:53, “LEGO System A/S IE Electronics Division”) or the Powered Up (90:84:2B, “LEGO System A/S”). It’s a Texas Instruments chipset, probably something like the CC2640, a ARM microcontroller with embedded BLE functions.
The usual browsing of properties with gatttool reveals 3 primary services and a few characteristics:
primary attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb attr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34fb attr handle: 0x0009, end grp handle: 0xffff uuid: 00001623-1212-efde-1623-785feabcd123
characteristics handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb handle: 0x000a, char properties: 0x1c, char value handle: 0x000b, uuid: 00001624-1212-efde-1623-785feabcd123
char-desc handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb handle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x0009, uuid: 00002800-0000-1000-8000-00805f9b34fb handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb handle: 0x000b, uuid: 00001624-1212-efde-1623-785feabcd123 handle: 0x000c, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x000d, uuid: 00002901-0000-1000-8000-00805f9b34fb
More details from the Nordic nRF Connect app:
The first primary service (1800, Genneric Access) has 3 chars:
Device Name: Handset
Appearance: Unknown
Peripheral Preferred Connection Parameters: Connection Interval: 100.00ms-200.00ms, Slave Latency:0, Supervision Timeout Multiplier: 1000
The second primary service (1801, Generic Attribute) is empty. Not unusual since it is optional.
The last primary service has the same UUID already present on BOOST and Powered Up hubs (i.e. “00001624-1212-efde-1623-785feabcd123”). And like those it has only one characteristic, “LWP ProtocolChar”.
(side note: LWP might mean Light Weight Process or LEGO Wireless Protocol or just Lets Worsen your Pain)
Thats good: since this “Handset” shares the same primary service UUID of the other PF2 / Powered Up devices, it might also work in the same way.
So lets enable notifications and see what we got:
char-write-req 0x0c 0100 Notification handle = 0x000b value: 0f 00 04 00 01 37 00 00 00 00 10 00 00 00 10 Notification handle = 0x000b value: 0f 00 04 01 01 37 00 00 00 00 10 00 00 00 10 Notification handle = 0x000b value: 0f 00 04 34 01 17 00 00 00 00 10 00 00 00 10 Notification handle = 0x000b value: 0f 00 04 3b 01 14 00 02 00 00 00 02 00 00 00 Notification handle = 0x000b value: 0f 00 04 3c 01 38 00 00 00 00 10 00 00 00 10
Yeap! 4 devices on 5 different ports:
- Device ’37’ on ports ’00’ and ’01’
- Device ’17’ present on port ’34’
- Device ’14’ present on port ‘3B’
- Device ’38’ present on port ‘3C’
Nathan already told me that device ’37’ is associated to the buttons. So two “pads” of buttons, one on port ’00’ and other on port ’01’.
Device ’17’ is the RGB LED on the BOOST. I’ll look to it later.
Device ’14’ and ’38’, like Nathan pointed, seem Voltage and Current readings. We can activate each with:
char-write-req 0x0b 0a0041[3B/3C]000100000001
The first (3B) will generate regular messages like ’06 00 45 3b a5 0b’ and the second (3C) also generates regular messages like ’05 00 45 3c cc’
So the payload is ‘3B A5 0B’ and ‘3C CC’, reverting and converting to decimal it gives
0BA53B = 763195 = 7.63 Volt ? hard to believe with just 4 AAA batteries
converting to float = 0.00503671 = 5.037 Volt? Perhaps
CC 3C = 52284 = 52 mA ? Why just two bytes and not 4? Hmm….
We can also deactivate with
char-write-req 0x0b 0a0041[3B/3C]000100000000
Really not important, at least for now. Let’s look to the button pads and the RGB LED and give them a good use:
char-write-req --handle 0x0b --value 080081341151000X
The command works like the BOOST (just changed the port, ’32’ to ’34’) and it accepts the same 10 values:
OFF=0 PINK=1 PURPLE=2 BLUE=3 LIGHTBLUE=4 LIGHTGREEN=5 GREEN=6 YELLOW=7 ORANGE=9 RED=9 WHITE=A
Once again, not sure about the color names but those above are good enough for me…
Now the buttons, we activate them with:
char-write-req 0x0b 0a004100000100000001 (Left or 'A') char-write-req 0x0b 0a004101000100000001 (Right or 'B')
so we now receive a notification each time there is a state change:
Left or A+ on then off:
05 00 45 00 01 05 00 45 00 00
Left or A- on then off:
05 00 45 00 ff 05 00 45 00 00
Left or A Red on then off:
05 00 45 00 7f 05 00 45 00 00
And the same happens for Right or B, just the fourth byte is now ’01’ instead of ’00’.
So we can use our new ‘Handset’ with whatever BLE capable device we want.
Next bash shell loops through the 10 RGB possible values:
#!/usr/bin/env bash #colors OFF=0 PINK=1 PURPLE=2 BLUE=3 LIGHTBLUE=4 LIGHTGREEN=5 GREEN=6 YELLOW=7 ORANGE=9 RED=9 WHITE=A function remoteLED () { gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0b --value 080081341151000$1 } # activate notifications and keep changing colors gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0c --value 0100 while : do for color in $OFF $PINK $PURPLE $BLUE $LIGHTBLUE $LIGHTGREEN $GREEN $YELLOW $ORANGE $RED $WHITE; do remoteLED $color sleep 1 done done
And the bash script for ev3dev from the last post:
#!/usr/bin/env bash # identify motors MOTORA=$(ls /sys/class/lego-port/port4/ev3-ports\:outA\:lego-ev3-l-motor/tacho-motor/) MOTORB=$(ls /sys/class/lego-port/port5/ev3-ports\:outB\:lego-ev3-l-motor/tacho-motor/) echo "outA:"$MOTORA echo "outB:"$MOTORB MOTORSPEED=1050 MOTORDELAY=0.1 # reset motor positions and initialize echo reset > /sys/class/tacho-motor/$MOTORA/command echo reset > /sys/class/tacho-motor/$MOTORB/command echo brake > /sys/class/tacho-motor/$MOTORA/stop_action echo $MOTORSPEED > /sys/class/tacho-motor/$MOTORA/speed_sp echo brake > /sys/class/tacho-motor/$MOTORB/stop_action echo $MOTORSPEED > /sys/class/tacho-motor/$MOTORB/speed_sp function finish { # terminate all subshells kill 0 # reset all motors echo reset > /sys/class/tacho-motor/$MOTORA/command echo reset > /sys/class/tacho-motor/$MOTORB/command } trap finish EXIT # activate left pad gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0b --value 0a004100000100000001 # activate right panel gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0b --value 0a004101000100000001 # activate notifications and keep listening while read -r line; do message=$( echo "$line" | cut -f2 -d: ) # echo "Line: $line" # echo "Msg: $message" if [[ $message = *"05 00 45 00 01"* ]]; then echo "L+ ON" echo $MOTORSPEED > /sys/class/tacho-motor/$MOTORB/speed_sp echo run-forever > /sys/class/tacho-motor/$MOTORB/command elif [[ $message = *"05 00 45 00 7f"* ]]; then echo "Lr ON" elif [[ $message = *"05 00 45 00 ff"* ]]; then echo "L- ON" echo -$MOTORSPEED > /sys/class/tacho-motor/$MOTORB/speed_sp echo run-forever > /sys/class/tacho-motor/$MOTORB/command elif [[ $message = *"05 00 45 00 00"* ]]; then echo "L Off" echo stop > /sys/class/tacho-motor/$MOTORB/command elif [[ $message = *"05 00 45 01 01"* ]]; then echo "R+ ON" echo $MOTORSPEED > /sys/class/tacho-motor/$MOTORA/speed_sp echo run-forever > /sys/class/tacho-motor/$MOTORA/command elif [[ $message = *"05 00 45 01 7f"* ]]; then echo "Rr ON" elif [[ $message = *"05 00 45 01 ff"* ]]; then echo "R- ON" echo -$MOTORSPEED > /sys/class/tacho-motor/$MOTORA/speed_sp echo run-forever > /sys/class/tacho-motor/$MOTORA/command elif [[ $message = *"05 00 45 01 00"* ]]; then echo "R Off" echo stop > /sys/class/tacho-motor/$MOTORA/command fi done < <(gatttool -b A4:34:F1:CE:DC:A2 --char-write-req --handle 0x0c --value 0100 --listen)
[edit]
Ooops, forgot that EV3 already has an internal BT interface. Sometimes this script works, sometimes don’t. That’s because I don’t specify which BT interface will be used by gatttool command. We should use ‘-i hci0’ or ‘-i hci1’ but sometimes the kernel decides that hci0 is the internal one, sometimes it decides that it is the USB one.
Perhaps a udev rule can force hci0 to always be the USB one, don’t know. Bad quickfix: remove the USB BT adapter and insert it again, this forces ev3dev to switch hci devices.