R2-D2 Laser Robot for Cats

This is an expanded modification for the Laser ToyBot for Cats to fit into an R2-D2 toy. The entire project can be built with significantly less work without using the R2-D2, but the astromech droid had a lot more flair. First: How to make it work from scratch:

The first revision was just an Ardweeny on a proto board with some hot-glue attaching the continuous rotation servo horn to a project box. It spins in horizontal circles, randomly changing directions while also randomly changing vertical angle. The vertical servo must be "tuned" so it is consistently pointing toward the ground unless you enjoy having your cats climb the walls. 

Simple parts:

  1. Ardweeny (Maker Shed)
  2. Adafruit 1/2 Size Perma-Proto Board (adafruit)
  3. Micro Servo and perhaps some 10uF capacitors to clean up the noise (adafruit)
  4. Sparkfun TTL Laser and 10k resistor (Sparkfun) 
  5. Continuous Rotation Servo (adafruit)
  6. 3xAAA battery holder (adafruit)

Advanced/Optional parts:

  1. RobotShop pan kit for either Futaba or Hitec servos. I went with the Hitec version and modified a Hitec HS-422 servo for continuous rotation. Futaba continuous rotation servos are more widely available without modification, but the Futaba pan kit is more expensive. The servo I linked above is a Futaba servo.
  2. R2-D2 model. I used a Diamond Select bank I found on Amazon but can't find it anymore.
  3. Shape Lock molding plastic. (Maker Shed)
  4. On-Off button and LED. This beauty from adafruit does both

Simple assembly:

In my non-Droid version, I simply sandwiched the servos between the proto board and the battery holder then used hot glue to affix the continuous rotation servo to a project enclosure. It worked fine, but was not sturdy. The switch to the Perma-Proto board was ideal as shown here:

Pin assignment:

  • Vertical (standard) servo: 10
  • Horizontal (continuous rotation) servo: 9
  • Laser diode: 8  (The diode is TTL controlled and uses a 10k resistor to ground)
  • Power LED: 7

That's all that is needed to get a basic laser toy running. Fitting it into the R2-D2 robot was a bit more challenging. I needed to find a way to allow the entire R2-D2 head to spin freely without tangling wires and I didn't have a slip ring (but adafruit does now) so I decided to make the entire electronic device rotate. Finding the DDP155 Pan System from RobotShop and mounting it upside down solved that for me. I screwed in a few risers to the rotating plate to lift it higher into the droid model. 


When working with ShapeLock, be aware that the hot plastic will bond to other plastics. To get a very close form, insulate other plastic areas with aluminum foil until the cooling completes. ShapeLock can be cut with a Dremel rotary tool with a plastic or wood cutting bit at 5-8k RPM. Going over 10k causes the plastic to melt. USE SAFETY GLASSES when using a rotary tool. Little bits of white plastic in the eye are not fun.

The most difficult part of the R2-D2 enclosure was the centering and balancing of the head on the RobotShop pan kit. This took several tries. Thankfully ShapeLock can simply be melted down and re-molded. 

That's it for the construction. The rest is just source code. Enjoy!


/* Arduino laser cat toy
 2012 Daniel Gentleman
 Creative Commons Attribution license
 Laser diode attached to a standard servo for vertical movement
 Continuous rotation servo for horizontal spinning
 Power LED (optional) 
#include <Servo.h> 
Servo myservoh;  // Horizontal servo - continuous rotation
Servo myservov; // Vertical servo - standard 
unsigned int duration = 0;
int lasttime1 = 0;
int lasttime2 = 0;
int randstart = 0;
int randend = 0;
int pos = 0;
int laser = 8; // TTL laser diode on pin 8
int vpos = 80; 
int powerLed = 7; // Power LED on pin 7
void setup()
  myservoh.attach(9); // Continuous rotation servo on pin 9
  myservov.attach(10); // Standard servo on pin 8
  pinMode(laser, OUTPUT);
  pinMode(powerLed, OUTPUT);
  digitalWrite(laser, LOW);  // Turn ON the laser 
  digitalWrite(powerLed, HIGH); // Turn ON the power LED
void loop()
  int vaxis = random(50,120); // Range of vertical movement (50-120 here)
  lasttime1 = millis();
  randstart =  random(200, 19990); // Tune these for your preferred random behavior
  randend =  random(2000, 2400);
  while(pos <= randend) // Random horizontal spinning 
    pos += 1;
  vaxis = random(70,100);
  myservov.write(vaxis); // Random vertical movement
  duration = millis() - lasttime1;
  lasttime2 = millis();
  while(pos >= randstart)
  vaxis = random(70,100);
  duration = millis() - lasttime2;
  duration = millis() - lasttime1;