"MaKey MaKey + Raspberry Pi + iRacer + Bluetooth = Cheese Controlled Car (CCC)"
When Santa told me that he was getting an i-Racer remote controlled car for Fionn, I was very excited. This is a remote controlled car that, on the surface looks very crude. Heck it doesn't even come with a remote control.
That's because it's Bluetooth-controlled! You can install a simple Android App, pair with the car and control it either with on-screen controls or using the accelerometer in the phone.
As a standalone present it is pretty neat but like all remote controlled toys, I'm sure would be discarded after a few days use. However Santa didn't want to spend a fortune on a full-blown Arduino-based robot platform or an even bigger fortune on Lego Mindstorms.
It's when you start thinking about what is possible over time with the i-Racer that things get really interesting. Forgetting electronics for a minute, you could have huge fun making new shells for it out of different materials. Imagine a Foldify template for it so you could make printed paper shells. Lego might be a bit heavy but K'Nex plus some Sugru could work very nicely. Or what about bamboo food skewers or ice-pop sticks? Maybe just some stickers.
Then there is the code running on the car. The source is available so you can play around with it. Now this isn't the easiest thing in the world to do since the car is not Arduino so you need compilers and special programming dongles, but the option is there.
Taking that one step further, you could clip on other bits of electronics. I have a temp sensor, a PIR detector and an Ultrasonic distance detector all winging their way from China. You could use these to give the car a lot more "intelligence". There is also someone working on porting the car's code to Arduino since the microcontroller is compatible.
But that stuff is hard and more long term and wouldn't actually involved Fionn doing much. Always have to keep your focus on the "customer"! So I thought about it some more and realised that you could have enormous fun with how you control the car. The use of Bluetooth gives you a giant range of pretty cough easy possibilities.
So I started playing with some Python code and after a ton of dead-ends, Linux bugs and system problems I was finally able to talk to the car from my Ubuntu PC with a $2 Bluetooth dongle. (Details below)
Then I realised that this would be no use over Christmas as we spend it travelling to family houses around the country without the Ubuntu PC. My Windows laptop should work with tweaks but that's not for games! So I started looking at the Raspberry Pi. Whatever problems I had run into on my PC were 10x worse on the Pi. (More details below)
After a ton of messing I got keyboard control working the way I wanted over USB on the RPi. Which leads to the piece de resistance - MaKey MaKey control. MaKey MaKey is a beautifully simple idea. It's an Arduino-compatible board you plug into a PC and it emulates various key-presses and mouse clicks. You then connect whatever you want, as long as it is vaguely conductive, and use that for input. It famously uses bananas, pencil drawings and buckets of water as inputs to various fun software.
The Cheese Controlled Car (CCC)So Fionn finally had the ultimate car controller. 5 Pieces of Christmas Cheese connected to a Raspberry Pi via MaKey MaKey talking to a car over Bluetooth. Check it out in action: httpv://www.youtube.com/watch?v=qb9wso0pB4o If you want to try this yourself and run into any problems, pop a comment in below. Otherpossibilitiesinclude grapes (GCC): And Barbie (BCC): Now for the nasty details. Whilst these steps are quite short and the code is very simple, it took a week of evenings cursing, hacking and googling to get everything working right.
Technical Nitty Gritty
UPDATE 1: Much improved code compared to the simple one below is now available on GitHub.
The main steps in getting the code to run were as follows:
- Figure out Bluetooth on Linux usingBluez
- Figure out how to connect to car over Bluetooth using Python withPyBluez
- Sort out bad bug in Bluetooth on Debian (and therefore Ubuntu)
- Realise that most cheap micro Bluetooth dongles from China have duplicate MAC addresses and cannot talk to each other.
- Discover that Bluetooth dongle works on USB hub on Raspberry Pi at low-level but Bluetooth stack cannot see it. So connect it to one of USB ports on Raspberry Pi
- Discover that cheap Chinese Bluetooth dongles hang the Raspberry Pi after random amount of time
- Switch to using older bigger more expensive Bluetooth dongle
- Realise that Bluetooth dongle must be plugged in after booting Raspberry Pi in order for it to be detected
- Repeatedly curse the totally messed up implementation of USB on the Raspberry Pi
- Use a powered USB Hub to connect the MaKey MaKey and anything else like WiFi to the Raspberry Pi
- Figure out basic keyboard reading in Python
- Figure out reading keyboard in Python without carriage-return
- Try PyGame for keyboard reading but discover it needs a screen attached
- Figure out reading directly from USB with auto-repeat usingEvdevandpython-evdev(must be run as sudo)
Installs and Tweaks
sudo apt-get update sudo apt-get upgrade sudo apt-get install python-pip python-dev build-essential sudo apt-get install --no-install-recommends bluetooth sudo apt-get install bluez python-bluez bluez-hcidump sudo pip install evdev
Now you need to work around a nasty bug in Debian and Ubuntu. They have accidentally compiled in code for Nokia Series 60!
sudo nano /etc/bluetooth/main.conf
add this line to it:
DisablePlugins = pnat
Now plug in the Bluetooth dongle, power up the i-racer and run:
It should detect your dongle and report its MAC address. If it does, then run:
This should find the i-racer as a Dagu Car. Note its MAC address and then pair to it by running:
bluez-simple-agent hci0 00:12:05:09:94:26
where you replace 00:12:05:09:94:26 with the MAC address of your car. The PIN is either 1234 or 0000
In a Python shell, (sudo python) run the following to find out your Keyboard or MakeyMakey ID:
from evdev import InputDevice, list_devices devices = map(InputDevice, list_devices()) for dev in devices: print( '%-20s %-32s %s' % (dev.fn, dev.name, dev.phys) )
My MaKey MaKey comes up (with KB/Mouse/Joystick disconnected) as:
/dev/input/event0 Unknown USB IO Board usb-bcm2708_usb-1.3.3/input2
The CodeFinally run this code as sudo to control the car using the MaKey MaKey:
import sys import select import tty import termios import bluetooth import time from evdev import InputDevice, categorize, ecodes if __name__ == '__main__': dev = InputDevice('/dev/input/event0') bd_addr = "00:12:05:09:94:26" port = 1 sock = bluetooth.BluetoothSocket( bluetooth.RFCOMM ) sock.connect((bd_addr, port)) for event in dev.read_loop(): if event.type == ecodes.EV_KEY: key_pressed = str(categorize(event)) if 'KEY_LEFT' in key_pressed: # 0x5X for left forward. 0x51 very slow. 0x5F fastest sock.send('\x5A') if 'KEY_RIGHT' in key_pressed: # 0x6X for right forward. 0x11 very slow. 0x1F fastest sock.send('\x6A') if 'KEY_DOWN' in key_pressed: # 0x2X for straight backward. 0x21 very slow. 0x2F fastest sock.send('\x2A') if 'KEY_UP' in key_pressed: # 0x1X for straight forward. 0x11 very slow. 0x1F fastest sock.send('\x1A') if 'KEY_SPACE' in key_pressed: #stop sock.send('\x00')
Note that this is extremely simple control with fixed speed just to prove the idea works. Real code will go up on GitHub when it has much more usable controls with automatic acceleration/deceleration etc and after I make it configurable with any i-Racer and with the MaKey MaKey on any USB port.
What's next?Apart from extra sensors and new outer shells, I want to do more playing with controllers. I have an Arduino Joystick shield, Arduino Nano and serial Bluetooth breakout board coming from China. It'd be cool to make some sort of interesting custom controller case with the Arudino controlling the car. I may also get an Arduino Esplora.
The other really obvious one is to stick with the RPi and pair a Wiimote to it too. That could be the ultimate controller for the car.
One downside of the i-Racer is that Arexx, the Chinese manufacturers, have not released the source-code to their Android App, only to the car software itself. Given how trivially simple the control protocol is, it should be very easy for someone to create Open Source equivalents for Android and iOS or even WP8 or BB10. I'm currently poking around inside PhoneGap's Bluetooth support (this plugin) to see if a simple cross-platform Mobile Hybrid App could be created.
If this is a success, with success being defined as Fionn remaining interested, then I'll bite the bullet and start getting the parts for one of the good Arduino robot kits out there. A good intermediate step might be the Sparkfun Protosnap Minibot Kit. After that, the sky is the limit: