Wi-Fi Dongles for ev3dev

It’s Easter time so I’m considering organizing a workshop with my LUG to show them The Light of Ev3 MicroPython 🙂

I already have a few microSD cards that I can share but will probably need some Wi-Fi dongles (no way I’ll ever teach a bunch of Windows-addicted guys how to use USB or Bluetooth on their first contact with Ev3 MicroPython).

My local robotics store has no more Edimax dongles so I went after another Asus USB Nano, it works fine with ev3dev (I think it even works better than the Edimax but if I want to switch to LeJOS or Ev3-G I prefer to have the Edimax with me as it is officially suported by LEGO).

Didn’t find the Asus but got a TP-Link “Wireless N Nano USB Adapter” (TL-WN725N) and it also seems to work fine.


usbcore: registered new interface driver r8188eu
R8188EU: Firmware Version 11, SubVersion 1, Signature 0x88e1

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 =>

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:


The hostname starts with ‘ESP_’ (the device uses a ESP8266 chipset like the NodeMCU board I’ve been using) and got IP ‘’… 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.

IoT with LEGO EV3 MicroPyhton (2)

This post is part 2 of 2 of  EV3 MicroPython and IoT

Wrote a better script to illustrate how can we use MQTT to control multiple EV3 bricks.

On the video bellow I’m using ‘mosquitto’ commands on my Ubuntu laptop but any MQTT client (like Android MQTT Dashboard or even other EV3) can be used:

IoT with LEGO EV3 MicroPyhton

This post is part 1 of 2 of  EV3 MicroPython and IoT

Just a few hours with this new image from LEGO and so much awesomeness already!

So this is all based on the MicroPython project. Being ‘v1.9.4’ it’s not the lastest version but it’s also not too old (current official release is 1.10). But it’s not ‘just’ a version customized for the EV3 devices… it seems a full implementation for ARM with ‘micropython-lib’ included.

What does it means?

Well, you can add micropyhton aditional modules if/when they are released, like for instance ‘pystone’ (a benchmarking tool):

micropython -m upip install pystone

There are already a lot of modules available including one HTTP client and other for sockets (so you can make your own MicroPython EV3 web server)… and two for MQTT!

And even better… at least the MQTT modules are already included within the LEGO image.

So let’s use EV3 for IoT:

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase

from umqtt.robust import MQTTClient
import time

def getmessages(topic, msg):
if topic == b'JorgePe/test':

client = MQTTClient('52dc166c-2de7-43c1-88ff-f80211c7a8f6','test.mosquitto.org')


while True:

Just configure Wi-Fi, connect with Visual Studio Code, upload this project… and your EV3 is IoTed!

To be continued…

Voice with MicroPython for the EV3

The new MicroPython environment for the EV3 has sound commands… but not ‘speak’ like the full ev3dev python (ev3dev-lang-pyhton).

But it has ‘os.system’ so we can make system calls…


#!/usr/bin/env pybricks-micropython
import os
os.system('espeak "hello" --stdout | aplay')

works but as soon as we instantiate an ev3brick it stops working:

#!/usr/bin/env pybricks-micropython
from pybricks import ev3brick as brick
import os
os.system('espeak "hello" --stdout | aplay')

The error is ‘aplay: main:788: audio open error: Device or resource busy’

So it seems pybricks allocates the ALSA sound card in some exclusive way. Strange because ‘aplay -L’ shows there is a software mixer:

Discard all samples (playback) or generate zero samples (capture)
Default Audio Device
Default Audio Device
Direct sample mixing device
Direct sample snooping device
Direct hardware device without any conversions
Hardware device with all software conversions

So after several try&fail iteractions, I got a workaround by creating a ‘/home/robot/.asoundrc’ file:

