3D Printed, Motion-Activated, Actuated Skull Halloween Decoration
by Applepie1928 in Circuits > Arduino
1273 Views, 11 Favorites, 0 Comments
3D Printed, Motion-Activated, Actuated Skull Halloween Decoration
This project is a fully 3D printable, actuated skull which plays a series of different "animations" when triggered by motion on a PIR sensor.
The goal of this project was to make an accessible design using commonly available Arduino parts and a minimal amount of soldering. The 3D designs are all quite simple and should be easily printed on any level of 3D printer. This is a great learning project as it introduces a basic geared system and has a clean code base which can easily be expanded to produce more custom designed "animations".
So if you want to build a little animatronic, learn a bit about gears or Arduino coding, or if you just want to create a spooky decoration to scare visitors then this is the project for you!
Supplies
The supplies for this project can be broken down into 3 sections: 3D Printed Components, Electrical Components and Sundries. The STL files for the 3D printed components are attached as supporting files or can be found on ThingiVerse.
3D Printed Components
- Skull
- Jaw
- Servo Bracket x 2
- Servo Gear
- Left Eye Cover
- Right Eye Cover
- Nose Cover
- Back Cover (The alternative "Holes" version has mounting holes in the back plate)
- (Optional) PIR Case Front
- (Optional) PIR Case Back (Tack)
Electrical Components
- Arduino Uno (I used R3, but R4 should also fit)
- SG90 Servo x 2
- PIR Sensor
- SPDT Slide Switch
- 9V Battery Connector
- Red 5mm LED x 2
- 220 OHM Resistor x 2
Sundries
- M3 x 6mm Screw x 4
- M3 x 8mm Screw x 13
- M2.5 x 16mm Screw (or bigger) x 4
- M2 x 5mm Screw x 2 (These should be included with the servo for mounting)
- M2 x 6mm Screw x 2
- Small amount of AWG 26 or thicker wire (silicone insulation recommended)
- 9V Battery
- Solder
- Kapton Tape/Electrical Tape (or equivalent thin insulating tape)
In terms of tools there are only a few things that are required:
Tools
- 3D Printer
- Soldering Iron
- Screwdriver with tips to match your screws
- Flush Cutters and/or Wire Cutters
- (Optional) Multi-meter (highly recommended for testing connections/avoiding shorts)
- (Optional) Sandpaper (I used both 150 grit and 240 grit to clean up/smooth out the button guides in the shell)
- (Optional) Modelling Knife or equivalent (useful for removing blobs and blemishes from the printed parts)
3D Printing
The first step is to 3D print all the required components required for this build as are listed in the section above. All the parts not listed as optional are required for the main body of the skull, the two optional components are for housing the PIR sensor if you need a mounting solution.
You can print your skull in any colours you desire, but I chose to go classic and use white for the Skull and Jaw parts, and then Black for everything else. I used a matt PLA for the white parts to give a more realistic "bone" finish, however this will make these parts weaker than using a standard PLA+ with a glossy finish. I used a standard black PLA+ for all the other parts.
I printed all these parts at a fairly high speed and still got decent quality results, but if you know your printer is less accurate it might be worth reducing the speed to make sure push fits/screw holes are as accurate as possible.
The following are simple small prints which can just be printed without supports:
- Servo Bracket (print with the large flat surface to the build plate so the screw hole legs point up)
- Servo Gear (print in the orientation provided)
- Left Eye Cover (print in the orientation provided)
- Right Eve Cover (print in the orientation provided)
- Nose Cover (print in the orientation provided)
- Back Cover (print in the flipped orientation so the screw hole chamfers face up)
- (Optional) PIR Case Front (print in the orientation provided)
- (Optional) PIR Case Back (Tack) (print in the flipped orientation so the screw hole legs point up)
The two main parts of the skull require supports to get the best print results:
- Skull - Orient this model so the front of the model is face down to the build plate. Enable supports so that the large curved front can be printed more cleanly. You can block supports on the screw holes for the backplate, and for the mounting hole for the switch (this can be seen in the image above).
- Jaw - Orient the jaw the opposite to the skull, so that the rounded front of the jaw points up. Enable supports so that they support the overhanging teeth, and the large cut-out sections below the gear slide (this can be seen in the image above)
After printing there is a small amount of post processing to do in order to get everything clean. Remove all the supports from the Skull and Jaw and then use a combination of a craft knife and sandpaper to get a smooth finish on the surface. If you want to paint your skull, this would be a great time to whip out some acrylic paints and get creative!
With all the printing finished, we can start assembly!
Servo Mounting
In this step we will attach the servo to one of the two Servo Brackets, attach the gear to our servo and fit both brackets into the skull.
- Position the servo through the hole in the servo bracket from the side which has the two screw hole legs protruding. Ensure the gear of the servo is at the bottom (closest to the screw hole legs). Use the two M2 x 5mm screws which came with the servo to screw it into the bracket at the top and bottom.
- Take the servo gear and push fit it over the nylon gear on the end of the servo. This should be a snug fit and turning the gear should also turn the workings of the servo.
- With the Skull face down, place the bracket with the servo attached on the two mounts at the left of the skull and secure it in place with two M3 x 6mm screws.
- Take the other bracket (without a servo attached) and screw it into the same two mounts on the right side of the skull.
- Turn the servo (by turning the attached gear) as far as it will go anti-clockwise.
- Place the jaw into the slots so that it is in a mouth closed position and ensure the teeth of the servo gear mesh with the teeth of the gear slide on the jaw.
- Take the four M2.5 x 14mm (or longer) screws and screw them through the holes in the top of the servo brackets from the inside of the skull. These screws should go through the slot in the jaw and their only purpose is to keep the jaw level whilst it is actuating.
You may need to adjust the exact position of the gear on the servo, or the jaw on the gear to get the perfect fit, so spend a little time making sure everything fits neatly.
That's basically all the mechanical parts complete for this build, so now it's onto the electronics.
Eyes, Nose and Lights!
Next we need to prepare the LED lights for the eyes, before all the covers are mounted into place in the skull. So to start we will need to solder the two Red 5mm LEDs to the 220 OHM resistors and some lengths of wire.
- Cut two 5cm to 10cm lengths of wire for the positive legs of the LEDs (I used red wire), and strip both ends.
- Cut two 5cm to 10cm lengths of wire for the negative legs of the LEDs (I used black wire), and strip both ends.
- Identify the negative side of the LEDs, it should have a shorter leg, and a flat edge. Solder one black wire to the negative leg of the first LED. Then solder the other end of that wire to the negative leg of the other LED along with one end of the other length of black wire.
- Solder a 220 OHM resistor to the positive leg of each LED, and then solder one of the lengths of red wire to each of the end of the resistor.
Check the first image above to see how this should look when completed. The negative legs of both LEDs should be tied together with a common ground wire, and each positive leg should have a resistor in series with the connecting red wire. After you are happy the soldering is completed, use electrical or insulating tape to cover any bare metal to prevent short circuits.
The Left Eye Cover, Right Eye Cover and Nose Cover can now all be placed onto their mounts inside the skull, so that the flat side is facing into the inside of the skull (see the image above). These can now be screwed into place using a total of six M3 x 8mm screws.
Once these are secured, the LEDs can be push fit into the two holes in the eye covers so that they poke through to the front of the skull. If you find these are a bit loose they can be held in place with tack, tape or even hot glue. You can bed the legs of the LEDs down to keep them as flat as possible, and try to route the wires in such as way that they are not in the path of the moving sections of the jaw (see the final image above).
Power (It's Alive!)
The power supply system for this system is quite simple and is all provided from a single 9V battery. The battery is simply connected to a slide switch which enables power to flow to the Arduino which in turn provides voltage regulation and power to all the other components in this build.
- Cut a 5cm to 10cm length of wire (I used red wire), and strip both ends. Tin the one end of the wire on a soldering iron.
- Solder the other end of the wire onto either of the outside pins on the SDPT slide switch.
- Take the 9V Battery Connector and solder the red wire onto the centre pin on the switch.
At this stage, your wiring setup should look like the second image above.
To mount the switch into the skull, position it on the small shelf at the top of the skull, so that the switch itself protrudes through the square hole. Ensure that the soldered wires are coming out of the top of the switch (facing the back of the skull), and make sure the switch is in the OFF position (positioned on the opposite side to where the outer wire is soldered). Use the two M2 x 6mm screws to attach it to the skull.
You can now add the 9V Battery to the end of the battery connector and slot it into the rectangular housing as shown in the image above.
N.B Double check your switch is in the off position as now there are loose wires and a battery in the circuit you don't want to cause a short.
Spooky Software
I have written and provided some heavily commented basic code which can control the servo, flash the lights of the eyes once the PIR sensor is triggered. This is achieved through a number of different "animation" functions which each have their own character, such as slow creepy jaw opening, to evil laughter.
If you wish to just run this sketch as is, then simply download the provided Acutated_Skill.ino file from this section, open it in your Arduino IDE and upload it onto your Arduino Uno.
However, this little build is a great tool to mess around with learning some basic Arduino coding as it has moving servos, LED commands and separate functions. So I would recommend having a read through the existing code and comments and seeing if you can come with your own animations or just improve the ones I have provided!
The animations are handled through a switch statement which randomly selects one of the animation functions to play when the PIR sensor is triggered:
void loop() {
if (isPirTriggered()) {
delay(random(500, 5000));
int animationType = random(1, 5);
switch (animationType) {
case 1:
laughMouth(random(2, 10));
break;
case 2:
slowOpen(random(2000, 10000));
break;
case 3:
randomJaw(random(2, 10));
break;
case 4:
eyesOnly();
break;
default:
break;
}
...
}
The initial "delay" function call is to set a random timeout between when the PIR sensor is triggered and the animation starts. This makes it harder for people to judge when the skull will start moving and helps to improve the jump scare! By default I've set this with the "random" function to be between 500 and 5000 milliseconds (0.5 to 5 seconds).
Once this delay has finished another "random" function call is made to choose which animation to start with the "switch" statement. The "random" function will select a number between the first number passed to it (inclusive) and the last number passed to it (exclusive). So for my default setting, when called as; random(1, 5); it will return a number between 1 and 4 to store in the "animationType" variable.
This variable is then entered into the "switch" statement to call one of the animation functions. For example, if the "animationType" variable is storing the number 1 (as chosen by the random function call in the line above), then the "case 1:" section of the code would run. A switch statement can be thought of as another way to writing if, if else and else statements. The "break;" call after the function is used to end the switch statement and make sure none of the other cases also run.
Each of the different animations has their own function, so as an example lets look at the "laughMouth()" function:
void laughMouth(int laughLength){
for(int i = 0; i < laughLength; i++) {
eyesOn();
jawServo.write(jawOpen);
delay(250);
eyesOff();
jawServo.write(jawClosed);
delay(250);
}
}
We can see from the function declaration "void laughMouth(int laughLength)" that this function doesn't return any value (from the void at the start of the declaration) and it requires one integer parameter to be passed to it (as shown in the parenthesis). In this function the integer parameter "laughLength" is used to determine how many times the jaw opens and closes during the laugh animation. By making this a variable length it adds more random behaviour to the animatronic overall.
The main body of this function consists of a for loop which will repeat the code inside for the "laugh" animation as many times as the "laughLength" parameter determines. Within this loop the actual animation occurs; firstly the eyes turn on (the LEDs in the eyes are illuminated), then the servo controlling the jaw is set to the "jawOpen" position, a delay of 250 milliseconds occurs (to allow the servo time to move), then the eyes turn off and the jaw returns to the closed position.
In order to make it more digestible to write your own animations I have included some useful variables, constants and helper functions to achieve this:
Constants
- jawClosed - this constant contains the angle of the servo to close the jaw without putting extra strain on the servo.
- jawOpen - this constant contains the angle of the servo to fully open the jaw
Variables
- pos - this variable contains the current position of the servo and can be used to monitor the current position of the jaw, or to move the jaw more slowly by updating the position in small steps with delays (see the "slowOpen()" animation function for an example of how to achieve this)
Functions
- eyesOn() - calling this function will turn on both of the LEDs in the eyes
- eyesOff() - calling this function will turn off both of the LEDs in the eyes
Hopefully this gives you a good starting point to mess around with the code and see what you can get your skull to do! For simple changes you can just change some variable values and see how that affects the skulls behaviour or if you want to add your own animation then follow these steps:
- Create a new animation function to control the eyes/jaw or both
- Increase the maximum limit for the "animationType" random call - E.G change "int animationType = random(1, 5)" to "int animationType = random(1, 6)"
- Add a new "case" statement to the switch statement below the last numbered case and give it the new maximum number as a value. E.G add "case 5:" to the default code below the end of the "case 4:" section.
- In the new case section, call your animation function, and add a "break;" call on the next line. E.G below "case 5:" add "myAnimationFunctionName();" and then "break;" on the following line
Once you are done with any editing or additions you want to do, ensure the code has successfully uploaded to your Arduino Uno before moving to the next step.
Downloads
Installing the Arduino
I have included a wiring diagram above so that you can double check everything is getting connected to right pins. In this step we will mount the Arduino into the skull and attach all the wires we have been adding so far.
First we do have to create some junction wires by soldering three lengths of wire together. Simply cut two medium (3cm to 5cm) lengths or wire and one short (1cm to 2cm) length of wire, and strip and tin all the ends. Solder all three different lengths of wire together at one end. Repeat this whole process twice, so you have a positive (red in my case) junction wire and negative (black in my case) junction wire. Check the image above to see how this looks, and don't forget to add insulating tape over the exposed metal where the wires join.
Aside from the junction wires, we also require two medium (3cm to 5cm) lengths of wire to connect from the servo and PIR sensor to the board. Just cut these wires, strip both ends and then tin them with the soldering iron.
Now it's time to get everything connected:
- Take the black wire from the battery connector and insert it into the first "GND" port on the "Power" section of the Arduino.
- Take the red wire from the switch and insert it into the "Vin" port on the "Power" section of the Arduino.
- Take the common ground (black) wire from the LED eyes and insert it into the "GND" port on the "Digital" section of the Arduino
- Take the red wire from the left eye and insert it into the pin 10 port on the "Digital" section of the Arduino.
- Take the red wire from the right eye and insert it into the pin 11 port on the "Digital" section of the Arduino.
- Take the red jumper wire we made and insert the short end into the "5V" port in the "Power" section of the Arduino. Then take the two other ends and insert them into the VIN/VCC ports of the PIR sensor and the servo.
- Take the black jumper wire we made and insert the short end into the other "GND" port in the "Power" section of the Arduino. Then take the two other ends and insert them into the GND ports of the PIR sensor and the servo.
- Take one of the remaining lengths of wire and connect one end to the remaining pin of the servo and the other end to the pin 9 port on the Arduino.
- Take the other remaining length of wire and connect one end to the remaining pin of the PIR sensor and the other end to the pin 8 port on the Arduino.
With all the wires attached, double check your connections using the provided diagram and images above to make sure everything is where it should be. Then just neaten up the cables, ensuring they are not in the way of the moving parts of the jaw and wont get caught when the back panel is added.
Finishing Up
All that is left to do now is to attach the backplate and secure it in place. If you are using the Backplate (Holes) version, then start by threading a piece of string or ribbon through the backplate into the internals, and then pull it out through the hole in the top of the skull along with the wires for the PIR Sensor.
The backplate can then be screwed down in all corners with four M3 x 8mm screws. Just ensure that no wires are being trapped as you tighten everything up.
The project is now complete and if you are going to prop your PIR sensor up nearby, then you can just flick the power on and everything should be good to go! However, if you also want to create the case and mounting solution for your PIR sensor then move onto the next optional step.
(Optional) PIR Sensor Housing
Slot the board for the PIR Sensor into the PIR Case Front so that the dome protrudes through the hole, and the board sits inside the case. Use two M2 x 5mm screws to attach the board firmly to the case. The PIR Case Back (Tack) can then be placed on the back to close the case, ensuring that the cut out is inline with the pins on the PIR sensor board. Two M3 x 8mm screws can be added from either side to fasten it in place. Don't over tighten these as they may start to warp the box.
The two holes on either side of the back of the case can be used to mount it on a variety of surfaces using either tacks or M3 sized screws.
HAPPY HALLOWEEN!