Introduction: Pulse Sensor Controlled Tail

Hey everyone!

This Tutorial will go through the Steps of How to create your very own animatronic tail!I've seen many aimatronic tails either controlled by a remote control or set to a continuous sweep code, I decided to make my tail be contrilled by my heart rate!

To get started you will need:

-2 Klixx Balls/Links ( may need more depending on length, seems to have about 50 connector pieces per pack )
-2 Bicycle Brake Cables
-2 or more Boxes of Jumbo Paperclips
-1 Continuous Rotation Servo with "X" Head (* 2 if you want a wider range of motion)
-1Motor Shield
-1 Pulse Sensor
1 Battery 6V 5Ah ( amp hour)
-1 2" Flat-End PVC End Cap (*2 if you want a wider range of motion)
- Hook-up Wire 
-1 Arduino Uno Microcontroller
-Faux Fur 
-Sewing Supplies: needles, thread, pins, exacto knife or utility knife ( will cut out shape without trimming fur) , etc. I highly recommend a sewing machine.
-Pantyhose
-Belt
-Soldering Iron
-Solder
-Exacto Knife
-Dremel or Drill with Drilling Bits
-Needle-nose Pliers
-Wire Strippers
-Wire Cutters
-Gorilla Glue
-Handsaw
-Clamp
-Painter's Tape or Masking Tape

*BEFORE YOU BUY YOUR MATERIALS:

You need to decide before you buy anything if you would just like you tail to have the basic side to side sweeping motion or be able to to do more such as Lift, Tuck, and Wag. For a wider range of  motion you'll need two servo motors, 2 flat 2" PVC caps, and extra Klixx toys.

Also make sure you have plenty of free time to work.

Alright now that you have everything you need let's get started!
:D

Step 1: Constructing the Spine

Basic Anatomy Lesson #1
Tails need a spine to move, So we're going to build one!

1.1
Grab your klixx toy take it out of the package and just take a few minutes to have fun and play with it, see how it moves and listen carefully. As you move your Klixx around you can hear clicking noises. Klixx have tiny little nubs and grooves, you'll have to remove them so start disconnecting the individual pieces, this may be a little difficult to do with your hands so if need be use your Pliers. Once the pieces are all disconnected grab your utility or exacto knife and start shaving off the nubs, this should be really easy to do  the plastic is fairly giving.  

1.2
Once all your pieces are nice and smooth, connect the pieces back together and play with your Klixx some more! you shouldn't hear any more clicking noise and your klixx should move more smoothly as well. Now pull out your Dremel/ Drill or Drill press and Drill bits and a clamp. I would also like to recommend a sharpie and a ruler, once you clamp down your klixx toy making sure the flat end faces up at you mark with your sharpie the middle of each flat piece. You'll want to use your ruler to help keep your marks lined up all the way to the end of your klixx toy, once you've marked the center of each flat piece drill straight down all the way through. Do this with all the connector pieces. 

1.3
Once all your holes have been drilled it's time to make your wire guides! Grab your box of paper clips and unbend them and get them as straight as you possibly can! Afterwards cut your paper clips in half using your wire cutters make sure they are all approximately the same length. Push your cut paper clips through the holes in the klixx you drilled if you have a hard time pushing them through your hole may either be too small or you paper clip isn't straight enough, adjust accordingly. Afterwards using your needle nose pliers create loops at the end of your cut paper clips making sure the loops are all approximately the same size. 

Tip: make sure the Klixx are arranged that the more flexible klixx are closer the the bottom and the less flexible klixxs are closer to the top, this will help with better movement. 

1.4
 Time to grab your two bicycle brake cables, if there are knob pieces at the ends of the cables cut them off using your wire cutters ( this will take some effort so be very careful when doing so, highly recommended that you wear safety glasses) once the knob pieces have been removed wrap the end with some tape to keep the end from fraying. After that guide the wire through the paper clip wire guides on one side, then loop the wire up through the wire guides on the opposite side. Turn the tail over 90 degrees and  Repeat this step with the second brake cable. To test out your spine's movement lay the Tail flat on the ground and  hold the base of the tail in one hand and with the other pull on one of the cables. The tip will be pulled in. Now push that same cable. The tip moves in the opposite direction. if your tail moves smoothly then Awesome! If your tail kinks in some areas locate the problem area and correct it or replace the connector piece.

