jorgepe / boostreveng Goto Github PK
View Code? Open in Web Editor NEWReverse engineering the LEGO BOOST Hub
License: MIT License
Reverse engineering the LEGO BOOST Hub
License: MIT License
What would it take to wrap up all this low level code into a nice python package? We have enough info for that yet?
There are lots of blocks in the App. I understand the purpose of most but there a few I am not sure (having a small phone instead of a tablet doesn't help).
Even when knowing the purpose of a block, I don't know the proper way to refer it unless call it "the 13th orange block from the left".
I have put a few screenshots in [this folder] (https://github.com/JorgePe/BOOSTreveng/tree/master/LEGO_BOOST_App_blocks) and I was thinking on creating some kind of page with an explanation of all blocks.
Hi, I always have the following error :
Runtime error : Failed resolution of : Lcom/google/common/collect/Lists;
using the list in the WriteBytesWithResponse block.
I read it was a known error and Evan Patton seems to work on it but as you seems to have succeeded I guess you found a way to make it work with the current version.
Could you indicate how ?
Thanks for your nice work.
I just made an interesting discovery about the BLE manufacturer-specific advertising data on the BOOST Move Hub and Powered Up Smart Hub.
The first byte seems to indicate the button position. Normally it is 0x00, but if the button is pressed, it changed to 0x01. (On the Smart Hub, some of the other bytes change too, but I haven't figured out what that means).
Here are some other speculations:
Hub | Boot Mode | Example Advertising Data |
---|---|---|
Move Hub | Normal | 0x004006FE4100, 0x014006FE4100 |
Move Hub | Firmware Update | 0x000000104002 |
Smart Hub | Normal | 0x004107004300, 0x014107006300 |
Smart Hub | Firmware Update | 0x000000104002 |
Handset | Normal | 0x00420A134100, 0x01420A004100, 0x00420A006100 |
Interpretation of Normal mode data:
Interpretation of Firmware Update mode data:
Note: Firmware Update mode is what you get when you press and hold the button for 5 seconds when powering on and the light turns pale purple. Once a connection is made, the lights change to alternating red, green, blue to indicate that firmware update is in progress. The Handset does not have bluetooth active in this mode, so presumably the firmware cannot be updated on that device - it just seems this is used to reset the channel selection.
Anyone have any other insights? Anyone have a Duplo hub (what is the advertising data there)?
Color Sensor says:
2nd, 3rd and 4th bytes = 00 45 01 are still unknown
I think the second byte might be the high byte of the length, there are just no packets longer than 0xFF yet. Or reserved, not sure.
The 3rd byte is quite clearly the packet type.
The 4th byte seems to be the port (as registered by the 0x4 packets). 0x01, the color-distance sensor, at least in my setup.
Hi everybody,
found this project via a german computer magazine report (c‘t) and would like to contribute. I started with the readme and found the slack invite code to be invalid:
https://join.slack.com/t/legoboost/shared_invite/MjMxNzYxMTIwNzM3LTE1MDM4MjU4NTEtNGQwNWQwNDk5NQ
Perhaps one of the admins could generate a new one?
Thanks and regards
Tom
To further help (a little) in reverse engineering the protocol: Looking at all the example commands, the first byte must be the total number of bytes in the command:
I've been spying on my BOOST Color and Distance sensor
Like EV3 UART sensors, Powered Up UART devices (can't say "sensors" anymore since BOOST Interactive Motor is also UART) send data about the device at 2400 baud until the brick syncs with the device.
Here is the data that I captured and the interpretation according to lms2012.h and d_uart_mod.c.
40 MESSAGE_CMD + LENGTH_1 + CMD_TYPE 25 Type = 37; BOOST Color and Distance Sensor 9a checksum; 0xff ^ 0x40 ^ 0x25 51 MESSAGE_CMD + LENGTH_4 + CMD_MODES (similar to EV3 CMD_MODES with 2 extra bytes) 07 7 + 1; Modes = 8 (value used on EV3) 07 7 + 1; Views = 8 (value used on EV3) 0a 10 + 1; Modes = 11 (value used on Powered Up) 07 7 + 1; Views = 8 (value used on Powered Up) a3 checksum; 0xff ^ 0x51 ^ 0x07 ^ 0x07 ^ 0x0a ^ 0x07 52 MESSAGE_CMD + LENGTH_4 + CMD_SPEED 00 LSB c2 .. 01 .. 00 MSB; BitRate = 115200 6e checksum; 0xff ^ 0x52 ^ 0x00 ^ 0xc2 ^ 0x01 ^ 0x00 5f MESSAGE_CMD + LENGTH_8 + CMD_UNK1 (new PF2 command) 00 LSB 00 .. 00 .. 10 MSB; ??? = 0x10000000 00 LSB 00 .. 00 .. 10 MSB; ??? = 0x10000000 a0 checksum; 0xff ^ 0x5f ^ 0x00 ^ 0x00 ^ 0x10 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x10 9a MESSAGE_INFO + LENGTH_8 + MODE_2; really mode 10 20 MODE_PLUS_8 + INFO_NAME 43 'C' 41 'A' 4c 'L' 49 'I' 42 'B' 00 '' 00 '' 00 ''; Name = "CALIB" 00 checksum; 0xff ^ 0x9a ^ 0x20 ^ 0x43 ^ 0x41 ^ 0x4c ^ 0x49 ^ 0x42 ^ 0x00 ^ 0x00 ^ 0x00 9a MESSAGE_INFO + LENGTH_8 + MODE_2; really mode 10 21 MODE_PLUS_8 + INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB ff .. 7f .. 47 MSB; RawMax = 65535.0 83 checksum; 0xff ^ 0x9a ^ 0x21 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0xff ^ 0x7f ^ 0x47 9a MESSAGE_INFO + LENGTH_8 + MODE_2; really mode 10 22 MODE_PLUS_8 + INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 cd checksum; 0xff ^ 0x9a ^ 0x22 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0xc8 ^ 0x42 9a MESSAGE_INFO + LENGTH_8 + MODE_2; really mode 10 23 MODE_PLUS_8 + INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB ff .. 7f .. 47 MSB; SiMax = 65535.0 81 checksum; 0xff ^ 0x9a ^ 0x23 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0x00 ^ 0xff ^ 0x7f ^ 0x47 92 MESSAGE_INFO + LENGTH_4 + MODE_2; really mode 10 24 MODE_PLUS_8 + INFO_SYMBOL 4e 'N' 2f '/' 41 'A' 00 ''; Symbol = "N/A" 69 checksum; 0xff ^ 0x92 ^ 0x24 ^ 0x4e ^ 0x2f ^ 0x41 ^ 0x00 8a MESSAGE_INFO + LENGTH_2 + MODE_2; really mode 10 25 MODE_PLUS_8 + INFO_UNK1 (new PF2 info) 10 ??? 00 ??? 40 checksum; 0xff ^ 0x8a ^ 0x25 ^ 0x10 ^ 0x00 92 MESSAGE_INFO + LENGTH_4 + MODE_2; really mode 10 a0 MODE_PLUS_8 + INFO_FORMAT 08 DataSets = 8 01 Format = DATA16 05 Figures = 5 00 Decimals = 0 c1 checksum; 0xff ^ 0x92 ^ 0xa0 ^ 0x08 ^ 0x01 ^ 0x05 ^ 0x00 99 MESSAGE_INFO + LENGTH_8 + MODE_1; really mode 9 20 MODE_PLUS_8 + INFO_NAME 44 'D' 45 'E' 42 'B' 55 'U' 47 'G' 00 '' 00 '' 00 ''; Name = "DEBUG" 17 checksum 99 MESSAGE_INFO + LENGTH_8 + MODE_1; really mode 9 21 MODE_PLUS_8 + INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB c0 .. 7f .. 44 MSB; RawMax = 1023.0 bc checksum 99 MESSAGE_INFO + LENGTH_8 + MODE_1; really mode 9 22 MODE_PLUS_8 + INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 ce checksum 99 MESSAGE_INFO + LENGTH_8 + MODE_1; really mode 9 23 MODE_PLUS_8 + INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; SiMax = 10.0 24 checksum 91 MESSAGE_INFO + LENGTH_4 + MODE_1; really mode 9 24 MODE_PLUS_8 + INFO_SYMBOL 4e 'N' 2f '/' 41 'A' 00 ''; Symbol = "N/A" 6a checksum 89 MESSAGE_INFO + LENGTH_2 + MODE_1; really mode 9 25 MODE_PLUS_8 + INFO_UNK1 (new PF2 info) 10 ??? 00 ??? 43 checksum 91 MESSAGE_INFO + LENGTH_4 + MODE_1; really mode 9 a0 MODE_PLUS_8 + INFO_FORMAT 02 DataSets = 2 01 Format = DATA16 05 Figures = 5 00 Decimals = 0 c8 checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0; really mode 8 20 MODE_PLUS_8 + INFO_NAME 53 'S' 50 'P' 45 'E' 43 'C' 20 ' ' 31 '1' 00 '' 00 ''; "SPEC 1" 53 checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0; really mode 8 21 MODE_PLUS_8 + INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. 7f .. 43 MSB; RawMax = 255.0 7a checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0; really mode 8 22 MODE_PLUS_8 + INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 cf checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0; really mode 8 23 MODE_PLUS_8 + INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. 7f .. 43 MSB; SiMax = 255.0 78 checksum 90 MESSAGE_INFO + LENGTH_4 + MODE_0; really mode 8 24 MODE_PLUS_8 + INFO_SYMBOL 4e 'N' 2f '/' 41 'A' 00 ''; Symbol = "N/A" 6b checksum 88 MESSAGE_INFO + LENGTH_2 + MODE_0; really mode 8 25 MODE_PLUS_8 + INFO_UNK1 (new PF2 info) 00 ??? 00 ??? 52 checksum 90 MESSAGE_INFO + LENGTH_4 + MODE_0; really mode 8 a0 MODE_PLUS_8 + INFO_FORMAT 04 DataSets = 4 00 Format = DATA8 03 Figures = 3 00 Decimals = 1 c8 checksum 9f MESSAGE_INFO + LENGTH_8 + MODE_7 00 INFO_NAME 49 'I' 52 'R' 20 ' ' 54 'T' 78 'x' 00 '' 00 '' 00 ''; "IR Tx" 77 checksum 9f MESSAGE_INFO + LENGTH_8 + MODE_7 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB ff .. 7f .. 47 MSB; RawMax = 65535.0 a6 checksum 9f MESSAGE_INFO + LENGTH_8 + MODE_7 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 e8 checksum 9f MESSAGE_INFO + LENGTH_8 + MODE_7 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB ff .. 7f .. 47 SiMax = 65535.0 a4 checksum 97 MESSAGE_INFO + LENGTH_4 + MODE_7 04 INFO_NAME 4e 'N' 2f '/' 41 'A' 00 ''; Symbol = "N/A" 4c checksum 8f MESSAGE_INFO + LENGTH_2 + MODE_7 05 INFO_UNK1 00 ??? 04 ??? 71 checksum 97 MESSAGE_INFO + LENGTH_4 + MODE_7 80 INFO_FORMAT 01 DataSets = 1 01 Format = DATA16 05 Figures = 5 00 Decimals = 0 ed checksum 9e MESSAGE_INFO + LENGTH_8 + MODE_6 00 INFO_NAME 52 'R' 47 'G' 42 'B' 20 ' ' 49 'I' 00 '' 00 '' 00 ''; Name = "RGB I" 5f checksum 9e MESSAGE_INFO + LENGTH_8 + MODE_6 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB c0 .. 7f .. 44 MSB; RawMax = 1023.0 9b checksum 9e MESSAGE_INFO + LENGTH_8 + MODE_6 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 e9 checksum 9e MESSAGE_INFO + LENGTH_8 + MODE_6 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB c0 .. 7f .. 44 MSB = 1023.0 99 checksum 96 MESSAGE_INFO + LENGTH_4 + MODE_6 04 INFO_SYMBOL 52 'R' 41 'A' 57 'W' 00 ''; Symbol = "RAW" 29 checksum 8e MESSAGE_INFO + LENGTH_2 + MODE_6 05 INFO_UNK1 10 ??? 00 ??? 64 checksum 96 MESSAGE_INFO + LENGTH_4 + MODE_6 80 INFO_FORMAT 03 DataSets = 3 01 Format = DATA16 05 Figures = 5 00 Decimals = 0 ee checksum 9d MESSAGE_INFO + LENGTH_8 + MODE_5 00 INFO_NAME 43 'C' 4f 'O' 4c 'L' 20 ' ' 4f 'O' 00 '' 00 '' 00 ''; Name = "COL O" 4d checksum 9d MESSAGE_INFO + LENGTH_8 + MODE_5 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; RawMax = 10.0 02 checksum 9d MESSAGE_INFO + LENGTH_8 + MODE_5 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 ea checksum 9d MESSAGE_INFO + LENGTH_8 + MODE_5 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; SiMax = 10.0 00 checksum 95 MESSAGE_INFO + LENGTH_4 + MODE_5 04 INFO_SYMBOL 49 'I' 44 'D' 58 'X' 00 ''; Symbol = "IDX" 3b checksum 8d MESSAGE_INFO + LENGTH_2 + MODE_5 05 INFO_UNK1 00 ??? 04 ??? 73 checksum 95 MESSAGE_INFO + LENGTH_4 + MODE_5 80 INFO_FORMAT 01 DataSets = 1 00 Format = DATA8 03 Figures = 3 00 Decimals = 0 e8 checksum 94 MESSAGE_INFO + LENGTH_4 + MODE_4 00 INFO_NAME 41 'A' 4d 'M' 42 'B' 49 'I'; Name = 'AMBI' 6c checksum 9c MESSAGE_INFO + LENGTH_8 + MODE_4 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; RawMax = 100.0 e8 9c MESSAGE_INFO + LENGTH_8 + MODE_4 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 eb checksum 9c MESSAGE_INFO + LENGTH_8 + MODE_4 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; SiMax = 100.0 ea checksum 94 MESSAGE_INFO + LENGTH_4 + MODE_4 04 INFO_SYMBOL 50 'P' 43 'C' 54 'T' 00 ''; Symbol = 'PCT' 28 checksum 8c MESSAGE_INFO + LENGTH_2 + MODE_4 05 INFO_UNK1 10 ??? 00 ??? 66 checksum 94 MESSAGE_INFO + LENGTH_4 + MODE_4 80 INFO_FORMAT 01 DataSets = 1 00 Format = DATA8 03 Figures = 3 00 Decimals = 0 e9 checksum 9b MESSAGE_INFO + LENGTH_8 + MODE_3 00 INFO_NAME 52 'R' 45 'E' 45 'F' 4c 'L' 54 'T' 00 '' 00 '' 00 ''; Name = "REFLT" 2d checksum 9b MESSAGE_INFO + LENGTH_8 + MODE_3 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; RawMax = 100.0 ef checksum 9b MESSAGE_INFO + LENGTH_8 + MODE_3 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 ec checksum 9b MESSAGE_INFO + LENGTH_8 + MODE_3 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; SiMax = 100.0 ed checksum 93 MESSAGE_INFO + LENGTH_4 + MODE_3 04 INFO_SYMBOL 50 'P' 43 'C' 54 'T' 00 ''; Symbol = "PCT" 2f checksum 8b MESSAGE_INFO + LENGTH_2 + MODE_3 05 INFO_UNK1 10 ??? 00 ??? 61 checksum 93 MESSAGE_INFO + LENGTH_4 + MODE_3 80 INFO_FORMAT 01 DataSets = 1 00 Format = DATA8 03 Figures = 3 00 Decimals = 0 ee checksum 9a MESSAGE_INFO + LENGTH_8 + MODE_2 00 INFO_NAME 43 'C' 4f 'O' 55 'U' 4e 'N' 54 'T' 00 '' 00 '' 00 ''; Name = "COUNT" 26 checksum 9a MESSAGE_INFO + LENGTH_8 + MODE_2 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; RawMax = 100.0 ee checksum 9a MESSAGE_INFO + LENGTH_8 + MODE_2 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 ed checksum 9a MESSAGE_INFO + LENGTH_8 + MODE_2 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; SiMax = 100.0 ec checksum 92 MESSAGE_INFO + LENGTH_4 + MODE_2 04 INFO_SYMBOL 43 'C' 4e 'N' 54 'T' 00 ''; Symbol = "CNT" 30 checksum 8a MESSAGE_INFO + LENGTH_2 + MODE_2 05 INFO_UNK1 08 ??? 00 ??? 78 checksum 92 MESSAGE_INFO + LENGTH_4 + MODE_2 80 INFO_FORMAT 01 DataSets = 1 02 Format = DATA32 04 Figures = 4 00 Decimals = 0 ea checksum 91 MESSAGE_INFO + LENGTH_4 + MODE_1 00 INFO_NAME 50 'P' 52 'R' 4f 'O' 58 'X'; Name = "PROX" 7b checksum 99 MESSAGE_INFO + LENGTH_8 + MODE_1 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; RawMax = 10.0 06 checksum 99 MESSAGE_INFO + LENGTH_8 + MODE_1 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 ee checksum 99 MESSAGE_INFO + LENGTH_8 + MODE_1 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; SiMax = 10.0 04 checksum 91 MESSAGE_INFO + LENGTH_4 + MODE_1 04 INFO_SYMBOL 44 'D' 49 'I' 53 'S' 00 ''; Symbol = "DIS" 34 checksum 89 MESSAGE_INFO + LENGTH_2 + MODE_1 05 INFO_UNK1 50 ??? 00 ??? 23 checksum 91 MESSAGE_INFO + LENGTH_4 + MODE_1 80 INFO_FORMAT 01 DataSets = 1 00 Format = DATA8 03 Figures = 3 00 Decimals = 0 ec checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0 00 INFO_NAME 43 'C' 4f 'O' 4c 'L' 4f 'O' 52 'R' 00 '' 00 '' 00 ''; Name = "COLOR" 3a checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0 01 INFO_RAW 00 LSB 00 .. 00 .. 00 MSB; RawMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; RawMax = 10.0 07 checksum 98 MESSAGE_INFO + LENGTH_8 + MODE_0 02 INFO_PCT 00 LSB 00 .. 00 .. 00 MSB; PctMin = 0.0 00 LSB 00 .. c8 .. 42 MSB; PctMax = 100.0 ef 98 MESSAGE_INFO + LENGTH_8 + MODE_0 03 INFO_SI 00 LSB 00 .. 00 .. 00 MSB; SiMin = 0.0 00 LSB 00 .. 20 .. 41 MSB; SiMax = 10.0 05 checksum 90 MESSAGE_INFO + LENGTH_4 + MODE_0 04 INFO_SYMBOL 49 'I' 44 'D' 58 'X' 00 ''; Symbol = "IDX" 3e checksum 88 MESSAGE_INFO + LENGTH_2 + MODE_0 05 INFO_UNK1 c4 ??? 00 ??? b6 checksum 90 MESSAGE_INFO + LENGTH_4 + MODE_0 80 INFO_FORMAT 01 DataSets = 1 00 Format = DATA8 03 Figures = 3 00 Decimals = 0 ed checksum 88 MESSAGE_INFO + LENGTH_2 + MODE_0 06 INFO_UNK2 (second new PF2 info - others are 05) 4f ??? 00 ??? 3e checksum 04 MESSAGE_SYS + BYTE_ACK 00 MESSAGE_SYS + BYTE_SYNC
I’m a little stuck w/ the interactive motor. The angle based motor movement works kinda ok, but if I move forward and backward by say 40 degrees, the movement isn’t exact (also it is a move-by, not a move-to-angle). i.e. Vernie’s head doesn’t end up in the same position.
My assumption was that the interactive motto should be able to do this? And maybe even report the current position (but subscribing to the port values on 0x2 gives seemingly random values?)
However, it seems like the iPad app can do this. Shaking the head, it always seems to return the head to the 0-degree position.
It would be great to get some packets which reveal how to do this. I would think there is either a different command than the angle-one we currently have (a turn(to: angle) instead of turn(by: angle)), or there are notifications which report the current angle (so that the application can adjust it until it hits 0-degree).
Thanks! :-)
Just for your information:
My BOOST Move Hub got firmware update from lego recently and
BLE protocol seems to have changed.
For example, motors command now has length 15(0x0f).
cmd=0f008110110cc2010000cece647f03
Hi Jorge,
Do you happen to know/are you able to measure the resistance for the AutoID on the train motor?
I ask as using a 2k2 resistor should mimic a WeDo motor, but when used with a Powered UP controller, this will result in "bang-bang" style on/off operation. If we can mimic a train motor instead, then it will allow continuous variable power to be provided when using a PUP controller.
Cheers,
Nathan
I have a doubt: is it possible to read yaw with the App?
I mean, with the Move Hub always horizontal, measure when it rotates left or right?
I can read roll and pitch but not yaw. Both with the App and directly through gatttool.
I was expecting that a 6-axis tilt sensor would get all 3 types of movement.
This works from Ubuntu 17.04 shell:
gatttool -b 00:16:53:A4:CD:7E --char-write-req --handle=0x0e --value=0c018139110a00069B9B647f03
This doesn't:
#!/usr/bin/env python3
from gattlib import GATTRequester, GATTResponse
from time import sleep
req = GATTRequester("00:16:53:A4:CD:7E",True,"hci0")
response = GATTResponse()
req.write_by_handle_async(0x0e, "\x0C\x01\x81\x39\x11\x0A\x00\x06\x9B\x9B\x64\x7F\x03", response)
while not response.received():
sleep(0.1)
print(response.received())
print(req.read_by_handle(0x0e))
Output:
['\x13']
['\x0c\x01\x819\x11\n\x00\x06\x9b\x9bd\x7f\x03']
Also replacing with a shorter command like changing LED color
gatttool -b 00:16:53:A4:CD:7E --char-write-req --handle=0x0e --value=080081321151000A
returns
['\x13']
['\x08\x00\x812\x11Q\x00\n']
Something is wrong after 3rd byte ?!?
Confirmed that you can drive motor plugged into D with 02. (from the Boost Remote app code, and tested with gatttool)
Hi @JorgePe ,
nice that you did this work !
I just wanted to let you know that I found another way of programming it directly from an iPad or iPhone in python.
Just in case you don't have your mac, notebook or raspberry pi with you. ;-)
https://github.com/mithrendal/boostanista
best regards
Haven't bought yet, just query. Thanks for your work.
@JorgePe FYI, this is helpful for giving the blocks names
http://uploads.brickset.com/docs/legoboostcoding.pdf
In particular 0x39 is described as 'move hub' rather than 'motor'
Hi Jorge,
first of all: many thanks for publishing your findings!
I wanted to leave a note here that I started to implement a Node.js module based on your work:
https://github.com/hobbyquaker/node-movehub - contributions welcome :-)
Regards,
Sebastian
A Slack would be nice to talk about stuff? I made a LegoBoost one, want to use this? Just let me know so I can add people.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.