Project 2: Taking Indirect Control


Ultimately we want to replace the RoboPet’s brains so that we can teach him more sophisticated behavior than his poor, feeble existing one. For now, though, we will satisfy ourselves with indirectly controlling its current brain. We will do this by lying to it.

To accomplish this, we are going to use an Arduino Pro Mini 328 we got from SparkFun. We used the 5V version because that’s what we had lying around, but in hindsight the 3.3V version might be a better choice.


We wanted to be able to easily connect and disconnect our hardware during development, and also wanted to “do no harm”. That is, we wanted to be able to easily bypass our changes and restore the RoboPet to its original state.

We decided to abuse a set of long jumper wires we had sitting around. Each wire had a cheap male and matching female connector on its ends. They wouldn’t put up with much use, but they’re a temporary thing. Once we’re happy with our design, they will be removed and replaced with soldered connections.

We chose four different colored wires and cut them in half, so we had 4 pairs of wires, a male and female one of each color.

On the Arduino, we soldered two of the male wires to the RAW and GND pads. This is how we’re supplying power to the board. The other two male wires are soldered onto pads 2 and 5. Pin 2 will be our input from the IR sensor, and Pin 5 will be our output to the RoboPet’s old brain.


Our color scheme: Black is ground, white is power, brown is output, and gray is input. The pins on the right are a temporarily installed FTDI header to allow the device to be programmed.

Inside the robot, we located the white wire leading from the IR sensor connector C05 to the head. We cut this about halfway up and soldered the female wire matching the one connected to pad 2 to the end of the white wire leading to the head. The other end of the white wire got soldered to the female wire matching the one connected to pad 5.

In the end, the wiring is: The white wire leads from the IR sensor to pad 2 on the Arduino. Conceptually, the white wire continues out from pad 5 on the Arduino to the original IR Receiver connection. We have inserted our controller between the RobotPet’s brain and his eye.

Locating the power connector C01 on the mainboard, we cut away some insulation on one of the red wires and soldered a female lead onto it. We did the same thing to one of the black wires. It doesn’t matter which you use, both reds and blacks tie together anyway.

A note about power: The drain on the 4 AAA cells when the RoboPet operates is so large that it is impossible to power the Arduino using them as well, so the Arduino needs its own power source. Nonetheless, we need access to the GND from the RoboPet’s battery back, and while we were at it, we tapped into the hot side from the battery board as well. This is because soon we will be replacing the AAA battery pack entirely in favor of LiPo rechargables, at which time we’ll make use of that hot lead.

In the meantime, we power the Arduino by doing one of the following. Remember, no matter which one is used, it’s still necessary to connect the Arduino ground lead to the robot’s ground lead.:

  • connecting a 9V battery to the power leads we installed
  • connecting a wall-wart power supply that produces between 5 and 12 volts to the power leads we installed
  • connecting the FTDI programming cable.


To enable the RoboPet to operate without modification, completely remove the Arduino and install a jumper between the two IR connections we installed.

To install the Arduino, connect all of the wires to their color-matched counterparts EXCEPT THE POWER. You’ll be making three connections: the two IR connections and the ground. Turn on the RoboPet, then apply power to the Arduino, and you’re off and running.


To support our efforts, we made a library to contain all of the nasty details of operating the RoboPet. As of this writing, the library only handles IR communication, but it will expand as the project progresses.

Here is a little test Arduino sketch. Build this along with our RoboPet library and install it on your Arduino. Install the Arduino into your robot. The robot will behave normally unless you press “Stop” twice on the RoboPet remote. When that happens, the LED on the Arduino will light to indicate that it has taken control, and it will put the robot into guard mode. Press Stop twice again to release control.

If you hook up a serial monitor, then when you press buttons on the remote you will see the command codes the Arduino is receiving from it.

#include <RoboPet.h>

// Hardware Config
#define PIN_IR_IN         2
#define PIN_IR_OUT        5
#define PIN_INCONTROL     13      // pin 13 is onboard LED

RoboPet       Pet;
RoboPet::Cmd  LastCmd  = RoboPet::Cmd::None;
boolean       PassThru = true;

void setup() 
  Serial.begin( 9600 );
  Pet.Init( PIN_IR_IN, PIN_IR_OUT );
  digitalWrite( PIN_INCONTROL,LOW );

void loop() 
  RoboPet::Cmd curCmd;
  curCmd = Pet.GetCmd();

  if( curCmd != RoboPet::Cmd::None )  // We have a command waiting
    // Check if a command came in before we processed an earlier one
    if( Pet.GetOverflowFlag() )      
      Serial.println( "****> Overflow <****" );
    if( Pet.GetErrorFlag() )
      Serial.println( "****> Error <****" );

    Serial.print( "Got new command: 0x");
    Serial.print( (int)curCmd, HEX );
    Serial.println( "" );
    if( curCmd == RoboPet::Cmd::Stop && LastCmd == RoboPet::Cmd::Stop )
      curCmd = RoboPet::Cmd::None; 
      PassThru = !PassThru;
    LastCmd = curCmd;
    if( !PassThru )
      // We are now in control
      digitalWrite( PIN_INCONTROL, HIGH );
      Pet.SendCmd( RoboPet::Cmd::Guard );
      // We are no longer in control
      digitalWrite( PIN_INCONTROL,LOW );
      Pet.SendCmd( curCmd );


When the Arduino is not in control, it’s still in control: it’s just passing along all the commands it sees to the robot’s original controller. However, it does not currently pass along the signals used for edge or range detection, so those functions will not work.

Get the software

You can find the current version of the RoboPet library in here.