WeDo 2.0 with EV3 – an ev3dev tutorial

What a great weekend:

  • at Paredes de Coura FAN Weekend with almost 200 AFOL’s from allover the world
  • finally got the LEGO Education WeDo 2.0 App working with my Android phone – thanks Fernando for being such a good PITA 😉
  • github notified me that my ev3dev tutorial got merged so it’s now available in the ev3dev site on the Tutorials section: Controlling a WeDo 2.0 motor

Controlling WeDo 2.0 motor from Linux

LEGO Education released the WeDO 2.0 some months ago and I bought a kit. I returned to LEGO thanks to WeDO 1.0 and since I’m already using BLE with the SBrick, using the WeDo 2.0 seemed natural.

But LEGO Education made the Android app very restrictive and only a few Android devices are allowed to install it – I have two different BLE enabled Android phones and none complies with LEGO Education definitions. Although LEGO Education promised a SDK for the new WeDO 2.0, there’s still nothing available and since I don’t own a Windows computer or an Apple device, my WeDO 2.0 kit was rusting on the shelf, waiting for better days.

Then yesterday I found a Microsoft guy’ with some bluetooth code samples with references for the WeDO 2.0 – how ironic!

So it took me only a few hours to achieve what I think is a world premiere: a linux system controlling a LEGO WeDO 2.0 motor. And what better linux system than a LEGO Mindstorms EV3?

Next post will I’ll give more details.

EV3DEV na BRInCKa 2015

O controlo dos meus módulos MFL é feito por intermédio de um computador LEGO Mindstorms EV3 a correr ev3dev – Debian Linux for the EV3, uma versão de Debian Linux criada de propósito para o EV3.

EV3DEV inside

O tile à frente do pinguim foi-me oferecido pelos responsáveis do projecto em reconhecimento pelo Rasperry Pi 2 que contribuí para o projecto, que está agora numa fase de ser portado para outros dispositivos similares como o Pi ou o Cubieboard.

Módulo MFL em Tomar

Os meus primeiros 3 módulos MFL (Módulo Ferrovia LEGO) junto dos restantes módulos da PLUG no Tomar BRInCKa 2015:

O  módulo ao centro tem dois desvios motorizados, bem como um «desengatador» no troço de recta entre as duas agulhas. Toda a electrónica está disfarçada por baixo das linhas.

O módulo da direita consiste numa plataforma rotativa motorizada e controlada por um LEGO Mindstorms EV3 correndo ev3dev (uma variante de Debian para o EV3). Sobre o carril um pequeno comboio controlado por SBrick (bluetooth).

O módulo da esquerda, quase 100% da minha marida, começou com uma pequena cascata no nosso presépio do Natal anterior.

A montagem no BRInCKa 2015 não ficou completa por isso todas as demonstrações são manuais, controladas por mim. Neste video gravado em casa é o computador (LEGO Mindstorms EV3) a fazer tudo sozinho:

O que faltou montar e que permite a automação plena? As componentes RFID – por baixo do pequeno comboio há um identificador RFID do tamanho de uma moeda que permite identificá-lo e em certa medida seguir-lhe a posição. Na montagem do video existem dois leitores RFID (USB) por baixo da linha (um no extremo direito e outro junto ao sistema de desengate). O EV3 utiliza esses sensores para perceber se o comboio está nos sítios certos antes de passar à acção seguinte.

How to remote control a LEGO DUPLO Train

Some weeks ago, a fellow from my LEGO User Group reached me for some Infrared electronics insights. He was trying to remote control his LEGO DUPLO Train with an infrared remote.

I never played with IR before but got curious. I love the idea of remote controlling something. But not manually, it has to be programmatically so one can use it for automation or robotic purposes. So after some weeks I found the LIRC definitions for LEGO Power Functions IR and used it to remote control LEGO from my laptop via the audio output.

Then it was the anniversary of one the kids and he asked granny for a major upgrade of their DUPLO train track:

