Animatronic Hocus Pocus Spellbook Prop
by ImagineersApprentice in Circuits > Arduino
18017 Views, 241 Favorites, 0 Comments
Animatronic Hocus Pocus Spellbook Prop
This is my first Instructables, and a bit of an after thought. I'll do my best to document the process I took to create the book from Hocus Pocus and add more pictures. The biggest thing to remember while reading through this is that everything will need to be adjusted to fit depending on your set up.
With that disclaimer out of the way, I'll do my best to keep up with any questions you might have!
Materials
Guts
- Arduino Board (I used the Arduino Uno)
- Jumper Cables
- 4 AA Battery Power Pack
- 9 volt battery
- (4) Micro Servos
- Cardboard
- Hot Glue
- Fake Eye
- (2) Micro Clevis Pin sets (you'll need 4 in total (I got these at my local RC Hobby Shop))
- Ball links
- 12 gauge aluminum jewelry wire
- Hole punch pliers
- Dremel1/32" drill bit
- Staples
- Solder
- Soldering Iron
Book
- Magnetic Book Box
- Silver Clay
- Jewel
- Black Acrylic Paint
- Brown Packaging Paper
- Glucose
- Water
- Spray Bottle
- Wood Stain
- Mod Podge Matte
- Twine
- Needle
- Paintbrushes
- Hinge
- Velcro
Print Parts
I couldn't find any parts that would work for what I needed, so I ended up designing and printing parts
Eye Half - https://tinkercad.com/things/1Z48GWRMc21-eyeball-e...
Universal Joint - http://www.thingiverse.com/thing:172505/#files (This is a large universal joint, you'll need to scale it down quite a bit for it to fit)
Eyestand - https://tinkercad.com/things/5Z6XbSPlSjC-eye-stand
Eyelid Stand - https://tinkercad.com/things/euQ47HamzQ9-eyelid-st...
Servo stands - https://tinkercad.com/things/iaCfsbxVNpX-servo
I used straightened staples and hot glue to assemble the universal joint. Use the small Dremel bit to clean up any holes.
Assemble the Eye
Using the small drill bit, drill a hole near the edge of the printed eye half. Drill a second hole 90 degrees from the first hole (imagine the first hole is 12 o clock, the second hole would be at 3 o clock). This is your x and y axis.
Screw two of the ball joints in to the two holes you just drilled. I ended up using a bit of thread lock to keep them on, but you could use some hot glue too.
Hot glue the eye half, universal joint, and eye stand together.
Install the Eye
First you'll need to measure how far towards the spine of the book the eye needs to be. The blink and tilt mechanism will be flat against the side of the book (farthest from the spine). Glue the eye stand down with one ball link parallel to the length of the book facing the top of the book, and one parallel to the width of the book facing the inside of the book.
Next you'll want to cut out a hole in the cover. For now, cut the hole just large enough for the eye to fit through. You'll need to make it bigger once you install the eyelids, but it's easier to take pieces out than to try and fill them in.
Take the L-shaped pin and solder it into the threaded coupler. Thread the couplers in to the nylon sockets. Attach the nylon socket to the ball links.
Add X/Y Servos
Put the servos in to the printed servo stands (the thicker end is the bottom). Mark the screw holes on the stand. Drill pilot holes in to the servo stands and attach the servos using the provided screws.
Take two servos and attach the arm servo horns. Align these with the clevis pin/ball links attached to the eyes. This is how your eye is going to move X and Y.
Before actually attaching the eye to the servo, you'll want to "calibrate" the servos. Connect the servos to your arduino board and power source - Yellow connects to a digital input to the arudino board, red (or orange) is positive 5 volts, and black (or brown) is negative and is attached to the negative.
You can use this basic code to find out where 90 degrees is and how far you want the servos to move to get the right effect (Add brackets <> around Servo.h). Once you've figured out how far you want the servos to move back and forth, then you've probably figured out approximately where you need the servos to be glued down. In my case, I had to use cardboard to lift them up a bit.
#include Servo.h
Servo servoX; Servo servoY;
void setup() { servoX.attach(10); servoY.attach(11); }
void loop() { servoX.write(55); servoY.write(90); delay(400); servoX.write(125); servoY.write(90); delay(400); servoX.write(55); servoY.write(90); delay(400); servoX.write(90); servoY.write(70); delay(400); servoX.write(90); servoY.write(90); delay(400); servoX.write(90); servoY.write(70); delay(400); }
Add Blink/Tilt Servos
The blink and tilt servos are going to fit on the opposite side of the X-Axis servo. The blink servo is actually going to lift the tilt servo with a long arm servo horn. The tilt servo uses the small X servo horn to tilt the eyelids up and down along with the eye's movement.
Attach the servos to the printed servo stands. Drill a hole on the bottom (thicker) end of the servo stand in the middle. Attach the tilt servo to the blink servo using a few washers and a screw. The tilt servo and blink servo should be facing each other. In order to keep the tilt servo on the same path, I ended up gluing two cardboard "rails" on other side of the tilt servo.
Use the same code in the previous step to test movement, but connect the blink and tilt servos instead of the X and Y servos.
Add Button
Install a small button on the side of the button to activate the eye's movements.
Wiring
Here's the wiring setup I used. I started out using a 9-Volt battery for the arduino and 4 x AA Battery holder for the servos, but wanted a longer lasting battery and switched to a LiPo pack.
Add Eyelids
Cut two pieces of the aluminum wire approximately 1.5" long. Curve these pieces to fit over the eye, one on top of the other. With a small punch or some other tool, punch a small hole on either end of the eyelids. On one end, punch another small hole about 1/4" above the first. This second hole is how the eyelids will attach to the servos.
Use a small screw and two washers and a bolt to connect the two eyelid halves. You'll want the bolt on the inside and the washers on the outside of the eyelids. Since this will be moving, it's a good idea to use some thread lock on the bolts to keep them on. Screw the ball link in to the second holes and thread lock the bolt on the inside.
The small eyelid stand is glued on top of the X-axis servo stand. The taller eyelid stand goes in front of the tilt servo. Hot glue the head of the screw to the eyelid stand so that the eyelids can still move freely.
Code Test
Here's the final code I ended up using. This was my first adventure in to Arduino programming, so feedback is welcomed. I'll also try to update this with an excellent article I used to have smooth servo movements.
/*
* Smooth servo rotation using a sinus square function. * ATTENTION: THIS SKETCH USES THE DELAY FUNCTION * More infos: http://letsmakerobots.com/node/31697 * created by NilsB */#include
int blinkTimerInMillies = 5; const int blinkTableEntries = 21; const int blinkTable[] = { 60, 60, 60, 60, 61, 61, 62, 63, 64, 66, 67, 69, 71, 73, 75, 77, 79, 80, 80, 80, 80
}; const int eyeTimerInMillies = 8; const int eyeTableEntries = 77; const int eyeTable[] = { 45, 45, 45, 46, 46, 46, 47, 47, 48, 49, 50, 51, 52, 54, 55, 57, 59, 61, 63, 65, 67, 68, 70, 72, 74, 76, 78, 80, 81, 83, 84, 85, 86, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 94, 95, 96, 97, 99, 100, 102, 104, 106, 108, 110, 112, 113, 115, 117, 119, 121, 123, 125, 126, 128, 129, 130, 131, 132, 133, 133, 134, 134, 135, 135, 135 };
const int button = 2;
Servo blinkServo; Servo shiftServo; Servo xServo; Servo yServo;
void setup(){ setupBlinkServo(); setupShiftServo(); setupEyeServo(); pinMode(button, INPUT); digitalWrite(button, HIGH); }
void loop(){
if (digitalRead(button) == LOW) { attach(); delay(600); open(); close(); open(); delay(200); lookUp(); delay(200); lookUpDown(); delay(200); neutral(); delay(200); lookLeft(); delay(200); lookLeftRight(); delay(200); neutral(); delay(200); blinkTimerInMillies = 20; close(); blinkTimerInMillies = 5; delay(200);
} else{ } detach();
}
/*********************************** ********* Stop/Start Function ****** ***********************************/ void detach(){ stopXMove(); stopYMove(); stopBlinkMove(); stopShiftMove(); }
void attach(){ setupEyeServo(); setupBlinkServo(); setupShiftServo(); }
/*********************************** ********* Blink Functions ********** ***********************************/ void open() { for(int angleIndex = 0; angleIndex < blinkTableEntries; angleIndex++){ moveBlinkServoTo(angleBlink(angleIndex)); waitBlink(); } waitLongBlink();
}
void close() { for(int angleIndex = blinkTableEntries-1; angleIndex >= 0; angleIndex--){ moveBlinkServoTo(angleBlink(angleIndex)); waitBlink(); } waitLongBlink();
}
void moveBlinkServoTo(int angle){ Serial.println(angle); blinkServo.write(angle); }
int angleBlink(int index){ return blinkTable[index]; }
void stopBlinkMove(){ blinkServo.detach(); }
void setupBlinkServo(){ blinkServo.attach(11); blinkServo.write(60); }
void waitBlink(){ delay(blinkTimerInMillies); }
void waitLongBlink(){ delay(5*blinkTimerInMillies); }
/*********************************** ********* Shift Functions ********** ***********************************/
void up() { shiftServo.write(90); }
void down() {
shiftServo.write(130); }
void neutral() { shiftServo.write(110); xServo.write(90); yServo.write(90); }
void setupShiftServo(){ shiftServo.attach(10); shiftServo.write(110); }
void stopShiftMove(){ shiftServo.detach(); }
/*********************************** ********** Eye Functions *********** ***********************************/
void lookDown() { down(); for(int angleIndex = 38; angleIndex < eyeTableEntries-1; angleIndex++){ moveYEyeServoTo(angleEye(angleIndex)); waitEye(); } waitLongEye(); }
void lookUp() { up(); for(int angleIndex = 38; angleIndex >= 0; angleIndex--){ moveYEyeServoTo(angleEye(angleIndex)); waitEye(); }
waitLongEye();
}
void lookUpDown() { up(); for(int angleIndex = 0; angleIndex < eyeTableEntries-1; angleIndex++){ moveYEyeServoTo(angleEye(angleIndex)); waitEye(); down(); } waitLongEye(); }
void lookDownUp() { for(int angleIndex = eyeTableEntries-1; angleIndex >= 0; angleIndex--){ moveYEyeServoTo(angleEye(angleIndex)); waitEye(); } waitLongEye(); }
void lookLeft() { for(int angleIndex = 38; angleIndex < eyeTableEntries-1; angleIndex++){ moveXEyeServoTo(angleEye(angleIndex)); waitEye(); } waitLongEye(); }
void lookRight() { for(int angleIndex = 38; angleIndex >= 0; angleIndex--){ moveXEyeServoTo(angleEye(angleIndex)); waitEye(); } waitLongEye();
}
void lookLeftRight() { for(int angleIndex = 0; angleIndex < eyeTableEntries-1; angleIndex++){ moveXEyeServoTo(angleEye(angleIndex)); waitEye(); } waitLongEye(); }
void lookRightLeft() { for(int angleIndex = eyeTableEntries-1; angleIndex >= 0; angleIndex--){ moveXEyeServoTo(angleEye(angleIndex)); waitEye(); } waitLongEye(); }
void moveYEyeServoTo(int angle){ Serial.println(angle); yServo.write(angle); }
void moveXEyeServoTo(int angle){ Serial.println(angle); xServo.write(angle); }
int angleEye(int index){ return eyeTable[index]; }
void stopYMove(){ yServo.detach(); }
void stopXMove(){ xServo.detach(); }
void setupEyeServo(){ yServo.attach(9); yServo.write(90); xServo.attach(6); xServo.write(90); }
void waitEye(){ delay(eyeTimerInMillies); }
void waitLongEye(){ delay(5*eyeTimerInMillies); }
Skinning the Book
Mark out where you'd like to have pieces. Use some scrap paper to cut templates. Cut pieces of brown paper slightly larger (about 1/4") larger than the template pieces
Mix a small amount (like 1 Tablespoon) of glucose to a small spray bottle of water. Spray the pieces of brown paper with the water/glucose mixture until they're wet but not soaking. Crumple the paper and flatten it back out. You want to get a nice set of lines. Below is a good tutorial that I followed up until adding ink:
Sheena's Faux Leather Technique
Once the paper pieces are dried, use some wood stain to give them color.
Use modge podge to glue the pieces to the book, but leave the edges unglued. After the pieces have dried, fold the edges together to make a ridge. Add a coat of modge podge on top of all of the pieces.
With a large needle, start using the twine and blanket stitch all of the pieces together. Use a bit of wood stain on the stitches to age them.
Repeat the faux leather technique on two smaller pieces of paper to be used as the eyelids. The best way I found to attach them is to fold a portion over and glue the paper to itself to create a pocket. You may need to cut darts in to the eyelids to give it more of a curved shape.
Decorations
Use the silver clay to make the book corners and snake. The clasp is three separate pieces - the circle, a braid the height of the book, and a small skeleton hand. Bake these in the oven until hard.
Once hardened, take the black acrylic paint and lightly dry brush all of the pieces to age them. Glue the corners and snake on the book.
Glue the circle and the braid to one hinge. Glue the other end of the braid and the hand to the other hinge. Glue the skeleton hand to the back of the book so that the circle fits around the eye opening.