After half a lifetime of dreaming about it, I've finally started building a robot. It's based on a remote controlled tank, an Android mobile phone and a IOIO board which connects the two via USB.
Update: source is available on GitHub including some basic image processing stuff.
The IOIO is a small circuit board with a USB socket, a microcontroller and 48 input/output pins. Plug it into an Android phone and you can use software to write to or read from each of the pins. Roughly speaking, on is 3.3V and off is 0V. Some of the pins can also function as analogue inputs and PWM outputs.
I initially looked at Arduino but in the end IOIO made more sense for a number of reasons:
- Pure Java API - no new languages to learn
- USB built in - Arduino controller would need a USB host shield to communicate with the phone
- Cheaper than Arduino + USB shield
- More IO pins than I could ever need
In theory, the IOIO board works with any Android device. In practice, there are many phones it doesn't work with. The first phone I bought had to be returned to the shop and the second phone only worked after upgrading it to a non operator branded version of Android. On the other hand it worked straight off when I tested it with someone else's Nexus One and HTC Desire.
The first step was to dismantle the tank and strip out the internal RC circuit. That left only the tracks, drive motors (and gears), battery and on-off switch. Sadly that meant losing the BB gun in the turret. There's always a next time.
Due to current draw issues, I couldn't just connect the tank's motors to the output pins of the IOIO. At best it would not work, at worst it could fry the circuit. I bought a TB6612FNG motor driver circuit which controls two motors using a PWM channel and two digital channels per motor. It connects directly to the battery to provide up to 1A current to each motor. I was initially worried about damage from back-EMF but so far that hasn't been a problem.
The final pieces of equipment were a set of header pins to solder into the IOIO and TB6612 and a solderless breadboard to make it easy to reconfigure the circuit if necessary.
In the photo above:
- The black and yellow wires, centre right, are 10V and ground from the battery (via on-off switch)
- The black and red wires, top and left, go to the motors
- The blue wires are carrying 10V from the battery
- The yellow and green wire is carrying 3.3V from the IOIO to drive the TB6612 chip
- The brown wires are ground
- The TB6612 and IOIO control pins are connected through the breadboard
I'm still not sure what this robot will ultimately do but an obvious first step seemed to be to make it remote controllable over the internet.
This is my first Android project but thankfully the Android SDK and documentation are outstanding. With the help of a few tutorials I went from Hello World to a simple app that accepted HTTP connections in just a few hours.
I now have a basic HTTP server on the phone which serves up a single web page and then listens for commands sent from that page over AJAX. Sending real time commands over HTTP is tricky because of the overhead in setting up TCP connections and the fact that requests may arrive out of sequence. I got around the first problem by using HTTP 1.1 persistent connections and the second by including a counter variable with each request. Any request with a counter value less than the last one received is ignored.
Using multiple threads on the phone to handle each incoming request, I've got response times over wifi down to around 30ms which is good enough. I've not yet tried it over 3G but I suspect network latency may be a big problem.
Likely next steps are:
- Stream video from the camera to the browser so I can drive it from another room (or country)
- Improve the input UI to make it easier to drive
- Implement some basic machine vision algorithms such as line following or the classic photovore behaviour (drives towards light)
Other ideas for the future:
- Add a laser line to the front to make a budget laser rangefinder
- Let other people control it over the internet
- Use the Android text-to-speech and the phone screen to give it a voice and a face
- Hook it up to a thermal receipt printer and make it physically deliver my emails
- Implement a behaviour-based robotics API with swappable behaviours
- Foster a community of robot builders using the same API to create a pool of behaviours which can be combined to generate highly complex robot personalities