LEGO® DUPLO® Deluxe Train Set

So I thought it would be great if they could control the train back and forth… and ordered a used DUPLO Train Locomotive Base (5135c01) from BrickLink.

Opening it was difficult but I managed to do it without breaking anything, thanks to these two previous brave pioneers:

(their locomotives are from a different set but the idea is the same)

The locomotive has a pair of free wheels at front and another pair drived by a motor and some gears at back where there is also a piezo buzzer, a printed circuit board and a pair of wires comming from the batteries holder. There are also two rubber buttons that press some small metal rings against the surface of the PCB to act as switches – the smaller one, hidden in a small hole, makes the sound of fuel being pumped into the tank when the fuel hose is inserted, the bigger one controls starts/stops the train but also indirectly controls the sound of the locomotive (when in movement) and the sound of the breaks (when stopping).

The PCB has 6 wires soldered at points labeled J1 to J6:

  • J1 and J3 – buzzer
  • J2 and J4 – batteries
  • J5 and J6 – motor

As the batteries holder is for just 3 AA batteries, the board works with 4.5V. Not much but enough for a LEGO Power Functions IR receiver or a Vengit SBrick.

We could just dessolder the wires at J2/J4 (power) and J5/J6 (motor), get a LEGO Power Functions cable, cut it in half and solder the tips from one half to J2/J4 and the tips from the other half to J5/J6. But that will make the buzzer useless.

As the buzzer is controlled by an IC on the PCB, I choose to keep the power lines going to the PCB (J2/J4) and deriving from there to the Power Functions cable (but still dessoldering J5/J6). This way, when the batteries are inserted, both the remote and the PCB are ON so the two buttons maintain their functionality. This gives us as an unexpected possibility: we can also use the PF cable to power the train instead of using 3 AA batteries – with special caution because LEGO PF batteries or LEGO 9V batteries give more than 4.5V so some reduction has to be done, like adding some 1N4001 diodes or a voltage regulator… but a USB 5.0V battery pack will be perfect.

Since I didn’t want to drill or cut the plastic, I managed to pass the PF cables through the start/stop button hole (before soldering it) but later found out that it was to tight for the rubber button – so no more «tchoo-tchoo!» nor breaks (some may consider this a feature, not a bug).

Some more photos are available at this Brickshelf folder.

The final result is a LEGO DUPLO train that:

  • can be remotely controlled by Infrared or Bluetooth, manually or programatically
  • can move forward AND backward
  • can use LEGO batteries (PF or 9V) with a special cable or a USB battery pack

Raspberry Pi + SBrick

Finally got time to return to the Pi.

Yes, the Raspberry Pi can talk to the SBrick. It’s only necessary to install Bluez 5.

But as the standard Raspbian is based on Debian Wheezy, if you install bluez from the repositories

sudo apt-get install bluez

you will get Bluez 4 (today, 1 December 2014, it’s version 4.99). I can make a Low Energy Scan (lescan) and find the SBrick but my gatttool commands fail with

Host is down (112)

So we need Bluez 5. There are at least two ways:

  • get Bluez 5 source code and compile as in RPi Bluetooth LE
  • update Raspbian to Debian Jessiea as it already includes Bluez 5

I’m lazy, I don’t like to compile anything. I’m also afraid that any update might brake compatibility and forces me to recompile again. And my laptop (Unbuntu) and my EV3 (ev3dev) are already running a version of Jessie so let’s update.

Warning: Raspbian update from Wheezy to Jessie takes almost a day – so compiling Bluez might appeal to those in a hurry.

We need enough free space on the SD card. I used a 4 GB card and my first try failed miserable after a long night. So the second time I removed some things to assure an happy end.

First I transfered the most recent image available (2014-09-09) to the 4 GB card and edited networking to get wi-fi (I only use SSH with the Raspberry, like I do with the LEGO Mindstorms EV3).

After first boot with the fresh card run rasp-config to expand the file system with all free space available.

