Introduction: Animatronic Talking Christmas Tree - Part 1

About: Dad, maker, dreamer, hacker, painter.
In this Instrutable I will show you how to turn a regular cheap decorative artificial Christmas Tree into an awesome animatronic robot platform for the geek in the family.

In the second installment, I will show you how you can incorporate speech recognition.

It looks inconspicuously like a regular little Christmas tree, but then magically comes to life as a fun lovable talking robot!


Some things you might learn
  • How to animate just about anything with some imagination, an Arduino and some servos
  • How to control a servo with Arduino without using the servo library
  • Get your robot to receive serial commands
  • How to use Processing to send serial commands to your robot
  • Use the ttslib(text to speech) library in Processing to give your robot a voice

Step 1: Gather Stuff


To make something similiar to this tree you will need a bunch of stuff and tools, and more importantly, a healthy dose of creativity and imagination.

Here is a list of the materials I used.
  • A small wireframe artificial tree - I got mine at the dollar store
  • x-mas tree covered wire - like the branches of the tree, also found at the dollar store
  • x-mas tree garland - also found in most dollar stores
  • a scrap of wood
  • a scrap of something thin and flat. card, wood, I used polysyrene
  • some craft paints
  • some styrofoam balls
  • craft foam sheet, white, small piece
  • garden wire, the kind that is coated in dark green plastic - dollar store
  • short piece of 1/4 inch copper piping, less than two inches - any small strong tube will do, a pen body even.
  • two servo motors
  • an Arduino (or a clone, I am using an RBBB)
  • a breadboard
  • hookup wire
  • two sets of Lynxmotion ball joints and threaded rod to match
  • A set of cheap battery operated Christmas lights
  • some male - male headers and some regular male headers
  • some Christmas decorations of a suitable scale for your tree.
Tools:
  • Hot glue gun
  • drill
  • hand  saw
  • x-acto knife
  • needle nose pliers
  • black marker
  • small philips screwdriver
  • pipe cutter

Step 2: Prep the Tree

We will start by getting our tree into rough shape for hacking on some servo-motors.

Begin by flattening out one side tree, this has the added benefit of making the viewed side of the robot bushier. Simply bend the wire branches to conform to the shape you like.

Take a rough measure of the height of the tree and cut a piece of lumber short enough and narrow enough to be concealed, but at same time, is thick enough to support some servo motors.

When you are happy with your brace, drill several sets of holes down it's length.

Make some little 'U' shapes out of garden wire. Put these around the trunk of the tree and  through the holes of your lumber brace. Then twist up the ends with some needle nose pliers to secure the brace to the tree. 

Last, bend some of the lower branches down out of way, and make a sort of indentation or cave up near the top of the tree. This is hard to describe and also to get pictures of because it is all just green tree. The idea is to give yourself enough room to create a set of eyes and a mouth.

Step 3: Make the Jaw

Begin by cutting out a half circle shape that is smaller than the radius of your tree from something flat and stiff. I am using polystyrene here, but use whatever you have.

Cut out a small nothch on the flat side to accomidate the trunk of the tree. Then drill two tiny holes on either side near the outer edge of the circle.

Next we will hide the outer edge of the plastic by glueing some strips of the wire wrap foliage around the mouth.
On which ever side that you view as the bottom, use the garland and some more strips of wire wrap to disguise it and make it look like the tree.

Leave some room to access your holes near the back. As it is buried deep in the foliage it won't show.

Cover the top side in black craft paint, and once that has dried, you can embelish it with a tongue as well. If you don't have the confidence to paint a tongue, you could make one out of paper and glue it in.

Step 4: Make the Jaw Hinge

First you will need to position your jaw and move some branches until you can manually hold the jaw in place and move it up and down.

Once you are satisfied that you have ample room, take a rough measure with your fingers to see how long of a hinge you will need.

