Instructables

Arduino Animatronic Eyes

FeaturedContest WinnerContest Winner
Picture of Arduino Animatronic Eyes
head.jpg
After reviewing and scouring the internet like most hackers I decided what I wanted wasn't documented well. So I set out to not only do the project for myself but to also try and get some sort of documentation.



For this project you will need:

Electronics side:
1 - Arduino board
1 - Breadboard (anysize)
2 - Servo's I used Futaba S3003

Hardware side:
1 - Set of eyes (ebay, I specifically looked for realistic acrylic doll eyes that had the cornea bump in them). 
1 - Set of RC Car half shafts
8 - EZ connectors*
4 - Servo horns (All of mine came with my servos)
Connecting rod (various sizes and thicknesses)
1 - Sheet of Plexiglass/Acryilic Sheet (I used this as my base. Only because I had it on hand.)
1 - 12" length of Aluminum Angle Bracket 


Assorted Extras:
Aluminium Shims fabricated on the spot from bar aluminum
Screws
Cotter pins
Threaded Rod (or a bolt with head cut off)
Nuts
2 Part Epoxy

Tools:
Drill
Hack Saw
Propane Torch
Pliers
File
Dremel

*NOTE: The EZ connector hole sizes are determined by the thickness of your connecting rod. I was lucky enough to have an RC Hobby store down the road so I purchased what was on clearance  If you buy the wrong size you could always attempt to drill a bigger hole in the EZ connector but it may be more of a pain.

 
Remove these adsRemove these ads by Signing Up

Step 1: Hardware Setup

Picture of Hardware Setup
Unfortunately these eyes were a Halloween rush so I didn't document the build well. I will do my best to explain how I did everything.

For the first step start with a well drawn out plan. Keep it simple.  Servo 1 is for the X-Axis.  Servo 2 is for the Y-Axis (see picture).

"Keep it simple servo" - Christen Gundersen 

Next you will want to start marking out on the plexiglass, or piece of wood, etc where the servos will be and where the eye brackets will be.

Everything starts with a good plan!

My first cheap test using ping pong balls.





Step 2: Cutting and Mounting Eye Brackets

When I made my eye brackets I did all freehand with little planning but I learned quite a few things doing it that I will pass on to you.

NOTE: I did drill three holes to allow for expansion for eyelids.

When finding out where you want to drill your holes for the eyeball rod (see pic). You must take into account to leave room for your nut on the inside of the bracket. If you drill the hole two low you won't be able to install the nut. 

You don't have to cut notches in your brackets on the right side. (I am not sure why I did actually.....) You do need to have notches on the left side of the eyeballs for the control rods to pass by without rubbing. 

To mount the brackets I drilled a small hole through both the aluminum and the plexi, then I used some spare screws to mount them. 

CAUTION: You have to pre-drill plexiglass before you screw into it otherwise you WILL crack it.

Last thing is ensure your eyes are far enough apart that you can fit the servo's behind comfortably. 


Step 3: Mounting servos/horns.

Cut your base to receive the servos. I didn't have much in the way of cutting tools for plexiglass so I used a drill on the four corners and then used a dremel cutting bit to cut the rectangles. You don't want the plexi to melt so take your time and move pretty quickly.

When mounting the servos, servo #2 needs to be shimmed higher. This is for two reasons 1) to keep the servo horn in line with the top of the eyeball and 2) to keep it from interfering with the servo # 1 control rods.

Next you will want to attach the secondary horns to act as dummies to move the second eye. Placement is critical so you don't get a "lazy eye". I mounted them using shims or washers to raise the horn to the servo's level. (see pic) Also the washer that is touching the horn is a nylon(plastic) washer to ease friction.

Step 4: Prepping and mounting Eyeballs

When you receive the eyes they are for dolls so we have to prep them. 

This is a four step process:

1) Take the back half of the eyeball and cut off a half inch ring of the widest part. (see pic two)
2) Glue the ring to the eye using two part epoxy. DO NOT get glue on the front of the eyeball or you will ruin the realistic touch. Use the glue sparingly.
3) Don't touch them until the glue dries.*
4) Drill a hole in the top and left side of eyeball #1 and on the top and left side of eyeball #2. This hole is to receive the cotter pin in step five.

*While the eyeballs cure you will want to get onto the eyeball mounting rod/pivot point.