sudo rasp-config

after next boot remove some heavy things and clean:

sudo apt-get remove x11-common midori lxde
rm /opt/vc/src/hello_pi/hello_video/test.h264
rm -rf python_games
sudo apt-get clean
df -h

there are now 2.0 GB available on the 4.0 GB card. That’s enough, let’s change the source of our packages:

sudo nano /etc/apt/sources.list

replace ‘wheezy’ with ‘jessie’ and save.

sudo apt-get update
sudo apt-get upgrade
sudo reboot
By now we have near 1.8G available.

sudo dist-upgrade
sudo reboot

Now we are already using a Debian Jessie version of Raspbian.

sudo apt-get install bluez

As of 1 December 2014, Debian Jessie for Raspberry Pi uses bluez 5.23-1. Now remove all garbage and check space again:

apt-get autoremove

df -h

807 MB avaliable, not bad.

My bluetooth BT 4.0 USB dongle is recognized (it already was) but is not active by default so before using it

sudo hciconfig hci0 up

now gatttool commands work with the SBrick, and so all my scripts from Ubuntu and EV3.

 

 

 

 

 

 

LEGO WeDO – Temperature Sensor

As the WeDo USB Hub uses some kind of ADC (Analog to Digital Converter) to read the tilt sensor values, we can use this ADC for our own analog sensors.

So let’s start with  a Temperature Sensor.

The most simple/easy temperature sensor is just a NTC thermistor: every regular resistor has some minor variations when the operating temperature changes and a thermistor is just a resistor designed to have a significant and well-known variation. A NTC (negative temperature coefficient) thermistor has a decrease in it’s value proportional to the temperature increase.

We can buy a cheap (less than €1) 10 kΩ NTC thermistor and use it as a temperature sensor knowing that at 25°C (average ambient temperature) it has a 10 kΩ value – we also need to know its temperature coefficient from the manufacturer datasheet or from our own calibration tests. Just solder two wires and provide some insulation and we’re done:

Or we can just use an old LEGO Mindstorms (RCX) Temperature Sensor 🙂

To use this sensor we can make our own cable with just one 3.9 kΩ resistor between C1 and 0 to makes the WeDo think we have a tilt sensor connected to it. Then we connect our sensor between C2 and 0 or between C2 and 9V.

Our we can piggyback a real tilt sensor with a modded cable and just connect our sensor to it:

In this scenario we must assure that the tilt sensor always stays flat so it doesn’t get in our way when we’re reading the temperature sensor and since the tilt sensor already has a 10 kΩ resistor between C2 and 0 I prefer to connect the sensor between C2 an 9V.

Early first readings, room temperature compared to the readings from a SensorTag :

RAW Temp (°C)
159 20
158 20
165 36.5
157 19.8
157 19.5
157 19.6
156 18.8
157 19
156 18.9

LEGO WeDO with EV3 – kernel support

Last night the ev3dev people released a Linux driver for WeDo. For now it is just for ev3dev so it works only in Mindstorms EV3 but hopefully it will get to other distributions and it will allow anyone with a Raspberry Pi or an Ubuntu laptop (like me) to use WeDo without python WeDo or WeDoMore libraries – just a shell is enough!

We need a ev3dev with kernel 3.16.1-7 or above:

root@ev3dev:~# uname -a
Linux ev3dev 3.16.1-7-ev3dev #2 PREEMPT Tue Nov 25 11:24:38 CST 2014 armv5tejl GNU/Linux

If your kernel is older, just

apt-get update
apt-get dist-upgrade
reboot

After reboot, creat a udev rule for WeDo – it will prevent the kernel to bind it to the usbhid driver, binding it instead to legowedo driver:

nano /etc/udev/rules.d/80-wedo.rules

