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