pcm.hwmix {
type dmix
ipc_key 1939 # must be unique
slave { pcm "hw:CARD=legoev3" }
pcm.!default hwmix

This works… unless we also use ‘brick.sound.beep()’… then it locks in some other way. Oh well, nothing is perfect.

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
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
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! 🙂

Remote ultrasonic sensor for EV3 with micro:bit

This post is part 1 of 1 of  EV3 and micro:bit

Been testing the micro:bit BLE Uart service. It’s a service that uses Nordic chipset features to deliver a simple TX/RX mechanism so we talk with the micro:bit without having to create our own BLE services.

Someone offered me a ultrasonic sensor this week. It’s a HC-SR04, very common with Arduino projects but can also be used with the micro:bit, there’s even a “sonar” extension available in the Makecode editor.

So I added the BLE Uart service and started writing the distance values to the TX characteristic every second:

Nordic nRF Connect App reads them fine but gatttool doesn’t… except when in Interactive mode. Strange!

After a while, I found out a note that explains that the way the TX characteristic works forces us to keep the connection or reset the micro:bit regularly. That’s why Interactive mode works (it keeps the connection). So I have to forget gatttool for a while and use something better like python.

On Ubuntu, my scripts worked fine. Latest version of pygatt (4.0.3) allow me to subscribe to the TX Characterist (in “Indication” mode only – almost the same as notifications but with an extra acknowledge step) and I was getting distance values on my laptop through BLE.

But on the EV3 the scripts failed because “No characteristic found matching”. Why? I’m using same version of pygatt and don’t think that kernel version make much difference now that pybluez has settled.

I was almost giving up when something worked: decided to use the python exception mechanism to retry several times the subscribing step.

So instead of just

device.subscribe("6e400002-b5a3-f393-e0a9-e50e24dcca9e", callback=handle_data, indication=True)

I included the subscribe command in a loop that only ends when the command completes:

while True:
        device.subscribe("6e400002-b5a3-f393-e0a9-e50e24dcca9e", callback=handle_data, indication=True)
    except pygatt.exceptions.BLEError:
        print("unknown characteristic")

And it works?! Usually just retrying once:

unknown characteristic
Dist = 1.19 m
Dist = 1.19 m
Dist = 1.18 m

My micro:bit github page now includes the python script used on the above video

If you wonder about the format of the data, the micro:bit sends the distance value as a string of bytes, each byte being the ASCII code of the character, so 40 cm is sent as a “4” followed by a “0”:

34h 30h

EV3 and micro:bit

Almost 2 and a half years ago I bought a BBC micro:bit, planning to give it as a xmas present to my geek nephew. Unfortunately (for him) I decided that he wasn’t geek enough for this small ARM-based controller as I found out it was too confusing to set it up properly for BLE usage.

At that time I managed to get EV3 working with it but it was very awkward. Most of my problems were related to making a proper connection because the firmware required BT to be paired before accepting BLE commands but I also had problemas with the python BLE library I was using (gattlib).

This weekend I had a long day at work upgrading some Microsoft servers and had the time, between downloads and reboots (argh!) to return to this little fellow. So I found out it is now much, much easier to configure it… thanks to Microsoft! Yes, same Microsoft.

I used Makecode Editor to configure my micro:bit from a browser: just added the Bluetooth extension, included th e Bluetooth blocks that activate the proper BLE services and enabled using BLE without the need to pair BT first.

On the ev3dev side it was also easy to use it with python but with a different library: pygatt.

Interestingly, a new version of pygatt was released this very same weekend.

Details and code samples at another Microsoft site (github).

Two demo videos:

  • using the two buttons to control a Medium motor:
  • using the LED Matrix:

I love opensource

Today I got a nice note from a guy named Kevin Walters. He used my mindstorms-vll code to control a MINDSTORMS MicroScout droid with a smarphone, using an Adafruit Feather M0 Bluefruit LE running CircuitPython 3.1.1 as a gateway controller:


Thanks Kevin for quoting me and for the wonderful project.

LEGO Conveyex Imperial Transport

This post is part 1 of 1 of  Conveyex

So another never-to-be-completed project.

I like Star Wars but usually don’t care for LEGO Star Wars sets. But when the Conveyex set was released I liked it a lot. Probably because it looked like a monorail train and I was already gathering a few old LEGO monorail pieces. So I ordered one… or so I tought.

When I order from LEGO I take the chance to buy a few MINDSTORMS motors and some Power Function elements like cables or batteries. I had a few items already on my desired list so I didn’t notice exactly how many items I was ordering… and so I received 3 (three!) Conveyex sets.

Oh boy. What I am going to do with all these Conveyex?

Then I realized that the size of the set wagons is simillar to the monorail wagons. After assembling the first set I took off the wheels and with just a few extra bricks I got my first monorail version:

Since I was already trying to use Powered Up as a way to control the monorail motor it seemed natural to extend this first version to a bluetooth controled one:

This way the Conveyex could be controlled not just with the Powered Up train headset but also programmatically. That would allow me to use the Conveyex on a large animated diorama, with MINDSTORMS and other controllable elements:

So this was the beginning. Now I “just” needed to extend the train with a few more wagons. And the rail with a few more tracks. Seemed simple.

But the old LEGO monorail system wasn’t meant for long trains. The system was designed for just 1 engine in the middle and 1 wagon at each side:

The wagons connect to the engine through a custom coupling system. As far as I know, there is no way to connect other LEGO elements to the engine couplings. Extending the length is possible by adding wagons and using some LEGO parts as custom couplers, like in LEGO trains.

Fortunately there is a company named 4DBrix that sell a few custom elements compatible with the monorail system. I ordered them some car extensions that has a “male” tab that connects to the engine and a “female” socket that allow extra wagons to be added. It worked but then the overall weight started to be feel too demanding for the monorail motor. Perhaps a single motor could move a train with 2 or 3 wagons and an engine but I also wanted ramps (of course!) and that seemed too much. So I wondered if it is possible to use more than one monorail motor…

It is:

The monorail track is really just a long gear. So the two motors are directly coupled together and just add their force (oh well… after a while I found out that this is not always true).

But the way that the Powered Up Hub was designed it is not the best for such a setup – the 6x AAA batteries would drain too fast and I would have to remove the Hub to replace them. Once in a while it might be acceptable but certainly not every 30 minutes. The good old Power Functions LiPo battery is much better – it allows in place recharging and it also looks like it can supply a few more milliamps than the PUP Hub (not confirmed).

So I picked my LEGO relay idea and built a Powered Up version:

and then applied it to the Conveyex:

So now the Powered Up Hub batteries are only used to keep the Hub ON and sometimes to change the relay state. Need to measure it but I suspect that it would work a few hours. And no custom cable is used, just 100% LEGO electric parts.

So today the Conveyex is already looking good:

The model uses 2 monorail motors, 4 wagons and an engine car:

From left to right:

  • Powered Up Hub wagon
  • Monorail motor
  • Relay wagon
  • Power Functions LiPo battery wagon
  • still no purpose wagon
  • Monorail wagon
  • Engine car

So the Conveyex is really just 2 monorail trains linked together (in the above drawing, the extra space reflects the custom coupling I had to build, longer than the monorail coupling sustem). The wagons aren’t all of the same size because the wagons length from the LEGO Conveyex are in facto a bit too larger and make the monorail derail at regular curves and ramps – so I built the Relay wagon 4 studs shorter.

The weight is not equally distributed, the front train is lighter than the back train. So sometimes, when the Conveyex is moving on ramps, the two trains move at different speeds – like when the front train already reached the top and the back train is still moving up in the ramp:

On the video above the LiPo was adjusted for 4/7 of output power. The front train gained too much speed and the monorail coupling couldn’t handle and disconnected. Now I’m running the Conveyex with the LiPo at 5/7 of output power and this never happened again but probably will need to add more weight to the “still no purpose wagon”… crazy ideas welcome 🙂