I managed to get a decent serial protocol and a simple example that drives the robot using an Xbox 360 controller connected to a Linux PC.
Step 1: What it can do...
The best thing about it is that you can add whatever you want to an Arduino robot. It only takes a little bit of interface code to control extra stuff and get input to the computer.
Step 2: Parts
1) Arduino Duemilanove w/ ATMega328
This is the newest Arduino, and since I just got it a few days ago I have the newest one. However, the code is small enough that it should easily fit on any Arduino. It could probably even fit on an ATTiny (if I build a robot controller apart from the Arduino, the ATTiny 2313 looks like a good choice, it's smaller and cheaper but still has plenty of outputs and a serial UART interface)
2) Vex Robotics Platform
I got a Vex kit a few years ago to build a radio-controlled robot to pick up stuff for a high school competition. I constructed the basic "square bot" base that has 4 wheels driven by two motors. You could substitute other robot bases if you have some other platform you want to drive. The important thing to note is that Vex motors are essentially continuous rotation servos, they use pulse-width modulation to signal how fast and in what direction to turn. The Vex motors are nice because they have a high range of operating voltages, somewhere between like 5 to 15 volts. I'm using 12V because I had a 12V battery. For most standard hobby servos, you'll need a lower voltage (often 6 volts).
A robot is useless without a power supply. For testing I use a standard 9V wall-wart adapter from RadioShack, but for cordless operation I found a 12V NiMH battery pack in an ancient laptop. Although it doesn't hold enough of a charge to run the laptop it drives my Vex robot just fine. It can also power the Arduino using the Vin input pin on the power connector, the Arduino will regulate the 12V down to 5 and even output it out the 5V output pin on the power connector.
4) Basic Breadboard
I'm currently using a breadboard to wire everything up. Eventually I'll get a nicer prototyping board and solder on some more permanent connections but for now the breadboard makes it easy to change things. My breadboard is SparkFun's "basic breadboard", just a breadboard on a metal plate with 3 terminals.
5) MAX232-based RS232-TTL converter
If you want to drive your robot using an RS-232 serial port connection (as opposed to the Arduino's built in USB) you can use an RS232-TTL converter. I'm using a MAX232 because I had a few of them lying around and I soldered it on a little piece of prototyping board with the required capacitors. I need RS-232 because my old laptop only has one USB port and I'm using that for a game controller to drive the robot.
6) Extra parts as desired
For easy debugging of the serial protocol, I put an RGB LED on it (got one with my Arduino order cause they sounded cool). The light flashes red, green, blue in sequence when the Arduino boots up to show the robot has rebooted and then lights up Green when a motor packet has been received, Blue when a fan packet has been received, and Red when a bad or unknown packet has been received. To drive the fan I used a standard NPN transistor (the same ones I demonstrated in my last Instructable) and a resistor in between the transistor and the Arduino (the transistor was drawing too much current and heating up the Arduino, so I put a limiting resistor in to stop it).
Step 3: Arduino and PC Programming
On the Arduino we will need a serial interface that allows the PC to control the motors. We will also need a PWM servo drive system to send the correct signals to the Vex motors and make sure they go in the correct directions when given the right values. I also added some simple LED flashing, mainly for status indication but also because it looks cool.
On the PC we will need to open the serial port and send frames of data that the Arduino program will understand. The PC also needs to come up with motor values. An easy way to do this is to use a USB game pad or joystick, I'm using an Xbox 360 controller. Another option is to use a networked computer (either a netbook or a small mini ITX board) on the robot itself to drive wirelessly. With a netbook, you can even use the onboard webcam to stream back a video feed and drive your robot remotely. I used the Linux sockets system to do network programming for my setup. One program (the "joystick server") is run on a separate PC that has a controller plugged into it, and another program (the "client" ) is run on the netbook connected to the Arduino. This links the two computers and sends joystick information to the netbook, which then sends out serial packets to the Arduino that drives the robot.
To connect to the Arduino using a Linux PC (in C++) you must first open the serial port at the correct baud rate and then send the values using a protocol that you have also used on the Arduino's code. My serial format is simple and effective. I use 4 bytes per "frame" to send the two motor speeds (each is a single byte). The first and last bytes are hard-coded values that are used to keep the Arduino from sending the wrong byte to the PWM code and causing the motors to go crazy. This is the primary purpose of the RGB LED, it flashes red when the serial frame was incomplete. The 4 bytes are as follows:
255 (hard coded "start" byte),
To ensure reliable reception of the data, make sure you put enough delay between program loops. If you run your PC code too fast, it will flood the port and the Arduino may start dropping or even mis-reading bytes. Even if it doesn't drop information it can also overflow the Arduino's serial port buffer.
For the Vex motors, I used the Arduino Servo library. Since Vex motors are just continuous rotation motors, they use the exact same signaling that servos use. However, instead of 90 degrees being the center point, it is the stop point where the motor does not spin. Lowering the "angle" causes the motor to start spinning in one direction, while raising the angle makes it spin in the other direction. The farther away from the center point you are, the faster the motor will spin. While it is not going to break anything if you send values greater than 180 degrees to the motors, I would advise limiting the values from 0 to 180 degrees (which in this case are speed increments). Because I wanted more control and less out of control robot driving, I added a software "speed limit" to my program that doesn't allow the speed to increase above 30 "degrees" in either direction (range is 90 +/- 30). I plan on adding a serial port command that changes the speed limit, so that the computer can remove the limit on the fly if you want to go fast (I've been testing in small rooms so I don't want it to speed up and crash into the wall, especially with a netbook on it).
For more information, download the attached code at the end of this Instructable.
Step 4: Add a Netbook to explore unknown worlds from a distance
There are many ways to get this working, many are probably a lot easier than mine, though I am not familiar with Processing or script-based languages so I opted to use Linux and C++ to create a wireless control link between my base station (a.k.a. old ThinkPad) and my new Lenovo IdeaPad netbook that is connected to the Arduino drive base. Both PC's are running Ubuntu. My ThinkPad is plugged into my school's LAN and my IdeaPad is connected to my WiFi access point that is also connected to the school's LAN (I couldn't get a reliable video stream from the school WiFi since everyone else is using it, so I set up my own router to provide a good connection). A good connection is especially important in my case since I have not implemented any error-checking or timeout. If the network connection suddenly drops, the robot keeps going until it crashes into something or I run and stop it. This is the main factor behind my decision to slow down the drivetrain both by gearing the motors down and implementing a software speed limit.
Step 5: Get a Video Feed
Next, click Stream to go to the next menu. Click Next, then select and add HTTP as a new destination. Now set up Transcoding to make the stream smaller. I made a custom profile that uses M-JPEG at 60kb/s and 8fps. This is because using an advanced codec like MPEG or Theora will eat up massive CPU time on a netbook's Atom processor and this can lead to your video feed stopping for no apparent reason. MJPEG is a simple codec that is easy to use at low bitrates.
After starting your stream, open up VLC on your other PC, open a network stream, select HTTP, and then type the IP address of your netbook (either local or Internet depending on how you're connecting) followed by ":8080". You need to specify the port for some odd reason, otherwise it gives you errors. If you have a decent connection, you should see your webcam's feed on your other PC, but it will have a slight (about a second) delay. I don't know exactly why this delay occurs, but I can't figure out how to get rid of it. Now open up the control app and start driving your netbook robot. Get a feel for how the delay works when driving so you won't crash into anything. If it works, your netbook robot is finished.