So I was trying to figure out how I would get the pivot point done during brainstorming and I came across the half shafts at the RC store. What I had to do was cut them down to a more manageable size and find a mounting rod.

The mounting rod is just a bolt I had laying around that I "screwed" into the half shaft and then bolted to the bracket. This was such a tight connection I didn't even have to glue it!

Once your half shaft is on the rod you can epoxy it to the eyeball stub with the two part epoxy. Ensure you let the epoxy fully cure so as not to weaken it.

Lastly, mount the eyeball mounting rod onto the bracket. Take time to ensure the eyeballs are the same distance from the bracket and don't adjust them anymore.

Step 5: Installing Connecting Rods

For my setup, I used some connecting rod/push rod they had at the RC store. Do note these rods come in varying lengths and diameters so be sure you get your EZ connectors to match. 

The great thing about the connecting rods and EZ connectors is that you can adjust it to any length indefinitely because the rod just slips through the EZ connector and the screw on top clamps the rod in place.

Cut your rods to length either using heavy duty pliers or even the hack saw. The important thing is to ensure you have no burrs on the end so it will slip into the EZ connector.

On the end that is going to the eyeball, you will need to devise some sort of hook. For this task, I employed the use of a cotter pin because it was readily available in my garage and because it already had a nice "hook" feature to it. What you need to do is cut one leg of the cotter pin short and solder the longer leg to your connector rod. Once you have it soldered on (and cooled) you can hook it into the holes you drilled in the eyeballs and close it using pliers.

For the last part you need to insert it into the EZ Connector on the horns but do not tighten them down yet. (they should be able to slide on the rods for now)

Step 6: Wire up the servos

Using my breadboard, so I could drive both servos from the Arduino's on board 5VDC, I set up the board as follows:

1) 5VDC(ORANGE WIRE) to breadboard power strip
2) GND(BLUE WIRE) to breadboard power strip (I try to use the same ground on both servos)
3) Digital PIN 8(YELLOW WIRE BOTTOM) to horizontal servos (X-Axis)
4) Digital PIN 9(YELLOW WIRE TOP) to vertical servos (Y-Axis)

That's it! Now on to the software side.

Step 7: Programming

This may be the single most confusing part of the project so I tried to write as much code as I could to ideally minimize the issues you may have.

All files are in the sketchbook.zip.

First here is the code to get your servos centered. The problem you face is getting the servo position correct. Keep in mind these servos go from 0 to 180 degrees.

So in summary we want to set the servos to 90 and 90 so its in the center of the servos "range of motion". Then we can set the Horizontal (X-Axis) and Vertical (Y-Axis) limits. For that you can use the eyes_servo_single_test changing horServo.write(); and vertServo.write();

[eyes_servo_single_test CODE]

 
 
#include <Servo.h>

Servo horServo;
Servo vertServo;

void setup(){
  horServo.attach(8);
  vertServo.attach(9);
}

void loop(){
  horServo.write(80);
  vertServo.write(40);
}

[END CODE]

Next I would use eyes_full_servo_test again plugging in your high and low values for the servos that way you can see if you have any binding. I built in a blinking key so you can visualize what step your on. You can always stop it midway by pulling the USB cord.

[eyes_full_servo_test CODE]

//==================
//This is a quick servo position test I did for my Eye Project
//The servos move from the set postions for the X and Y axis
//Test one sets the LED HIGH 20 seconds, long blink.
//Test two sets the servos at position 40,0 for 6.5 seconds, two blinks.
//Test three sets the servos at position 80,0 for 7.5 seconds, three blinks.
//Test four sets the servos at position 0,70 for 8.5 seconds, four blinks.
//Test five sets the servos at position 0,110 for 9.5 seconds, five blinks.

//NEED TO PRESS RESET ONCE TEST IS COMPLETE

#include <Servo.h> //servo library

Servo horServo; //x-axis servo
Servo vertServo; //y-asxis servo
int led = 13;

void setup(){
  horServo.attach(8); //x-axis servo pin 8
  vertServo.attach(9); //y-axis servo pin 9
  pinMode(led, OUTPUT);
}

