Skip to content

Commit 828ead7

Browse files
JorgePedlech
authored andcommitted
Create controlling-wedo2-motor (ev3dev#168)
* Create controlling-wedo2-motor I found a way to use a linux system to control the new WeDO 2.0 motors. Also found a python library that works with ev3dev. Code examples aren't "clean" but I think it's a good example of how to use the EV3 to talk with BT 4.0 BLE devices. The WeDO 2.0 hub is rather weak (just 2 AA batteries) but the same idea can be used with the SBrick to control Power Function motors or with those lots of IoT devices that keep appearing every day. Of course, if someone has access to the WeDO 2.0 SDK, we could extend this tutorial to sensors and whatever we may find. * Rename controlling-wedo2-motor to controlling-wedo2-motor.md * Update controlling-wedo2-motor.md Changes made according to notes. Just left the hci part untouched, not sure how to explain this new EV3 internal BT chipsets in a clear and short way. * Update controlling-wedo2-motor.md Tested with latest ev3dev image. * Update controlling-wedo2-motor.md Change subject. * Update controlling-wedo2-motor.md Add comment to turn BT on. * Update controlling-wedo2-motor.md typo fixed * Update controlling-wedo2-motor.md remove reboot reference; add "sudo" to gattlib install procedure; * Update controlling-wedo2-motor.md correct way of disabling and re-enabling zram swapfile * Update controlling-wedo2-motor.md Fixed 2 links markup. * Update controlling-wedo2-motor.md Minor text corrections. I already can read the button and the sensors but this tutorial is now only for motors. Still need to understand sensors data - tilt is simple but distance is very strange. A SDK would be great as I'm just gathering fragments of information around the NET. * Update controlling-wedo2-motor.md Typo * Update controlling-wedo2-motor.md Same typo.
1 parent 8f1594a commit 828ead7

1 file changed

Lines changed: 258 additions & 0 deletions

File tree

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
---
2+
title: Controlling a WeDo 2.0 motor
3+
subject: Hardware - WeDo
4+
author: "@JorgePe"
5+
---
6+
7+
* Table of Contents
8+
{:toc}
9+
10+
## Intro
11+
12+
LEGO Education released the second version of WeDo in the beginning of 2016.
13+
We'll show how to use the bluez, the linux bluetooth stack, to wireless control a
14+
WeDo 2.0 motor.
15+
16+
The first WeDo version uses USB so every robot needs to be tethered to a *host*
17+
(usually a computer but can also be a Mindstorms EV3 running ev3dev)
18+
The second WeDo version uses [BLE](https://en.wikipedia.org/wiki/Bluetooth_low_energy) (Bluetooth Low Energy, a sub-set of the Bluetooth
19+
4.0 standard) so robots can now be totally autonomous.
20+
21+
## Requirements
22+
23+
The EV3 internal bluetooth isn't compliant with the BT 4.0 BLE subset so we need an
24+
USB Bluetooth 4.0 dongle supported by ev3dev. If it works with Ubuntu or with a
25+
Raspberry Pi then most probably will also work with ev3dev.
26+
27+
Since we'll probably use Wi-Fi, an USB hub will be required aswell. Most (but not
28+
all) USB 2.0 hubs work fine with ev3dev.
29+
30+
If ev3dev recognizes our Bluetooth 4.0 dongle, we'll have two hci devices - the
31+
internal bluetooth and the new USB one:
32+
33+
robot@ev3dev:~# hciconfig -a
34+
hci1: Type: BR/EDR Bus: UART
35+
BD Address: 00:17:EC:48:44:6B ACL MTU: 1021:4 SCO MTU: 180:4
36+
UP RUNNING
37+
RX bytes:863 acl:0 sco:0 events:32 errors:0
38+
TX bytes:1396 acl:0 sco:0 commands:32 errors:0
39+
Features: 0xff 0xff 0x2d 0xfe 0x9b 0xff 0x79 0x83
40+
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
41+
Link policy: RSWITCH HOLD SNIFF PARK
42+
Link mode: SLAVE ACCEPT
43+
Name: 'ev3dev'
44+
Class: 0x000000
45+
Service Classes: Unspecified
46+
Device Class: Miscellaneous,
47+
HCI Version: 2.1 (0x4) Revision: 0x0
48+
LMP Version: 2.1 (0x4) Subversion: 0x191f
49+
Manufacturer: Texas Instruments Inc. (13)
50+
51+
hci0: Type: BR/EDR Bus: USB
52+
BD Address: 00:19:0E:16:3F:EA ACL MTU: 1021:8 SCO MTU: 64:1
53+
UP RUNNING
54+
RX bytes:11809 acl:120 sco:0 events:872 errors:0
55+
TX bytes:8004 acl:120 sco:0 commands:470 errors:0
56+
Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
57+
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
58+
Link policy: RSWITCH SNIFF
59+
Link mode: SLAVE ACCEPT
60+
Name: 'ev3dev #1'
61+
Class: 0x000000
62+
Service Classes: Unspecified
63+
Device Class: Miscellaneous,
64+
HCI Version: 4.0 (0x6) Revision: 0x1000
65+
LMP Version: 4.0 (0x6) Subversion: 0x220e
66+
Manufacturer: Broadcom Corporation (15)
67+
68+
In the above situation, `hci0` is our Bluetooth 4.0 BLE device (note "BUS: USB" and
69+
"HCI version: 4.0"). If you don't see status "UP RUNNING" you need to activate
70+
Bluetooth first (one easy way is using the Brickman User Interface: choose "Wireless
71+
and Networks" at the main screen then "Bluetooth")
72+
73+
We also need a recent bluez version for BLE support. Most recent builds of ev3dev
74+
will have it already (checked with "ev3-ev3dev-jessie-2015-12-30.img.xz").
75+
76+
Now we need to find the bluetooth address of our WeDo 2.0 hub.
77+
For that we press it's button to put it in descovery mode and run this
78+
command:
79+
80+
robot@ev3dev:~# sudo hcitool -i hci0 lescan
81+
LE Scan ...
82+
A0:E6:F8:1E:58:57 (unknown)
83+
A0:E6:F8:1E:58:57
84+
85+
In the example above, `A0:E6:F8:1E:58:57` is the bluetooth address of our WeDo 2.0
86+
hub. We can use other tools, including a smartphone with BLE support - the WeDo 2.0
87+
will probably show up as `LPF2 Smart Hub 2 I/O`, just look for the address in its
88+
properties.
89+
90+
91+
## Shell script example
92+
93+
This short shell script makes a motor connected to the first port spin for one second
94+
then stop:
95+
96+
#!/bin/bash
97+
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write -a 0x003d -n 01010164
98+
sleep 1
99+
gatttool -i hci0 -b A0:E6:F8:1E:58:57 --char-write -a 0x003d -n 01010100
100+
101+
(You need to run this script with sudo, unless you already have root previleges)
102+
103+
We see that it uses the gatttool command to send a sequence of 4 bytes to one specific
104+
handler (0x003d). The WeDo 2.0 has several handlers but until LEGO Education releases
105+
the promised SDK this is the only handler we "know" how to use:
106+
107+
This is meaning of those 4 bytes:
108+
* the first byte defines the port (01 or 02)
109+
* the second byte defines the command (01 = motor speed)
110+
* the third byte defines the length of the following argument(s) (01)
111+
* the fouth byte is the argument, in this case the speed percentage
112+
113+
To spin in one direction we send a positive value from 1 to 100 (or 01 to 64 in
114+
hexadecimal).
115+
To spin in the opposite direction we send a "negative" value from
116+
255 to 156 (or FF to 9C in hexadecimal).
117+
To stop the motor we set the speed as zero (00).
118+
Please note that for small speed values (less than 20%) the motor will not respond.
119+
120+
121+
## Python example
122+
123+
To use pyhton with the WeDo 2.0 we need a BLE library. Unfortunately BLE
124+
support in python is still quite imature but there is at least one library that
125+
works in ev3dev - [gattlib](https://bitbucket.org/OscarAcena/pygattlib)
126+
127+
sudo apt-get install pkg-config libboost-python-dev libboost-thread-dev \
128+
libbluetooth-dev libglib2.0-dev python-dev
129+
130+
sudo pip install gattlib
131+
132+
This library is also used as an extension for a more known library, [pybluez](https://pypi.python.org/pypi/PyBluez)
133+
so if you want a library for both bluetooth "Classic" and BLE this would be better:
134+
135+
pip install pybluez
136+
pip install pybluez[ble]
137+
138+
Unfortunately I couldn't make it work in my ev3dev system.
139+
140+
Please note that it takes **a lot** of memory and around 2 hours to install gattlib.
141+
After some failures ("virtual memory exhausted: Cannot allocate memory") I finally
142+
succeeded extending my ev3dev swapfile to almost 1 GB (please first check if you have
143+
enough free space in your SD card):
144+
145+
robot@ev3dev:~$ sudo dd if=/dev/zero of=/swapfile1 bs=1024 count=917504
146+
917504+0 records in
147+
917504+0 records out
148+
939524096 bytes (940 MB) copied, 442.332 s, 2.1 MB/s
149+
150+
it will take 5 to 10 minutes to allocate space for such a big file
151+
152+
robot@ev3dev:~$ sudo mkswap /swapfile1
153+
Setting up swapspace version 1, size = 917500 KiB
154+
no label, UUID=55fcb430-451b-4699-955c-5754bf65999b
155+
156+
robot@ev3dev:~$ sudo swapon /swapfile1
157+
swapon: /swapfile1: insecure permissions 0644, 0600 suggested.
158+
159+
this is a temporary measure so we'll skip security warning
160+
161+
robot@ev3dev:~$ sudo swapon -s
162+
Filename Type Size Used Priority
163+
/dev/zram0 partition 98300 8188 16383
164+
/swapfile1 file 917500 0 -1
165+
166+
We don't want to use the swapfile in memory (it will overflow) so we disable it:
167+
168+
sudo systemctl stop zram_swap.service
169+
170+
After installation completes we reset the swapfile configuration:
171+
172+
sudo systemctl start zram_swap.service
173+
sudo swapoff /swapfile1
174+
sudo rm /swapfile1
175+
176+
This short python script makes the motor spin 2 second in each direction then stop:
177+
178+
{% highlight python %}
179+
#!/usr/bin/python
180+
from gattlib import GATTRequester
181+
from time import sleep
182+
183+
req = GATTRequester("A0:E6:F8:1E:58:57",True,"hci0")
184+
req.write_by_handle(0x3d, "\x01\x01\x01\x64")
185+
sleep(2)
186+
req.write_by_handle(0x3d, "\x01\x01\x01\x9C")
187+
sleep(2)
188+
req.write_by_handle(0x3d, "\x01\x01\x01\x00")
189+
{% endhighlight %}
190+
191+
## A more practical example
192+
193+
A BLE connection is not permanent - it drops after a few seconds. And the WeDO 2.0
194+
hub also enters in sleep mode a few seconds after the connection drops so we need
195+
to assure this never happens.
196+
197+
We will use an EV3 touch sensor to control the direction of the WeDo 2.0 motor and
198+
periodically refresh the connection.
199+
200+
{% highlight python %}
201+
#!/usr/bin/python
202+
203+
from ev3dev.auto import *
204+
from gattlib import GATTRequester
205+
from time import sleep
206+
207+
address = "A0:E6:F8:1E:58:57"
208+
HANDLE = 0x3d
209+
SPIN_LEFT = "\x01\x01\x01\x64"
210+
SPIN_RIGHT = "\x01\x01\x01\x9C"
211+
SPIN_STOP = "\x01\x01\x01\x00"
212+
DELAY = 0.3 # this is empiric - the WeDo seems to need this delay
213+
# between each command
214+
215+
ts = TouchSensor();
216+
217+
req = GATTRequester(address,True,"hci0")
218+
sleep(DELAY)
219+
220+
command = SPIN_LEFT
221+
while True:
222+
if ts.value():
223+
if(req.is_connected() == True):
224+
print("Already connected")
225+
sleep(DELAY)
226+
else:
227+
print("Connecting...")
228+
req.connect(True)
229+
print("OK")
230+
sleep(DELAY)
231+
232+
req.write_by_handle(HANDLE, command)
233+
234+
if (command == SPIN_LEFT):
235+
command = SPIN_RIGHT
236+
else:
237+
command = SPIN_LEFT
238+
sleep(DELAY)
239+
240+
if(req.is_connected() == True):
241+
print("Still connected")
242+
else:
243+
print("Reconnecting...")
244+
req.connect(True)
245+
print("OK")
246+
sleep(DELAY)
247+
{% endhighlight %}
248+
249+
This video shows the script in action:
250+
{% include youtube-embed.html youtube_video_id="0d3MdZuDOTc" %}
251+
252+
## Final notes
253+
254+
We still need to know all motor commands and option. But until LEGO releases
255+
its SDK there is at list this way to extend the number of motors available to the EV3.
256+
And if rumours are true, the next generation of LEGO Power Functions and Mindstorms
257+
will both share some components with the WeDo 2.0 (the Hub is already announcing
258+
itself as "LEGO Power Functions 2" device) so this might be just the start.

0 commit comments

Comments
 (0)