Command serial interface for the Robosapien V2
![]() |
The goal of this project is to add an RS-232 serial interface to a Robosapien V2 so that it can be remotely controlled from a computer. After making this mod, you will be able to make your robot do any of the 70+ built-in commands: talk, walk, stop, raise/lower the arm, etc. by typing commands from the keyboard. In Part 3, we’ll discuss how to add more complex behaviors such as grab an object, bow or wave SOS.
Some of you are probably thinking… computers these days don’t even have a serial port. Why use that? Well, because a serial interface is simple and cheap to implement.. and quite reliable. Better yet, if you decide to do so, you can easily add wireless capabilities to your robot by tacking on a serial-to-Bluetooth or serial-to-Zigbee adapter. If your computer does not have a built-in serial port, all is not lost. You can readily buy a USB-to-serial converter as a workaround as we will discuss in Part 2.
Designing the RS-232 serial interface
As it turns out, the RSV2 already comes with an internal serial decoder circuit that operates at 3.3 volts. When you use the RSV2 remote controller, it wirelessly sends commands as a series of pulses over a 39.2KHz Infrared (IR) carrier frequency– light that is invisible to the naked eye. A TV remote works in a similar way but in our case, the remote controller is sending binary data to tell the robot to move a limb, say something, etc. K.Smith has a nice article describing this although it is specific to the original Robosapien model.
The computer serial interface we are making works by tricking the RS V2 into thinking that it is receiving commands from the remote controller when in fact we are injecting the serial pulses directly into its circuit. To do this, we will add a microcontroller (or “MCU” for short) which acts as a middleman or “wedge” between the computer and the robot. Its main purpose is to intercept the commands sent from the computer or IR remote and relay the command to the robot. Thus the MCU will have two physical interfaces: (1) an RS-232 serial port that connects to a computer, and (2) a digital Output pin that injects the serial pulses into the RSV2′s internal serial decoder circuit.
Now that we’ve covered the general idea, it is time to hash out the details. We’ll do this in two parts. First we will put together the microcontroller that receives computer commands and generates the serial pulses. Then we will connect the microcontroller to the robot. Let’s go.
Building the Serial Interface Circuit
While there are many ways to build a serial interface circuit, I chose to make one using an Arduino microcontroller. My reasons are:
- Arduinos are cheap. You can buy one for around $20-$30 US dollars, less if you’re willing to build it from a kit.
- Easy to program. Arduino’s are preloaded with a bootloader. That means you can program it by simply downloading your code from your computer using an RS-232 serial cable. No need for an embedded programming hardware.
- Large, active community. There are tons of Arduino-based projects available and an equally large number of Arduino enthusiasts willing to help others.
For my robot I bought the RBBB (Really Bare Bones Board) Arduino kit, $12.95 from Modern Devices. I chose this because I wanted to learn how to build an Arduino from scratch. If you choose this option, you will need a soldering iron, solder and some free time to put it together (and get it to work
. If you want to skip this adventure entirely, you can also buy a preassembled and fully tested RBBB kit for $22. Alternatively, you can buy other types of Arduino boards from sources such as SparkFun. (DISCLAIMER: I have no affiliation with either Modern Devices or SparkFun. I just like their products.)
Programming the Arduino
Once you have a working Arduino, the next step is to program it. Our “wedge” logic is pretty simple. It does the following in an infinite loop:
- Check if there is a command sent from the IR remote controller. If there is, read it and go to Step 3.
- Check if there is a command sent from the computer. If there is, read it and go to Step 3. Otherwise, loop again.
- Inject the command to the Robosapien’s serial input by generating a series of pulses on the Arduino’s Pin 13.
- If enabled, echo the byte command on the serial port connected to the host computer.
Here is the actual code. Credit duly given to Karl Castlet:
// rs_commander.c - Arduino-based serial port controller for Robosapiens
// Modified: 9/15/10
// Author: Ben Bongalon (ben@borglabs.com)
// Adapted from Karl Castlet's code
// (http://www.arduino.cc/playground/Main/RoboSapienIR).
// I refactored it a bit and added support for the Robosapien V2 and
// other models (untested).
// Robosapien's model types. Credit to AiboPet's BoneYard
// (http://www.aibohack.com/robosap/ir_codes_v2.htm)
#define RS_MODEL_ROBOSAPIEN_V1 0x00
#define RS_MODEL_ROBORAPTOR 0x01
#define RS_MODEL_ROBOPET 0x02
#define RS_MODEL_ROBOSAPIEN_V2 0x03
#define RS_MODEL_ROBOREPTILE 0x04
#define RS_MODEL_RSMEDIA 0x05
#define RS_MODEL_ROBOQUAD 0x06
#define RS_MODEL_ROBOBOA 0x07
#define RS_BIT_HIGH 1
#define RS_BIT_LOW 0
// User-configurable parameters
int RSModel = RS_MODEL_ROBOSAPIEN_V2; // your Robosapien model
boolean RSEcho = true; // echo commands to host PC?
int irSignalPin = 2; // Infrared wire connects to this Pin
int ctrlPin = 13; // Generate the pulses on this Pin
volatile int RSIRCommand; // Single byte command from IR
volatile int RSBit=9; // Total bits of data
boolean RSIRCommandReady=false; // IR command was received?
int bitTime = 833; // bit width in microseconds (1/1200 second clock)
#define INTER_CMD_TIME 10 // msecs before sending next command
// Encode a binary '1' or '0' on the wire
void WriteBit(int bit)
{
digitalWrite(ctrlPin, HIGH);
delay_ticks((bit == RS_BIT_HIGH) ? 4 : 1);
digitalWrite(ctrlPin, LOW);
delay_ticks(1);
}
// Send a byte down the wire (MSB first)
void WriteByte(byte b)
{
WriteBit( (b & 0x80) == 0x80 );
WriteBit( (b & 0x40) == 0x40 );
WriteBit( (b & 0x20) == 0x20 );
WriteBit( (b & 0x10) == 0x10 );
WriteBit( (b & 0x08) == 0x08 );
WriteBit( (b & 0x04) == 0x04 );
WriteBit( (b & 0x02) == 0x02 );
WriteBit( (b & 0x01) == 0x01 );
}
// Start each Robosapien commands with a preamble
void WritePreamble()
{
// Pull down the I/O line for 8 ticks
digitalWrite(ctrlPin, LOW);
delay_ticks(8);
// Send the Robosapien model type (not needed for the orginal Robosapien)
if (RSModel != RS_MODEL_ROBOSAPIEN_V1) {
WriteBit( (RSModel & 0x08) == 0x08 );
WriteBit( (RSModel & 0x04) == 0x04 );
WriteBit( (RSModel & 0x02) == 0x02 );
WriteBit( (RSModel & 0x01) == 0x01 );
}
}
// Add N clock ticks of delay
void delay_ticks(int ticks)
{
delayMicroseconds(ticks*bitTime);
}
// Receive a bit at a time.
void RSReadCommand()
{
delayMicroseconds(bitTime + bitTime/4); // about 1 1/4 bit times
int bit = digitalRead(irSignalPin);
if (RSBit==9) { // Must be start of new command
RSIRCommand=0;
RSBit=0;
RSIRCommandReady = false;
}
if (RSBit<8) {
RSIRCommand <<= 1;
RSIRCommand |= bit;
}
RSBit++;
if (RSBit==9) {
RSIRCommandReady=true;
}
}
void RSSendCommand(int opcode)
{
WritePreamble();
WriteByte(opcode & 0xFF);
digitalWrite(ctrlPin, HIGH);
if (RSEcho) {
Serial.print(opcode, BYTE);
}
delay(INTER_CMD_TIME); // buffer time before processing next command
}
// Initialize the serial port, GPIO pins and interrupts
void setup()
{
Serial.begin(9600);
pinMode(irSignalPin, INPUT);
pinMode(ctrlPin, OUTPUT);
digitalWrite(ctrlPin, HIGH);
attachInterrupt(0,RSReadCommand,RISING);
}
// Main program loop
void loop()
{
// If a command was received from the IR remote, relay it to the robot
if (RSIRCommandReady) {
RSSendCommand(RSIRCommand);
} // otherwise, check the serial port for new commands sent by computer
else if (Serial.available() > 0) {
int opcode = Serial.read();
RSSendCommand(opcode);
}
}
As you can see, the code does not do much more than relay the sent commands to the robot. The reason for this spartan functionality is that I moved the intelligence on the host (PC) side. More on that later. Right now, let’s get the code running on the Arduino. To do that, install the Arduino environment on your computer, compile the code and upload it your Arduino board. See the Getting Started page for details.
Links
Part 1 – Command serial interface for the Robosapien V2 (this page)