void loop(){
  //==================TEST ONE=============//
 
  //Servos in resting or center position. 
  horServo.write(80);
  vertServo.write(40);
 
  //blink once
  digitalWrite(led, HIGH);
  delay(20000);
  digitalWrite(led, LOW);
 
  //============Test Two=================//
 
  //test two blinks twice
 
  horServo.write(20); //x left limit
  vertServo.write(40);
 
  //blink twice
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(5000);
 
  //=================Test Three==================//
 
  //test three blinks three times
 
  horServo.write(80); //x right limit
  vertServo.write(40);
 
  //blink three times
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(5000);
 
 
  //==================Test four==================//
 
  //Test four blinks four times
 
  horServo.write(80);
  vertServo.write(0); //y top limit
 
  //blink four times
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(5000);
 
  //=================Test Five===================//
 
  //Test Five blinks five times
 
  horServo.write(80);
  vertServo.write(110); //y bottom limit
 
  //blinks five times
  digitalWrite(led, HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led, LOW);
  delay(5000);
 
  //=====================END======================//
 
  //Servos back to resting or center. Testing ended hit RESET or wait FOREVER
 
  horServo.write(80);
  vertServo.write(40);  
  digitalWrite(led, HIGH);
  while(1){}
 
 
}

[END CODE]


The code uses PI to move the eyes in a radius. You need to ensure you have your servos on pin 8 and 9 or change it in the code. Once you are confident you have everything set properly you can set the EZ connectors in place.

[eyes_sketch CODE]

#include <math.h>

#define pi    3.14159265358979323846
#define twopi (2*pi)
float circleradius = 50; //50 each side - make no more any of your max limit values
float stepnumber = 360;
float stepangle;


#include <Servo.h> //include servo library for servo control

Servo horServo; //servo for left/right movement
Servo vertServo; //servo for up/down movement

byte randomhor; //define random horizontal position variable
byte randomvert; //define random vertical position variable
int randomdelay; //define random delay variable

#define HLEFTLIMIT 40 //define left limit on horizontal (left/right) servo
#define HRIGHTLIMIT 80 //define right limit on horizontal (left/right) servo

#define VTOPLIMIT 70//define top limit on vertical (up/down) servo
#define VBOTLIMIT 110 //define bottom limit on horizontal (up/down) servo


void setup()
{
  horServo.attach(8); //horizontal servo on pin 8
  vertServo.attach(9); //vertical servo on pin 9
  randomSeed(analogRead(0)); //Create some random values using an unconnected analog pin

  stepangle = twopi/stepnumber;
  for(int i = 0; i<stepnumber; i++){
    float angle = i*stepangle;
    float x = sin(angle)*circleradius;
    float y = cos(angle)*circleradius;

    x = map(x, 1-circleradius, circleradius, 0, 2*circleradius);
    y = map(y, 1-circleradius, circleradius, 0, 2*circleradius);

    horServo.write(x); //write to the horizontal servo
    vertServo.write(y); //write to the horizontal servo

    delay(10);
  }
}


void loop()
{
  randomhor = random(HLEFTLIMIT, HRIGHTLIMIT); //set limits
  randomvert = random(VTOPLIMIT, VBOTLIMIT); //set limits
  randomdelay = random(1000, 4000); //moves every 1 to 4 seconds

  horServo.write(randomhor); //write to the horizontal servo
  vertServo.write(randomvert); //write to the vertical servo
  delay(randomdelay); //delay a random amount of time (within values set above)
}

 
[END CODE]

Step 8: Finishing Touches

Picture of Finishing Touches
fiberglassheadinside.jpg
I chose to also learn how to make a mask AND learn to fiberglass. I won't be going into those steps here but you can find out on other instructables (I did!)

I did a simple fiberglass mask and riveted in some angle brackets to hold the eye in place.

Good Luck everyone! Be sure to leave feedback for version 2.0!
jedimasta2 months ago
Can your explain a bit about how you mounted the dummy horns to the plexiglass to allow for them to rotate freely?
LGProspects (author)  jedimasta2 months ago

jedimasta I used model glue on them on! Really no rhyme or reason just that it was in arms reach. Honestly my thinking was that it (the glue) was made for plastic and since plexiglass was a type of plastic it should work. So far it has held up very nicely, even when I have applied a ton of stress on it.

But if you glued them, how do they rotate? Is there some sort of spacer (glue the spacer to the base, insert horn into spacer)?

LGProspects (author)  jedimasta2 months ago