SUBSYSTEM=="usb", ATTRS{idVendor}=="0694", ATTRS{idProduct}=="0003" ACTION=="add", \
    RUN+="/bin/sh -c 'echo $kernel > /sys/bus/usb/drivers/usbhid/unbind;           \
                      echo $kernel > /sys/bus/usb/drivers/legowedo/bind'"

Now just reboot or refresh the udev rules by

udevadm control --reload-rules

If you plug the LEGO WeDo USB Hub and check dmesg it wil show

[ 1222.200538] usb 1-1.2: new low-speed USB device number 5 using ohci
[ 1222.370828] hid-generic 0003:0694:0003.0002: hidraw0: USB HID v1.10 Device [LEGO USB Hub V1.00] on usb-ohci.0-1.2/input0
[ 1222.691293] wedo hub0: Bound 'hub0' to 'usb1-1.2:1.0'

We now have a new device ‘hub0’:

root@ev3dev:~# ls /sys/bus/wedo/devices/ -la
lrwxrwxrwx 1 root root 0 Nov 25 06:21 hub0 -> ../../../devices/platform/ohci.0/usb1/1-1/1-1.2/1-1.2:1.0/hub0

with the following properties:

root@ev3dev:~# ls /sys/bus/wedo/devices/hub0
clear_error  error  high_power  port0  port1  power  reset  shut_down  subsystem  uevent  voltage

So we may check if the USB port gives enough current for a motor:

root@ev3dev:~# cat /sys/bus/wedo/devices/hub0/high_power 
1

or check for the USB power quality (in mV):

root@ev3dev:~# cat /sys/bus/wedo/devices/hub0/voltage 
5145

Now if we plug a LEGO Power Functions motor to one of the ports it will immediately be recognized by the kernel:

[ 1736.348469] dc-motor motor0: Bound to device 'port0'

and the motor is seen by the kernel as dc-motor like if we were using an NXT/EV3 to Power Functions or RCX adapter:

root@ev3dev:~# ls /sys/class/dc-motor -la
lrwxrwxrwx  1 root root 0 Nov 25 06:30 motor0 -> ../../devices/platform/ohci.0/usb1/1-1/1-1.2/1-1.2:1.0/hub0/port0/dc-motor/motor0
root@ev3dev:~# ls /sys/class/dc-motor/motor0
command   device      duty_cycle_sp  polarity   power         ramp_up_ms  uevent
commands  duty_cycle  name           port_name  ramp_down_ms  subsystem

So we can make it spin with 35% duty cycle:

echo 35 > /sys/class/dc-motor/motor0/duty_cycle_sp

And it’s the same for WeDo sensors – as I just have a tilt sensor, lets plug it:

root@ev3dev:~# ls /sys/class/msensor/ -la
lrwxrwxrwx  1 root root 0 Nov 25 06:40 sensor0 -> ../../devices/platform/ohci.0/usb1/1-1/1-1.2/1-1.2:1.0/hub0/port1/msensor/sensor0
root@ev3dev:~# ls /sys/class/msensor/sensor0
address   bin_data_format  commands  dp    modes  num_values  power      uevent  value0  value2  value4  value6
bin_data  command          device    mode  name   port_name   subsystem  units   value1  value3  value5  value7

The tilt sensor driver has 3 operation modes:

root@ev3dev:~# cat /sys/class/msensor/sensor0/modes
TILT TILT-AXIS RAW

by default it operates in TILT mode:

root@ev3dev:~# cat /sys/class/msensor/sensor0/mode
TILT

This is the expected operation mode with LEGO WeDo software: it returns 0 when flat and 1 to 4 when tilted.

TILT-AXIS mode returns 3 values: -1 or +1 when tilted, one value for each axle, the third value being 1 whenever it’s not flat.

And RAW mode returns the original analogic value read at the C2 pin. Almost useless for a tilt sensor but VERY usefull if we want to make our own sensors (more of it in my next post):

root@ev3dev:~# echo RAW > /sys/class/msensor/sensor0/mode
root@ev3dev:~# cat /sys/class/msensor/sensor0/value0
179