And with that your spine is done! On to the Next step! 

Step 2: Connecting the Tail Motor

2.1
Now it's time to grab your flat PVC cap.

(if you are making a tail with two servo motor you will have to do steps 2.1 and 2.2 twice) 

Measure 1/2" from the flat closed end and mark it with a pencil or sharpie. Clamp down your PVC cap with it's side facing you and cut along the measured line you made. I used a Hack saw for this but a blade on a Dremel tool should work if not be a bit better and will probably give a cleaner more precise cut. Next Sand down the little shavings hanging off the edge of the PVC cap. and if your cut turned out a bit uneven try to sand the edge down so that it is level. 

Note:
If you for what ever reason had trouble like I did and couldn't find flat PVC caps then instead grab 2" rounded PVC caps and either cut or sand down the rounded part, cut either a piece of plywood or preferably a  piece of plastic about 1/2 inch in thickness about the circumference of the PVC cap you sanded. Once it's attach your round piece to the PVC cap, nails would be stronger but gorilla glue works just as well.

   2.2 
Next you'll want to  measure to find the exact center of the end cap, mark it and drill a hole not to big of a whole though it needs to be just the right size for your mounting screw. The mounting screw is the small screw found in the center of you servo motor. Next you'll need the four sided horn from the servo motor unscrew the "X" shaped horn and put your mounting screw somewhere safe, meanwhile take the horn and lay it on the inside of your cap lining the drilled hole  you made with the center of the horn. Hold the horn in place and mark the four outer holes of the horn, remove the horn and drill where you marked the holes. After that grab some small screws, put your "X" horn back and screw them onto the cap. 

Note: 
If for whatever reason you don't have any tiny screws and you don't have a convenient way of getting some then i recommend  instead grabbing four paper clips and straightening them , Put your "X" horn back  on the cap line it up with the holes, put your paper clips through the hole and bend the ends on either side and snip off the excess. if you're not completely confident with the security of the this grab some hot glue and tack down the paper clip on the outside of the cap not on the servo horn. Re-attach the servo motor and the "X" horn using you mounting screw and give your new cap a couple of turns do you feel it coming in contact with the edge or delaying for any reason? Good!
If you do that's ok just fix/ adjust the problem and re-test it again. 

Once everything is moving smoothly unscrew the horn again and put your mounting screw somewhere safe and we'll go on to the next step.

2.3
In the next step you have to do some soldering! Yay finally!

so plug in your soldering iron and grab some solder, while your waiting for it to heat up grab more paper clips and straighten them out you'll need enough straightened paperclips to create a box around your servo motor, you'll also need a couple of paper clips to create a connector between the box of your servo motor and the base of your tail spine. 

Note: If you're doing the double servo motors you have to solder together two boxes for each servo and then attach them together by aligning them and rotating them 90 degrees. For example if the top motor is facing front ways towards you than the bottom motor would be facing to the side. You want to solder the boxes together until they are really sturdy and aren't going to wiggle around while the tail is moving. 

When creating a connector between your tail and your Servo motor housing box make sure there is a decent bit of space between the two so they don't interfere with each other. using about four fully straightened paper clips solder one end to the box you created for the servo motor and twist the other end around the first wire guide that you see at the base. Do this for all four you can also add more for good measure and i soldered the twisted parts as well. 

2.4 
Now pick up your cap again and drill two holes somewhat close together on the edge, this is going to be where you attach your brake cables. Grab both end of one cable and  guide them up and around your cap and push them through the holes, then take your pliers and bend the cable so it hooks and doesn't slide out of the hole as easily. You can bend a small paperclip and push it into the hole with the brake cable to keep it from moving but I also find a little glue will help keep it in place as well, just make sure to put it on top and the cable and to not let it drip inside the hole too much. 

Turn the Pulleys to see if the tail moves the way you want, if it does great! If not that's ok just add more wire guides to your structure. 