Ah I see what you mean. The horn is simply held in place with a screw and under the horn (between the horn and plexiglass) is plastic washers.

gotcha. so the washers are glued down, the horn is screwed into the washers and that allows the horn to rotate freely. Makes sense. Thanks for clearing it up.

rstackhouse5 months ago

You have a link to the mask and fiberglass instructors you used?

LGProspects (author)  rstackhouse2 months ago

rstackhouse I don't but I just looked up how to make a cheap/simple paper mache mold and used it to lay the fiberglass into. This worked very crudely but didn't come out very well.

640011 months ago
Good article, oh yes I plan to make a servo that moves in accordance with the lace high tone of voice, can you help me to make it?

thx
thanks a lot and congrats !!, very good work man !!, very instructable really !!
LGProspects (author)  otro laboratorio11 months ago
Thanks!
LGProspects (author)  otro laboratorio11 months ago
Thanks!
kooth11 months ago
Awesome job!
LGProspects (author)  kooth11 months ago
Thanks!
J-Five1 year ago
Like in those old haunted house movies, wait did those eyes just move?????

PERFECT
Foxtrot701 year ago
Excellent Engineering!!! I like the music you chose for the videos. The music gives an eerie quality that makes you think the machines are about to become self-aware. Skynet might be closer than we think.
Great job - love the engineering!
have you considered using an EZB from Z robots to control the movement? Its a really great platform and all of the hard work of programing has been done already. You could easily add a camera for tracking and motion and it has a heap of other great options which would work really well with these eyes.
Here's the link:
http://www.ez-robot.com/
LGProspects (author)  lonesoulsurfer1 year ago
I checked it out. Pretty neat kits they have there but it seems you could save some serious cash by fabricating them yourself! I suppose if I was just starting out I would highly consider using their kits.

I personally enjoy the fabrication and programming parts of these projects. The hardest parts have always been working on these things by myself can be tedious.

True - although at $65 for the board it's not too bad and all the tedious work is taken out.


Keep up the great work.
maewert1 year ago
Beautiful job and very creepy effect! You want the point of rotation to be as close to the center of the eye as possible or the eyes will move the mask as they look left to right.

(An alternate point of view if you are going for 'creepy' is that you want it to be close to human movements *but not too close* so that you hit the bottom of the 'uncanny valley' for maximum creepy effect.)

For more realistic eyes you'll need at least three servos, one for up/down and one for left-right for each eye so it can look cross-eyed if needed.

Would be neat to incorporate a Wii sensor so it can look at you and follow you as you move :-)

Best Wishes
LGProspects (author)  maewert1 year ago
Thanks for the tips on the eye motion. What do you mean by the 'uncanny valley'?

I plan on getting eyelids on next to mimic even more realism.

I just told j1vvy that I plan on attempting to use the Raspberry Pi and OpenCV to track faces and/or movement.
http://en.wikipedia.org/wiki/Uncanny_valley
Thank you so much for posting this! I've been looking for a decent animatronic eyes tutorial for months!
JesusGeek1 year ago
Great ible, but some of the faces were innappropriate for some viewers, could you edit this please?
j1vvy1 year ago
Very well done. Add two motion detectors, one on each side. Quickly move the side when motion detected. Slowly move around when no motion detected. If motion is detected on both then look straight ahead.

Higher tech would be adding a camera and motion tracking.

I was hoping to do just the side to side motion for last Halloween, but ran out of time. I was thinking it should be possible without an Arduino, but not sure how.
LGProspects (author)  j1vvy1 year ago
j1vvy,

Great tip on the motion detectors idea. I have spent countless hours with no success at using Arduino + Processing and OpenCV mainly because I have zero time with Visual Basic and it appears that is a main component with the tutorials I have come across.

My plan is to experiment with the Raspberry Pi for the task of facial/motion tracking.
Great job and neatly set out. Like you, when I wanted to do this, I couldn't find anything that did what I was trying.
For what it's worth, here's how I did it...
http://www.instructables.com/id/Arduino-controlled-animatronic-wooden-head-readin/step8/Controlling-the-eyeballs-inside-the-head-with-the-/

My attempt was not as neatly constructed as yours - great Instructable
LGProspects (author)  rosemarybeetle1 year ago
Rosemarybeetle,

I like how you implemented bicycle cable for servo movement! Your facial structure is pretty neat too. Thanks for the kudos.