Simon and Sam are the two Android figures in the picture below. Simon is the one on the right, with the slick paint job and arms to his sides. Sam is the one on the left, who has lost his head. They both keep me company at my desk, but outside of that, neither Simon nor Sam do all that much. Not very droid-like, in my opinion.
Simon and Sam before their transformation.
Now, after some modifications, the two Androids are able to talk to each other by sending and receiving pulses of infrared light. Sam will do everything that Simon tells him to do. If Simon’s right arm is rotated 30 degrees, Sam will rotate his own arm 30 degrees. If Simon’s left arm is pointed to the sky, Sam will point his own left arm to the sky. Simon’s arms can be moved by an outside user. Sam’s arms are controlled by two tiny servo motors.
How does it work?
Simon's left eye is an infrared LED. When a voltage is applied, the eye will emit infrared light (invisible to us humans, but not to these droids). Sam's right eye is an infrared detector. When it sees infrared light, it sends a signal to Sam's brain (an ATMega328 microcontroller).
The two droids speak in a binary language of short and long pulses. When Sam sees a pulse, he interprets it as either a zero (short pulse) or a one (long pulse), and stores the information. Once Sam has seen eight pulses -- a full byte -- he follows the instructions that they represent.
How does Simon know what byte to send?
Each of Simon's arms is connected to a potentiometer -- so rotating the arm will change the voltage across two adjacent pins. By measuring this voltage, we know the angle of his arms.
Simon sends Sam an instruction telling the droid to rotate its arm to the same angle. The instruction takes the form of a byte, as shown below.
Sam receives the instruction and uses the servo motor to move the arm into the the correct position.
The two droids didn't learn to talk easily -- I ran into a few obstacles along the way. Since these types of problems are not necessarily unique to the Talking Androids project, I've detailed them here, in case anyone else has similar difficulties.
Simon tells Sam, "point your arm straight out!". Sam points his arm as instructed...and then starts to wobble it rapidly, when we want him to keep it still. That's because the angle readings aren't perfect -- when we take measurements from Simon's arms, the values can vary by few degrees. As a result, Simon is sending a somewhat confusing message: "move to 80 degrees, move to 81 degrees, move to 80 degrees, move to 81 degrees...".
There is a simple fix for this on the software side. A low-pass filter can be used to smooth out the high-frequency variations in a signal -- such as the wobbly potentiometer readings from Simon's arms.
Implementing this solved the problem completely. Sam's arms move smoothly, as desired.
Filtering ambient light
My early adventures in infrared involved an emitter and detector pair from Sparkfun (link here). The emitter is a simple infrared LED. The dectector is an NPN phototransistor -- the more IR light it is exposed to, the more current flows through the component. By taking a voltage measurement across the two pins, we can determine how much IR light is present. The lower the voltage, the greater the amount of infrared light.
The original plan was to use this phototransistor as Sam's eye. Simon would send a pulse of infrared light. Then, when the voltage across Sam's eye dropped below a certain threshold, Sam would be able to tell that Simon was sending a message.
The problem is that Simon isn't the only source of infrared light -- there's ambient infrared light in the environment as well. Worse still, the amount of ambient infrared light changes depending on the time and place. This means that the threshold necessary to detect Simon's message is always changing.
Television remotes use infrared technology as well. They overcome this problem by pulsing the infrared light at a particular frequency (usually 38 kHz). The infrared detectors are then tuned to ignore IR light at any other frequency (using a band-pass filter).
Infrared sensor (photo from Adafruit)
Adafruit sells an IR sensor tuned to 38 kHz, which is what I ended up using for Sam's eye. It has an output pin that goes low in the precense of such light and high in the absense of it. Simon, then, doesn't send out solid pulses of light -- Sam wouldn't detect it. Instead, for each pulse, Simon's LED is actually flickering on and off 38,000 times per second.
Current draw is critical
One of my self-imposed requirements for this project was that all electronics had to be completely contained within the droids. No protruding wires, no plugs. I had to find a battery that was small enough to fit inside Simon and Sam, and powerful enough to make everything work.
My primary concern was the servo motors, which require a relatively large amount of current to operate. I wanted the droids to work as long as possible before running out of power, so I went about finding a battery with a high capacity. I chose a couple of coin cell batteries from Mouser that could last for 1000 mAh.
What I did not look at was the maximum current draw these batteries could handle (a mere 0.2 mA). They may have the capacity to run for hours and hours, but the maximum current they can supply at any one moment was much lower than what I needed.
I later purchased two polymer lithium ion batteries from Sparkfun. These batteries have a maximum discharge current of 200 mA, which worked well for this project.
Finding tiny servo motors is a challenge -- I looked far and wide, and the only ones that fit the bill were these ultra-micro servos from HobbyKing.
These servos, unfortunately, are not very reliable. One arrived broken in the mail. Others stopped working mid-test for reasons I still can't comprehend. I ended up throwing away three of these motors before I found two that worked well.
HK-5320 ultra-micro digital servo (photo from HobbyKing)
Questions? Comments? Feel free to contact me here.