Monday, January 17, 2005

How to you get a PC (or a Pocket PC or a Palm) to talk to all that robot hardware?

So you want to create a robot. You've got a great idea -- you're going to use that old Palm Pilot you have sitting around, or maybe a Pocket PC, or maybe you agree with Via and think a Mini-ITX PC motherboard is going to 'be all that'. Heck, you even have an old set of rollerblades you haven't used in two years, an erector set, and some windshield wiper motors you've been saving from your '57 Chevy for the day when you knew they would come in handy.

So you have your computer of choice and your compiler and you've written your first line of code, "Console.WriteLine("Hello, Robot");" and compiled it and it's all very exciting. But there's a missing piece. How can you get this computer of yours to talk to the windshield wiper motors? OK, more seriously, how can you get it to talk to a couple of servos, maybe a RC car's speed controller, perhaps even a Sharp IR distance sensor or a digital compass?

The glue that you're going to need is called a microcontroller. A microcontroller is a modern day marvel -- it combines a very small computer, RAM storage, and low level input/output lines into a single cheap, small chip. They're really useful for robotics because they're smart enough to talk to a PC using a high level communication protocol like RS-232 or sometimes even USB or Ethernet while at the same time they can talk to hardware devices using a much lower level protocol like pulse wave modulation (PWM), analog (voltage) to digital converters (A/D converters or just A/D for short), Digital I/O, and a microcontroller-specific serial bus called I2C.

Here's a brief overview of each type of signal:

PWM (Pulse Wave Modulation)
PWM takes the current on a wire and turns it on and off rapidly in pulses. It has a frequency (how many times a second could it potentially go on and off) and a duration (what % of the time is it on versus off).
PWM is commonly used in robotics to control "how much" of something since it's much more reliable to measure PWM pulses than minute fractions of a voltage change due to how microcontrollers work. You'll frequently see PWM used to control the position of a servo, the speed of a motor, or the intensity of an LED.

A/D (Analog to Digital converters)
A/D takes a current on a wire and measures it's voltage. Is it at 3.1V or 5.0v or 0.5v?
A/D is commonly used to measure 'resistive' sensors, like cadmium sulfide light detectors or temperature sensors. It's also useful when using the Sharp IR distance sensors (GP series).

Digital IO (I'll call it DIO)
A DIO port are kind of like a "dumb" A/D port in that it generally measures if the voltage on a wire is < 2.5 V (off) or > 2.5 V (on). Even this "dumb" reading is useful for simple inputs like 'is that button or switch pressed' for an on button or a whisker bump sensor. They are also generally configurable as output ports where they can be used to do things like turn on an LED. Many times, using microcontroller code that's tightly written, they can also be used to build up higher functionality by switching on and off very rapidly -- from making primitive music on a buzzer to "bit-banging" (AKA rapidly banging out bits, generally by dedicating all the microcontroller's CPU cycles to this one function) a higher level communications protocol like RS-232 or USB or I2C.

I2C is a microcontroller serial protocol that is used much like RS-232. The reason I2C exists is it is simpler to implement on a microcontroller and it can be used as a "multi-master bus", AKA more than one device can be attached to the wire (like USB). I2C is commonly implemented in hardware on microcontrollers and so it makes a good choice to be used when hooking multiple microcontroller assisted sensors together. There are a plethora of similar microcontroller serial protocols out there that compete with I2C, but I'm only talking about I2C here because it's the protocol that the devices and sensors I like use (see Devantech and all their cool stuff). You can debate which one is "best" just like all the other "best of/shudda used" debates out there, but I'm just interested in making my robot work, nu?

Alright, do you have a point already?

Yes I do. I'm just warming up to it, OK?

After a lot of searching and spurious buying of excess equipment that took my money and now takes up my shelf space, I settled on the Acroname Brainstem the way I attach my "brains computer" (AKA Mini-ITX PC or Pocket PC or Palm Pilot) to my robot. Why did I choose the Acroname Brainstem?

  • It has a good selection of ports

  • The Brainstem GP comes with a decent selection of ports, enough to make a moderately complex robot. It has 2x I2C, 4x PWM, 5x DIO, 5x A/D ports, and 1 RS-232 port. In other words, I can attach it to my computer, four servos, a digital compass, two IR range finders, a gyro, and a two-axis accelerometer. Yep, you can definitely do some non-trivial robotics there.

  • It has a great programming interface

  • I was first attracted to the Brainstem because it was being used by both Palm Pilots and Pocket PCs to drive cool robots. Back when I was first starting, I was totally convinced that a Pocket PC was going to be my robotic brain. I was wrong about that, but I ended up being right about the Brainstem. With good documentation and great libraries and sample code for WinCE, Windows, Palm OS, and Linux, the Brainstem is easy to use from a variety of programming environments and tools.

  • It has a fast slave mode

  • Ah, this is an important and not necessarily obvious one. If all you want your robotic microcontroller to do is feed data back and forth from your "brain computer", you want it to do so rapidly. Most microcontrollers out there (Basic Stamp, OOPic, Handyboard, etc.) concentrate on writing programs that will run when a computer *isn't* attached. While you can do so on the Brainstem too, Acroname has put a lot of effort into making sure the Brainstem is a good "router", AKA a device that "routes information" between places without getting in the way.

    Also, the Brainstem can use RS-232 at 112kbaud and it has an extremely low protocol overhead so you are getting mostly data over that link. Some microcontroller choices don't do a good job with this. For instance, the controller that comes with the ER1 system has a "fast USB" connection back to the host computer, but their wire protocol is, ah, lacking and they didn't exactly work on the efficiency as a #1 priority. Trying the best I could, I was only able to get 3 readings per second off my ER1's A/D ports when I had other things going on at the same time (like controlling the motors, etc.) which is completely insufficient for writing routines like obstacle detection and avoidance.

  • It's well supported

  • You don't really appreciate a knowledgeable dude answering the phone on the second ring or responding to an intricate forum post at 11 PM at night until you really need it. In the dozen or so times over the past few years that something around the Brainstem has stumped me, Mark or Steve from Acroname have cleared it up within 12-24 hours. You can't beat that.

  • It's expandable

  • Need to control some high amp motors? You can daisy-chain a Brainstem Moto to a Brainstem GP (General Purpose) over the I2C bus. Need to add another 5 A/D ports? Daisy-chain another Brainstem GP or attach one of the many I2C controlled slave boards out there.

  • It's cheap

  • $79 is a lot better deal than the cost of getting ahold of a C compiler, microchip programmer, and making up some PCB boards. Believe me, I know :-) With the support and documentation and out of the box functionality you get, it can't be beat.

    Well, that's it. I think you get the drift, I like the Acroname Brainstem. When I get off my duff and finish off my work, I'll be publishing a Managed C++ wrapper for the Brainstem SDK that makes it really easy to take advantage of the Brainstem from any managed programming language like C# or VB.Net or any of the 22 or so others out there.