Cut a small section of copper tube that is the same width as your tree brace. pass a piece of garden wire through your tube and bend it so that it forms a 'U' shape and lines up with the holes in your jaw when it is in position. The arms of the 'U' need to be long enough to pass around the tree's trunk, but to long will lead to sloppy motion.

Bend a little upwards hook in the end of each of the arms of the 'U' and hook theses through the holes on your jaw. Tighten the connection by bending the hooks a little further.

Secure the tube in place to the back of the tree, you can use some hot glue. I lucked out and it lined up perfectly with one of the wire twists that support the brace, so I used the tail ends of wire and curled them upwards to hold mine.

Now you should be able to move your jaw up and down nicely and the hinge should hold it in position. If is catching, check that there are no branches from the jaw or the tree obstructing it.

Step 5: Make the Brow

We will be using a similar technique for the brow as we used to make the jaw. The brow is intended to conceal the eyes when the robot is not animating, so the shape is more like sunglasses. There needs to be enough room behind them for the eyes to tuck away.
The hinge for this assembly is the assembly itself with two bent branches on the tree.

Start by cutting out a shape something like what I have done. You will need to work with your tree for this, so it is pointless to give measurements. I felt mine out, and have confidence that you can too.

As we did before embellish it with greenery. On the top side we want to just desguise the armature, but on the bottom we want some 'lashes' use the thicker garland to give your tree a good bushy brow. Trees have bushy brows.

You won't be able to hinge this one until we attach it to a servo, but you can manipulate it by hand to see where you are headed.

Step 6: Mount the Servos

Start by putting the armature hub on both of the servos. Attach it at full extension, and then attach a ball joint to each armature. The holes on the servo armature are too tiny to accept the ball joint. Use one of the servo screws to widen the hole a bit. Just screw it in a little and then take it out. Hole widened! If you don't go too far, your ball joint will thread right on without even requireing the nut.

Hold the servo in position on the brace and make two marks. Predrill the holes and then screw the servo into place.

Make an armature for the jaw by measuring with your fingers from the servo in the downward position(with the armature pointing down) to about two thirds of the way to the front of the jaw when it is closed. Cut a piece of threaded rod to match and then attatch a shoulder cup from the ball joint set to each end.

Attach a ball joint to the underside of the front of the jaw by punching a small hole, passing it through, and using the nut to secure it.

Test the motion by manually moving the servo to see how your tree reacts.

Mount the brow servo in the same manner. Except that this time the armature will be much shorter, as we are attatching it to the rear of the assembly.

Once the brow is connected you will need to prop the assembly on two of the wire branches from the tree to creat the pivot point. It is light enough that the branches support it fine with some strategic bends. You will need to fiddle with it a little bit, but once you have it right, you should be able to manually move the servo and have the brow raise and lower.

Step 7: Add the Eyes and Teeth

To make the cartoon eyes, we will use a styrofoam ball. We want our tree to have character and the soul is in the eyes.

Cut the ball in half and then cut off about a fifth from each half.

Use a very light coating of plastic cement and quickly bring the two cut edges together. Press and hold for about thirty seconds.

Now just use a black marker to give your eyes some pupils.

Raise the brow of your tree by moving the servo manually, and hot glue the eyes to the underside of the brow. They need to be positioned back a little and on a bit of an angle with the top more forward than the bottom. This is so they dissapear more when the brow folds down. Check the pictures to get a better idea.

I cut the teeth out from a little bit of craft foam sheet. You could use paper or cardboard as well. Move the jaw around a little until your imagination says 'there!' and then glue the teeth in.

Step 8: Wire the Servos to Arduino

Start out by putting wiring your power buses to the 5V and ground pins on your Arduino.

We will be using the power from our USB port, so we won't need to build a power supply. The voltage is stable for enough to power two little servos and the Arduino.

Then run a wire out to an empty area of the board from Arduino digital pins 8 and 9.

Put a jumper from 5V to the hole beside each, and then run a jumper to ground beside those.

Use a male to male headers to make an easy connection points for your servos.

Step 9: Determine Range of Movement