2.5 
This next step is for creating a belt loop out of paper clips. So once again grab some paperclips and straighten them out, bend some of your paperclips into a half square shape, place them vertically and solder the ends to the box around your servo motor. Grab more paper clips and form another half square, hold them horizontally cross it over the others you already tacked down and solder where they cross. leave enough of a gap between the horizontal paperclips for the loops to slide through.

 Awesome! We're most of the way through!
On to the next step!

Step 3: Pulse Sensor and Code

3.1
The Pulse sensor can be purchased from SparkFun for $24.95, sparkfun also provides the code you will need to work with for free!

So grab your Arduino, Arduino USB plug, Pulse sensor, Motor shield and get to a computer!
(even though more than likely you're already at a computer if you're reading this lol )

Go ahead and slide your Motor Shield on top of your Arduino and plug in it into your computer, once the Arduino program is open you can plug in your pulse sensor ( purple wire to A0, red to 5V or 3V, and black to GRD) and I developed this code combining the pulse sensor code and the basic sweep code

What should happen is at as certain heart rate is lower than 66 bpm it will move at a standard rate if your heart rate is higher than 66 bpm then it will move faster :

 #include <Servo.h>



Servo myservo;  // create servo object to control a servo

                // a maximum of eight servo objects can be created


int pinNineInput = 9;


int pulsePin = 0;                 // Pulse Sensor purple wire connected to analog pin 0

int blinkPin = 13;                // pin to blink led at each beat

int fadePin = 5;                  // pin to do fancy classy fading blink at each beat

int fadeRate = 0;                 // used to fade LED on with PWM on fadePin


// these variables are volatile because they are used during the interrupt service routine!

volatile int BPM;                   // used to hold the pulse rate

volatile int Signal;                // holds the incoming raw data

volatile int IBI = 600;             // holds the time between beats, the Inter-Beat Interval

volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low

volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

int pos = BPM;



void setup()

{

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

   pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!

  pinMode(fadePin,OUTPUT);          // pin that will fade to your heartbeat!

  Serial.begin(115200);             // we agree to talk fast!

  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS

   // UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,

   // AND APPLY THAT VOLTAGE TO THE A-REF PIN

   //analogReference(EXTERNAL);



}

void loop()

  {

if (pinNineInput < 66)

{

  for(pos = 0; pos < 360; pos += 2)  // goes from 0 degrees to 360 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(5);                       // waits 5ms for the servo to reach the position

  }

  for(pos = 360; pos>=1; pos-=2)     // goes from 360 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(5);                       // waits 5ms for the servo to reach the position

  }

    for(pos = 0; pos < 360; pos += 1)  // goes from 0 degrees to 360 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(15);                       // waits 15ms for the servo to reach the position

  }

  for(pos = 360; pos>=1; pos-=1)     // goes from 360 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(15);                       // waits 15ms for the servo to reach the position

  }

    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

}

else if (pinNineInput >= 66)

{

  {

  for(pos = 0; pos < 360; pos += 2)  // goes from 0 degrees to 360 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(5);                       // waits 5ms for the servo to reach the position

  }

  for(pos = 360; pos>=1; pos-=2)     // goes from 360 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(5);                       // waits 5ms for the servo to reach the position

  }

    for(pos = 0; pos < 360; pos += 1)  // goes from 0 degrees to 360 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(4);                       // waits 4ms for the servo to reach the position

  }

  for(pos = 360; pos>=1; pos-=1)     // goes from 360 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(4);                       // waits 4ms for the servo to reach the position

  }

    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(3);                       // waits 3ms for the servo to reach the position

  }

}

}

else

