LEGO IoT Train

This post is part 1 of 3 of  LEGO IoT Train

This recente release of LEGO EV3 MicroPyhton using ev3dev keeps amazing me. I think that most people didn’t realize the truly meaning of having a full modern operating system under the hood. And also the great work that David Lechner and all others (sorry, too many to name here) have been doing with and around ev3dev.

A few months ago I’ve been playing with the 4DBrix WiFi Train Controller. I already had bought some 4DBrix custom monorail parts including some small RC Servos that they sell in a LEGO-compatible form factor. When ordering a few more extra parts for my Conveyex project I noticed an interesting thing about their WiFi Train Controller – it used MQTT. Well, well, well… a LEGO-compatible RC controller that uses a non proprietary protocol and even better over WiFi, something I’ve been doing with NodeMCU but ‘out of the box’ and not too expensive.

[long dissertation]

Bluetooth and Bluetooth Low Energy (BLE) are great for gadgets but I’m still not convinced. Yes, been a beta tester of SBrick, had reverse engineered part of WeDo2, BOOST and Powered Up… but still think that BLE is not for robotics or even large IoT.

Bluetooth (standard or BLE) requires “a session”. Once a master device connects to a slave, no additional session can be created to that slave. So it’s great to keep reading data from a sensor but not to so great when you need to ‘time share’ to several masters – you need to release the session, that’s OK with SBrick because it keeps working and waiting for further sessions but it’s not OK with LEGO smart hubs because they shut off after a few seconds to save energy.

BLE beacons like iBeacon and Estimote announce all the needed data so a session isn’t needed but to save energy the frequency of the announcement is kept low. Ideally BLE devices should reduce energy consumption while waiting for a session to be stablished but that would increase latency so not so good for robotics and automation: most of the times, if you need to take a decisiona based on remote data or even worst stop a motor you cannot afford to wait.

Also Bluetooth is ‘point-to-point’, like Infra Red RC. Yes, since it’s radio it works through walls and is resiliant to room light conditions… but you cannot route it. If you have many devices to access/control you will find that there is a limit in the number of simultaneous sessions that you BLE controller can sustain (BLED112 states 8, Cambridge CSR just 5). So if you reach that limit on your smartphone or your limited tablet… you’re done. On a laptop or desktop computer you can add extra BLE dongles but then you start dwelling with your operating system idiosyncrasies (Windows guys, I feel your pain).

Now I am not saying that WiFi is the best solution as there are other very interesting wireless technologies like Zigbee and LoRa… but they are not wide spread as WiFi: my smartphone has WiFi, my laptop has WiFi, my SmartTV has WiFi… even my EV3 has WiFi!

[end of dissertation]

So I ordered one of this little fellows and it worked fine:

But I forgot to talk about it here, only wrote a post on Eurobricks forum about it. So now that I have MQTT working out of the box with this LEGO EV3 MicroPython it’s time to get back to the 4DBrix WiFi Train Controller.

4DBrix has a nice tool nControl to design train/monorail track layouts and also control them with their own controllers. It’s available for free download, you just need to give our e-mail and agree with their terms (essentially some fair use conditions including not redistributing it). There are versions for several platforms including Raspberry Pi’s Raspbian and Ubuntu. This tool is needed to configure the WiFi Controller through the USB port and also to eventually upgrade it’s firmware.

On linux, nControl looks for a connected WiFi Controller on ‘/dev/ttyUSB###’. Last year I had a problem with having more than one of this devices already defined so I needed to remove all before connect it:

sudo rm /dev/ttyUSB*

Not sure if this is still needed (4DBrix keeps upgrading the tool, it’s now in version 2019-0-409) but it doesn’t hurt.

After nControl finds the connected WiFi Train Controller (‘/dev/ttyUSB3’) we can configure it to work with our WiFi network and also chose an Alias and a MQTT Broker:

Alias: 4DB2
WiFi Network: SSID
WiFi Password: ****
MQTT Broker: -> use this system => 192.168.1.87