Now we need to determine our range of movement for our servos. At the same time I will show you some quick code that will operate a servo without using the servo library.

Servo Basics

 In order to move, a servo is waiting for a pulse. We can generate that pulse by turn a digital pin on and off quickly with the correct delay.

Specifically, a servo is waiting for an on pulse in the range of 500-2500 microseconds with an off period of 20 milliseconds between. 

Luckily, Arduino makes this really easy to do.

Type the following code into your Arduino environment, and we will use this quick sketch to figure out our maximum and minimum values for animating our tree.(or you could cut and paste from the included text file)


int servoPin = 8;    //this is the pin where the servo will be connected, change for any digital pin
int servoPos = 2500;  //this value will be to set the servo position
                     //values range from 500 to 2500, and represent from 0 - 180 degrees.
                     //is actually time in micro-seconds to determine pulse size for the servo

void setup(){
  //define the pin as an output
  pinMode(servoPin,OUTPUT);


void loop(){
  //in this case we are using a for loop to ensure that we hit the position that we want to reach with the servo quickly
  //one pulse will move the servo only a little ways towards it's final destination, so we are doing 20 pulses in a row

for(int i=0;i<20;i++){
  digitalWrite(servoPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(servoPos);  //delay for the pulse length set in declarations
  digitalWrite(servoPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);                   //you need to wait 15 - 20 milli-seconds between pulses, no more, no less.

}

This code just loops through setting the postition of the servo. In order to figure out your values, plug in different values for servoPos in the range of 500 - 2500. 

Try a value, upload it. Try another, upload it. A tedious route, but it ensures that you find an optimally pleasing motion. Also I wanted to show you a quick and dirty servo control method.

When you find a good value for each extreme, take a note, something like; Mouth open = 1100, Mouth closed = 500.

Do this for both of your servos, and we can move along to something a bit more interesting.

Step 10: String the Lights

The lights are pretty simple. We waited until now so that we are familiar with the movement of the robot and do not obstruct it with our string of lights.

Take your battery powered strand of lights and cut the battery compartment off. (Mark one of the wire so you know which is which)

Strip the two ends and solder them to some breadboard friendly male headers.

Wire the positive wire to Arduino pin 13, and the negative out to ground. 

That is all. Now we can control the lights from digital pin 13. 

Now that you know your robots moving bits well, you can go ahead and string the lights up. You do not want to obstruct the function of your talking tree, so watch where you hang them. I forgot to take a picture with just the lights, but you can see what it looked like in the video in the next step.

Step 11: Program the Arduino

Now that you understand how I am operating the servos, let's write some more useful code for it.

We will start by defining a bunch of functions using the values that we recorded in the last step that will animate the tree, and also add serial communication capability and program some actions to go along with data that is received from the serial port.

Open up a new sketch in the Arduino environment and enter the following. (remember that you will need to use your own values for the servo positions)
int ledPin = 13;    //assign pin 13 as the pin that the lights are on
int mouthPin = 8;    //this is the pin where the mouth is connected
int eyesPin = 9;    //eyes are on pin 9

//for serial communication
int message = 0;

void setup(){
  Serial.begin(9600);   //start the serial port with a baud rate of 9600
  //define the outputs
  pinMode(ledPin,OUTPUT);
  pinMode(mouthPin,OUTPUT);
  pinMode(eyesPin,OUTPUT);
  //close the eyes
  closeEyes();
  //close mouth
  closeMouth();
  //wait a few seconds so we can witness the opening after hitting reset
  delay(3000);


void loop(){
//digitalWrite(ledPin,HIGH);
//openEyes();
//talk(3);
if(Serial.available()>0){  //if the serial port is sending data
    //read the incoming byte
    message = Serial.read();
  //animate our robot according to the serial data that we recieve
    if(message == '1'){
      talk(1);
    }
    if(message == '2'){
      talk(2);
    }
    if(message == '3'){
      openEyes();
    }
    if(message == '4'){
      closeEyes();
    }
    if(message == '5'){
      blinkEyes();
    }
    if(message == '6'){ 
      digitalWrite(ledPin,LOW);
    }
    if(message == '7'){ 
      digitalWrite(ledPin,HIGH);
    }
  }
}

void talk(int times){
  for(int j = 0;j < times;j++){
  //first we open the mouth
for(int i = 0;i <10;i++){
  digitalWrite(mouthPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(1100);  //delay for the pulse length set in declarations
  digitalWrite(mouthPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}
   //then close it
for(int i = 0;i <10;i++){
  digitalWrite(mouthPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(500);  //delay for the pulse length set in declarations
  digitalWrite(mouthPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}
}
}

void closeMouth(){
   for(int i = 0;i <10;i++){
  digitalWrite(mouthPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(500);  //delay for the pulse length set in declarations
  digitalWrite(mouthPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}
}

void openEyes(){
   for(int i = 0;i <30;i++){
  digitalWrite(eyesPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(800);  //delay for the pulse length set in declarations
  digitalWrite(eyesPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}

}

void closeEyes(){
   for(int i = 0;i <30;i++){
  digitalWrite(eyesPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(2500);  //delay for the pulse length set in declarations
  digitalWrite(eyesPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}
}

void blinkEyes(){
  for(int i = 0;i <10;i++){
  digitalWrite(eyesPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(2500);  //delay for the pulse length set in declarations
  digitalWrite(eyesPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}
  for(int i = 0;i <10;i++){
  digitalWrite(eyesPin,HIGH);  //turn on the servo pin, i.e send 5V
  delayMicroseconds(800);  //delay for the pulse length set in declarations
  digitalWrite(eyesPin,LOW);  //turn servo pin back off to end the pulse
  delay(20);
}
}

Here is a video of what it should do at this point.


Step 12: Add Some Christmas 'Bling'

Finally we can 'Bling' out our christmas tree. This will disquise him even further and gives him even more Christmas appeal.

Go nuts, but don't obstruct any of the moving parts. I think mine turned out pretty swell. I ran some code to make his parts move once in a while to check that everything was still moving smoothly.

I hung the decorations in the traditional manner, just as I would have on any Christmas tree. I hot glued the star on top.

Step 13: Write a Processing Sketch

Now that we have an awesome eye opening, jaw flapping robot tree, we need him to do something for us. Otherwise he is not much of a robot at all.

It is beyond the scope of this Instructable to show you everything that you could do with this style of robot, but I will show you how to send some serial data to your tree to animate it and get you started in making your robot talk.

We will be using a couple of different libraries for this sketch, the serial library and ttslib.

The Serial library comes with Processing, but you will have to download and install ttslib. you can get it here.

ttslib is a text to speech library and using it will allow us to give our robot a voice.

Download the file and simply unzip it into your libraries folder in your sketchbook. Once that is done, Open Processing and you should be able to see ttslib if you click on Sketch - Import Library on the menu. If you cannot see it there then go back and try again. (Close Processing between attempts)

Let' get started. Open a new sketch in Processing, and type in the following code.(Or you can download the text file and copy and paste it into a new sketch)

//import the two libraries
import guru.ttslib.*;
import processing.serial.*;
//give our instances names
Serial treePort;
TTS tts;

//a default message
String message = "Ho Ho Ho";
String articulation = "111546";

void setup() {
  //start our port and also tts
  treePort = new Serial(this,Serial.list()[0],9600);
  tts = new TTS();
  //the following settings control the voice sound
  tts.setPitch( 200 );
  tts.setPitchRange( 20 );
  tts.setPitchShift( -10.5 );

}

void draw() {
  //this just blinks the lights to make it look like a regular tree
  treePort.write("7");
  delay(1000);
  treePort.write("6");
  delay(1000);
}

void mousePressed() {
  //open the robots eyes and stop blinking, lights on if they were off
  treePort.write("73");
  delay(900);  //delay to allow eyes to open
  treePort.write(articulation);  //write the current articulation to the port, i.e. send commands
  tts.speak(message);  //speak the message string

}

void keyPressed(){
  //the following changes the message and the articulation when we press the number keys
if(key=='1'){
   articulation = "111546";
   message = "Ho Ho Ho";
}
if(key=='2'){
   articulation = "225546";
  message = "Merry Christmas!!";
}
if(key=='3'){
   articulation = "1112546";
  message = "Have you been naughty";
}
if(key=='4'){
   articulation = "225546";
  message = "Bah humbug!";
}
if(key=='5'){
   articulation = "2246";
  message = "What do you want?";
}
if(key=='6'){
   articulation = "26157262756373564";
  message = "I wanna wish you! a Merrrrrry Christmas!";
}
if(key=='7'){
   articulation = "215363736373546";
  message = "Jingle Bells!";
}

}

Go ahead and run the sketch. You will notice that we get an error message concerning the mbrola voices not being installed, don`t worry about that, we will look at fixing that in the next step. 

For now you can run this sketch and hear your computer talk while your tree animates.

Just click the window to have him say something, pressing the numbers 1-7 will change the message and the articulation commands that we are sending to our robot.

If you have done things right, your robot should perform something like in the video.








Step 14: Install the Mbrola Voices

Now that we have our robot tree saying a few Christmas expressions, we can start to tweek his voice so that he does not sound so robotic.

This next part is not strickly neccessary, and requires a little bit more work, but I feel is well worth the effort. the mbrola voices sound more natural, still robotic, but more natural

First you will need to download two files. The mbrola binary files which you can get through the link. If you are using windows, download the windows file, then download the dos binary as well.

Run the MbrolaTools35.exe file to install it to your system. Then you will need to unzip the dos file, mbr301d.zip, and place the file named mbrola.exe into the folder where you installed MbrolaTools.

One last thing that you need to do is to download the three voices, us1, us2, us3. Apparently these are the only ones that will work, I have tried a few others without any luck. You can find them on the same page near the bottom.

Now all you need to do is change your setup function to look like this

void setup() {
  treePort = new Serial(this,Serial.list()[0],9600);
  System.setProperty("mbrola.base","C:/Program Files (x86)/Mbrola Tools");  // you will need to make sure that the path matches yours
  tts = new TTS("mbrola_us3");

}

Now run the sketch again, and it will sound more like this.



Step 15: Going Further

I think that I have given you enough to keep you busy for a little while, but I thought I would take a little moment of your time to give you a couple of ideas on how to make this even more interesting.

Once you have gotten this far, it is very simple to make your robot read your e-mail, or a news feed, or a twitter feed.

With a little bit of ingenuity you can do much more interesting interactions. For instance you can learn about another library, VOCE, and make a robot that can hear you as well as talk to you. VOCE is a speech recognition library, and is pretty easy to get working with Processing also. Maybe I will write up an Instructable for the VOCE library soon.

Join me in the second installment, where i will show you how to do it. Animatronic Talking Tree - Part 2 - Speech Recognition

If you want to see a little video of a robot skull that tells a variety of interactive jokes (knock knock jokes, question and answers type.) and is an all round decent conversationalist, have a look at Larry (one of my Halloween projects that I did not write a proper 'ible for)

I really hope that you have enjoyed this Instructable and go off and build a tree for your favorite geek or maybe to scare office mates. If not I hope that i have given you some decent information that you can work into a project of your own.

Merry Christmas everyone! (or any other holiday that you might be celebrating....or just the fact that you are reading this, which is, lets face it, better than the alternative)


Share and enjoy!


Arduino Challenge

Participated in the
Arduino Challenge

Make It Glow Challenge

Participated in the
Make It Glow Challenge

ShopBot Challenge

Participated in the
ShopBot Challenge

The Mad Science Fair

Participated in the
The Mad Science Fair

Holiday Gifts Challenge

Participated in the
Holiday Gifts Challenge