{

  for(pos = 0; pos < 360; pos += 2)  // goes from 0 degrees to 360 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(10);                       // waits 10ms for the servo to reach the position

  }

  for(pos = 360; pos>=1; pos-=2)     // goes from 360 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(10);                       // waits 10ms for the servo to reach the position

  }

    for(pos = 0; pos < 360; pos += 1)  // goes from 0 degrees to 360 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(15);                       // waits 15ms for the servo to reach the position

  }

  for(pos = 360; pos>=1; pos-=1)     // goes from 360 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(15);                       // waits 15ms for the servo to reach the position

  }

    for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(7);                       // waits 7ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(7);                       // waits 7ms for the servo to reach the position

  }

     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(7);                       // waits 7ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(7);                       // waits 7ms for the servo to reach the position

  }

     for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees

  {                                  // in steps of 1 degree

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(7);                       // waits 7ms for the servo to reach the position

  }

  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees

  {                               

    myservo.write(pos);              // tell servo to go to position in variable 'pos'

    delay(7);                       // waits 7ms for the servo to reach the position

  }



  Serial.print(BPM);

Serial.print("\t");



//  sendDataToProcessing('S', Signal);     // send Processing the raw Pulse Sensor data

//  if (QS == true){                       // Quantified Self flag is true when arduino finds a heartbeat

//        fadeRate = 255;                  // Set 'fadeRate' Variable to 255 to fade LED with pulse

//        sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix

//        sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix

//        QS = false;                      // reset the Quantified Self flag for next time   

//     }



  ledFadeToBeat();

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  myservo.write(pos);

  delay(3000);                             //  take a break


}

void ledFadeToBeat(){

    fadeRate -= 15;                         //  set LED fade value

    fadeRate = constrain(fadeRate,0,255);   //  keep LED fade value from going into negative numbers!

    analogWrite(fadePin,fadeRate);          //  fade LED

  }


//void sendDataToProcessing(char symbol, int data ){

//    Serial.print(symbol);                // symbol prefix tells Processing what type of data is coming

//    Serial.println(data);                // the data to send culminating in a carriage return

//  }


Once the code is uploaded test it by plugging your tail to the part of the motor shield that says Servo2.

Note:
This code was only developed for one servo motor, for those who want to control two servo motors you will have to adjust this code. I will also be working on it to account for two servo motors but if someone beats me to it and develops a code of their own please don't forget to share! :D

The original Pulse Sensor code can be found here:
SparkFun




Step 4: Fur and Finish

4.1
Alright now that you have a spine and motorized muscles to move it, it's time for a small layer of skin then fur!

By Skin I mean grab some pantyhose (skin colored if you like) and we are going to pull and attach that over the tail to help the spine not get caught on the fur. Make sure the pantyhose isn't too tight that it hinders the movement of the servo.  

4.2 
Now pull out your sewing stuff and your faux fur, lay out the fur and make sure the direction of the fur is going  downward, towards you. With a marking tool draw out the shape of your tail on the back of the fur, make sure the length is the same if not a little longer than your tail spine and mirror that shape right next to the first one making sure they touch in the center.
Using an exacto or utility knife cut out your shape.

Note:
DON'T USE SCISSORS to cut out your tail shape, you'll just end up trimming the fur, it'll get everywhere and it wont look as natural. 

Once the shape is cut out the two sides should still be attached to each other where they touched in the center, fold the piece so the fur sides are touching and pin them together along the outer edge, Then just sew!
Flip the tail inside out and guide your pantyhose covered tail spine inside. How you close up the tail depends on where your belt loop is and you also want to make sure your servo wire is hanging out side the fur so that you can still plug it in to your Arduino. 

To power your tail you'll need a 6V 5Ah ( or higher) battery they're they're not very small and are a bit heavy so i would recommend carrying it in a fanny pack or a mini back pack anyway to carry it and it still connect to the Arduino.

And with that we are Finished!

Last Note:
Your pulse sensor wire should be long enough to connect to your wrist or the inside of your elbow.


Happy Wagging!
:3

http://youtu.be/gBVELgoaf7g


Helpful Links:
http://www.wolftronix.com/

Theatre glasses:

http://www.youtube.com/watch?v=H8nE_sYLmOk


http://aisencaro.com/projects.html#Safety%20Glasses

animatronic tail:

http://www.youtube.com/watch?v=d1k9p1P4s8I


http://www.thingiverse.com/thing:13522


instructables:


https://www.instructables.com/id/Arduino-Controlled-Wolf-Tail/