The Alias is important because the internal MQTT client will subscribe to the topic ‘nControl/Alias’. So in my case ‘nControl/4DB2’ (I also have a 4DB1, the first Controller I received had an internal thermal problem with the power regulator so they sent me a second one).

We can specify any MQTT Broker like ‘test.mosquitto.org’ but there is also a ‘Use this system’ option where it finds the IP address of our computer and use it. That’s also usefull because nControl has its own MQTT Broker (based on ‘hbmqtt’ instead of ‘mosquitto’ and requiring authentication so not useful for open IoT projects

Although nControl as an option to verify that the applied configuration is working properly I found no way to know the IP address that the WiFi Train Controller gets so I had to go to my WiFi router and check for connected devices:

ESP_093471 192.168.1.112

The hostname starts with ‘ESP_’ (the device uses a ESP8266 chipset like the NodeMCU board I’ve been using) and got IP ‘192.168.1.112’… not that I need it’s IP address but might be useful for debugging eventual problems later

So I can now control a LEGO motor with it – disconnect USB cable, connect a LEGO battery and motor, power the device on and test it:

mosquitto_pub -h localhost -t "nControl/4DB2" -m "mot,f,1023"

the motor should spin at maximum speed in one direction. To make it spin in the opposite direction:

mosquitto_pub -h localhost -t "nControl/4DB2" -m "mot,b,1023"

And to stop it:

mosquitto_pub -h localhost -t "nControl/4DB2" -m "mot,f,1023"

or just:

mosquitto_pub -h localhost -t "nControl/4DB2" -m "mot,s"

There are a few other commands available but these are enough for what I want

So controlling a LEGO motor with EV3 through WiFi is just a matter of writing opening Visual Studio Code and write a short MicroPython script that publishes the proper messages to ‘nControl/4DB2’ topic.

Since MQTT is not ‘session’ based like Bluetooth we can use multiple Ev3 to control it. So a LEGO train can run over a long track and place several EV3 pBricks in proper places to control it, like this:

Next post I will explain how to do it and show a slightly more useful demo.


LEGO officially uses ev3dev

Yesterday LEGO Education quietly released “Python for EV3“:

You can now use your EV3 Brick to unleash the power of Python programming using MicroPython. Simply install the EV3 MicroPython image onto any micro SD card and boot up your EV3 Brick from it to start programming straight away.

What it really is: a full ev3dev image with a micropython environment meant to be used from Visual Studio Code through an EV3 MicroPython extension.

Amazing work from David Lechner, Laurens Valk, and Anton Vanhoucke, built over the shoulders of lots of other giants. Congratulations to all!

The documentation states that it uses a ‘pybricks-micropython’ environment and new ‘pybrick’ library, not yet available outside of this image but that’s just a matter of time.

Micropython programs tend to use less resources than common python and also start much faster. The ev3dev-lang-python is still included on the image but for simple projects this new micropython environment will be of great use for people starting with EV3 and text-oriented languages.

The image is really a full ev3dev stretch-based image, the ‘robot’ user is still available (password is “maker”) so we can still access through SSH and use it the way we were used:

ssh robot@ev3dev.local
Password: 
Linux ev3dev 4.14.96-ev3dev-2.3.2-ev3 #1 PREEMPT Sun Jan 27 21:27:35 CST 2019 armv5tejl
             _____     _
   _____   _|___ /  __| | _____   __
  / _ \ \ / / |_ \ / _` |/ _ \ \ / /
 |  __/\ V / ___) | (_| |  __/\ V /
  \___| \_/ |____/ \__,_|\___| \_/

Debian stretch on LEGO MINDSTORMS EV3!

Kernel is very recent but there is already a newer version available – since LEGO keeped the link to ev3dev repositories so the usual ‘sudo apt update’ and ‘sudo apt upgrade’ works:

The following NEW packages will be installed:
linux-image-4.14.111-ev3dev-2.3.3-ev3 rtl8188eu-modules-4.14.111-ev3dev-2.3.3-ev3
rtl8812au-modules-4.14.111-ev3dev-2.3.3-ev3
The following packages will be upgraded:
jri-11-ev3 libnss-myhostname libnss-resolve libpam-systemd libsmbclient libsystemd0 libudev1 libwbclient0
linux-image-ev3dev-ev3 samba-libs systemd systemd-sysv udev wget wpasupplicant

By the way, micropython says:

robot@ev3dev:~$ micropython 
MicroPython v1.9.4 on 2018-05-22; linux version
Use Ctrl-D to exit, Ctrl-E for paste mod

Just a few days after SPIKE anouncement, the future of LEGO robots seems now to be very very linked to linux, python and opensource

Me happy! 🙂

LEGO Wireless Protocol officially available

LEGO released the specs for the Powered Up BLE-based protocol (LWP):

https://lego.github.io/lego-ble-wireless-protocol-docs

Interestingly the document is also available as an open souce (MIT license) project at Github:

https://github.com/LEGO/lego-ble-wireless-protocol-docs

Is’s always a good sign when a big company like LEGO embraces open source so let’s hope for the best

Merry Christmas to all!

Crowdfunding: SmartBrick

Decidi apoiar um novo projecto de crowdfunding: SmartBrick.

Basicamente um bloco WeDO mais poderoso e sem o cabo USB, apenas Bluetooth.

Para quem estiver interessado, o site do produto e da empresa-mãe, a Vengit.

[actualização de 28 de Julho]

O projecto tem o apoio de figuras como o Philo e o Sariel. Este último participou numa review de um protótipo:

[adição de 6 de Agosto]

O conhecido Nico71 também participou numa review:

 

 

Pitagoras e a Esfinge

Faltava ainda um tipo qualquer de sensor para ter um sistema verdadeiramente autónomo por isso liguei um sensor de toque LEGO Mindstorms (ainda estilo RCX) a uma das entradas digitais PiFace.

O PiFace tem 8 entradas digitais com pull-ups internos (li algures que se podem desligar, deixando as entradas «flutuantes»). Como o sensor de toque RCX é um mero interruptor basta ligar um dos cabos a uma das entradas e o outro à massa. Com o sensor em repouso (interruptor aberto) a entrada do PiFace vai ler um “1” e quando ocorrer contacto (interruptor fechado) a entrada vai ficar ligada à massa e é lido um “0”.

bricklink.com: Lego Touch Sensor (879)

É muito fácil acompanhar o estado do sensor, basta ler continuamente o estado da entrada. No script abixo usei a entrada #0 e acrescentei um atraso de 200 ms entre cada leitura para não inundar o terminal com mensagens “ON!” ou “OFF!”

#!/usr/bin/python3

import sys
from time import sleep
import pifacedigitalio

pifacedigital = pifacedigitalio.PiFaceDigital()
led7=pifacedigital.leds[7]
led6=pifacedigital.leds[6]
led7.turn_off()
led6.turn_off()
in0=pifacedigital.input_pins[0]

while(True):
 if(in0.value != 0):
   print("ON!")
 else:
   print("OFF!)
 sleep(0.2)

E se quisermos usar o sensor para controlar o leão basta juntar tudo:

#!/usr/bin/python3

import sys
from time import sleep
import pifacedigitalio

DELAY_UP = 0.17
DELAY_DOWN = 0.14
DELAY_WAIT = 0.75

pifacedigital = pifacedigitalio.PiFaceDigital()
led7=pifacedigital.leds[7]
led6=pifacedigital.leds[6]
led7.turn_off()
led6.turn_off()
in0=pifacedigital.input_pins[0]

while(True):
 if(in0.value != 0):
   print("Para cima!")
   led7.turn_on()
   sleep(DELAY_UP)
   led7.turn_off()
   print("Espera!")
   sleep(DELAY_WAIT)
   print("Para baixo!")
   led6.turn_on()
   sleep(DELAY_DOWN)
   led6.turn_off()

Para ligar o sensor à entrada #0 do Piface Digital cortei um cabo RCX a meio:

rcx-cableO diagrama abaixo ilustra a configuração final, no que diz respeito às ligações eléctricas:

pitagoras-e-a-esfinge

Controlo de motores Lego

Quero utilizar o Raspberry Pi para controlar directamente construções em Lego, um pouco à maneiro do Lego Education WeDo Robotics.

Encomenda à PTRobotics:

Já tinha:

  • Lego Power Functions Rechargeable Battery Box (8878) ou AA Battery Box (8881)
  • Lego Power Functions XL Motor (8882)
  • fio eléctrico
  • carregador com ficha micro-USB
  • SD Card 4 GB com Raspbian instalado e pré-configurado para wi-fi para evitar ter de usar um teclado e um monitor
  • 2 resistências entre 220 Ω e 2.2 KΩ (usei duas de 1 KΩ)

A montagem do PiFace é simples: encaixar o módulo sobre o Raspberry Pi, inserir o SD Card e o Wi-Pi e fornecer energia através do cabo micro-USB.

O PiFace faz uso da interface SPI pelo que é necessário activá-la:

$sudo raspi-config

Escolher no menu “8 Advanced Options” e depois “A5 SPI”, responder “yes” e finalmente “finish”. Não é necessário reboot.

É também necessário instalar o módulo python para o PiFace, que já faz parte do repositório do Raspbian:

$sudo apt-get install python3-pifacedigitalio

Para testar, basta correr o script que vem com o módulo:

$python3 /usr/share/doc/python3-pifacedigitalio/examples/blink.py

O LED #7 acende e apaga segundo a segundo, tudo OK podemos passar ao controlo do motor.

As saídas do PiFace são Open Collector pelo que é necessário um pull up (ligar aos +5 V através de um resistência) para obter algo compatível com as entradas da bridge.

A bridge é alimentada pela bateria Lego Power Functions (usei um cabo Power Functions cortado a meio, aproveitando apenas os 2 condutores exteriores – um para GND e o outro para PWR).

powerfunctions-hbridge-powerUtilizei um voltímetro para confirmar qual o positivo e qual o negativo – no caso do modelo 8878 da foto acima o selector de velocidade ficou rodado até ao extremo no sentido dos ponteiros do relógio; no modelo 8881 é necessário deslocar o selector no sentido da ficha.

O motor é ligado à H-bridge com a outra metade do cabo anterior, desta vez utilizando apenas os 2 condutores interiores.

O script blinky.py anterior serve para testar mas para controlo manual a partir da shell do python optei por usar estes comandos:

$python3
>>>import pifacedigitalio
>>>pifacedigital = pifacedigitalio.PiFaceDigital()
>>>led7=pifacedigital.leds[7]
>>>led6=pifacedigital.leds[6]
>>>led7.turn_off()
>>>led6.turn_off()

Para acender apenas o LED #7 e fazer o motor rodar num sentido:

>>>led7.turn_off()
>>>led6.turn_on()

Para acender apenas o LED #6 e fazer o motor rodar no sentido oposto:

>>>led7.turn_on()
>>>led6.turn_off()

Se acender ambos os LED o motor permanece parado:

>>>led7.turn_on()
>>>led6.turn_on(

E para sair da shell de python:

>>>exit()

Mindstorms EV3 – data de lançamento

«É amanhã dia 1 de Agosto

e tudo em mim é um fogo posto (…)»

Xutos&Pontapés, 1º de Agosto

A 1 de Agosto estará disponível o conjunto educativo via LEGO Education portanto apenas para professores e afins nos EUA, possívelmente um sub-conjunto do que depois estará disponível ao público em geral algures no Outono, segundo a FAQ da LEGO.

A Evolução demonstrada em Legos

Lego-Minifigures-SecXX-70
Figuras Lego, década de 70 do século XX
(ainda se notam restos de marcador que tornaram a figura da esquerda num Socorrista)

Lego-Minifigures-SecXX-90
Figura Lego, década de 90 do século XX
(braços, pernas, mãos, articulações, olhos, boca e roupa autocolante)

Lego-Minifigures-SecXXI-10
Figuras Lego, década de 10 do século XXI
(rostos e troncos personalizados, acessórios)

  O futuro adivinha-se fascinante.

Actualização: houve alguém que fez um trabalho muito mais exaustivo.