My original plan for the LEGO figure detector was to introduce some 'reaction', based on 'recognition' of certain characters. This part is about the working proof of concept 'reaction' part, that I plan to further develop later.
Back in 2014, a project on kickstarter called SBrick promised a smart way to control all your LEGO creations. So I ordered 2 bricks, got them delivered, but never had the time to build anything with them ... until I realized that in the Feature list of the Dev Board, there is Bluetooth 4.2.
I never did any programming that dealt with bluetooth, so had to spend some time to reading about it.
I've found a nice multiplatform Python library, bleak. In my case multiplatform
means Linux (for the board), and Mac for my development envrionment. See below how to install bleak on the Dev Board, and
'asyincio' as bleak is heavly depending on it.
IMPORTANT: to successfully compile bleak on the Dev Board, python3-dev must be installed!
# sudo apt-get install python3-dev # pip3 isntall asyncio bleak
After bleak installed, I created a 'discover.py' file, wich was just a simple copy of the 'scanning' section of the documentation. Had to execute it few times to discover the SBrick, and all my neighbours devices. Seems, they have a nice LG OLED and someone is using a Haylou Solar for running.
# python3 discover.py ... 00:07:80:2E:21:32: SBrick ... 64:AF:28:A4:8A:45: [LG] webOS TV OLED55B8PLA 78:02:B7:A7:44:70: Haylou Solar ...
Ok, discovered the SBrik, now let's try to contorll it. Should be simple following bleaks Usage documentation. Partly true, because to do so I had to read through SBricks BLE protocol documentation first. After some testing, I've found a good candidate to controll the motor: 6.49 Quick Drive / Notifications. Here is my test code:
import asyncio import platform from bleak import BleakClient SBRICK_ADDRESS = ( "00:07:80:2E:26:76" if platform.system() != "Darwin" else "2CB1FF56-D5BD-4A84-AD79-A214CEB79FCD" ) QUICK_DRIVE = "489A6AE0-C1AB-4C9C-BDB2-11D373C1B7FB" FULL_SPEED_FW = bytearray.fromhex('00 ff 00 00') FULL_SPEED_FW = bytearray.fromhex('00 fe 00 00') HALF_SPEED_FW = bytearray.fromhex('00 7f 00 00') HALF_SPEED_BW = bytearray.fromhex('00 7e 00 00') async def run(address): client = BleakClient(address) try: await client.connect() for t in range(1, 500): await client.write_gatt_char(QUICK_DRIVE, FULL_SPEED_FW) finally: await client.disconnect() loop = asyncio.get_event_loop() loop.run_until_complete(run(SBRICK_ADDRESS))
As you can see on one of the pictures above, I have several boards, so I deployed the code on 2 of those, and built a little concept LEGO 'crane'. One of the boards sent the command HALF_SPEED_FW, thereafter the other HALF_SPEED_BW.
I've spent several months with this concept, as I was not very active on implementing it. Writing this article helped
me to focus on the task again, and the success with the PoC gave some ideas how to further develop it.
... and for those who read till the end: look at the picture, with both boards. Now look at the color of the component over the network jack. Did you noticed that on one of the boards it's white, and on other it's yellow? That is because these are different type of boards, but that is a story for Part. V.