Introduction: Animatronic Face of Ed From Good Burger
This project is inspired from Disney’s Hall of Presidents attraction. This animatronic face is based on one of the main characters, Ed, from the movie Good Burger (1997). The animatronic face is powered by the Arduino platform and has two forms of interaction: object tracking and mouth syncing with conversational integration. The face uses a dual ultrasonic sensor setup to track objects in front of it and move the eyes accordingly to maintain eye contact. The face also utilizes a microphone as a threshold sensor to listen for a person's interaction; once the threshold is reached the animatronic plays a sound and the mouth moves in a rudimentary mouth sync.
Attachments
Supplies
The following items should be used for the construction of the animatronic face. An itemized list with the quantity and unit price of each item is shown in the figure.
Other materials used in the construction of the animatronic face included various tools. The tools used were a drill, screwdrivers, a reciprocating saw, FDM 3D printer, and soldering equipment.
Step 1: Supporting Structure
The supporting structure for this project was created using wood as we decided this would be the best material to provide sturdiness and ease of transport. All components of the final assembly will be fixed to this supporting structure. To build the structure, follow the steps below:
- Cut the 2x4 into 5 pieces; 3 of which are 11 inches long and the other 2 that are 18.5 inches in length.
- Create a simple box by joining one of the 11-inch-long pieces with an 18.5-inch-long piece to create an L. Do this again with the other two pieces, once you have two L shaped pieces you can join the two pieces together creating a box. (Note: If possible, pre-drill holes before screwing to prevent wood from splitting) [Figures 1-3]
- Add the third piece of 11-inch wood to the middle of the box, this will serve as the support for the eye mechanism. [Figure 4]
- At this point, you may decide to paint the supporting structure the color of your choosing. In this project, we decided to paint the structure black to ensure all components behind the face remain concealed to the users during interactions.
Step 2: Face Fabrication
The face used in this project was determined to be a character from the movie Good Burger. To ensure the face was mounted in a strong fashion while allowing mechanical fixation to the supporting structure, the face was mounted on 0.25” thick cardboard. To fabricate the face, follow the steps below:
- Print out a full-page image of Ed from Good Burger
- Cut a piece of cardboard to fit a full-size sheet of paper(8.5” x 11”)
- Adhere the image to the cardboard using either tape or glue
- Cut out the eyes of the image and make sure to cut through the cardboard as well
- Apply hot glue to the edges of the cuts, this strengthens the edges and results in a clean finish
- Feel free to color the hot glue edges with a black sharpie in order to conceal any imperfections
Attachments
Step 3: 3D Printing Eye Mechanism
To complete this project, you must first print all 3D models used in the construction of the eye mechanism. The eye mechanism comprises simple linkage systems attached to servo motors capable of controlling eye movement. In this animatronic face, eye movement is constrained to side-to-side motion, however, the mechanism can be expanded to have the ability of up and down motion. This expansion of capabilities requires additional parts and code and instructions can be found using this link here.
The required 3D printed parts used in this model are outlined in the figure below and the necessary STL files are located in the attached zip folder. The print settings and materials for these parts are arbitrary, however, this project utilized 0.2mm layer height with PLA material and on the Original Prusa i3 MK3S+.
Attachments
Step 4: Post Processing 3D Printed Parts
Once all 3D parts are printed, there will be some necessary post-processing procedures to ensure the eye mechanism can be properly assembled and functionality is not hindered in any way.
- Remove any and all supports located on the 3D printed parts. (Note: The 3D printed parts are susceptible to printing imperfections that can sometimes lead to breaking or cracking of the part. Please be aware that the parts are weakest between layers and can break if handled improperly. In the event a piece breaks, we found the best solution to be Krazy Glue or Loctite Super Glue to repair. We also found that you may prevent future breaking by identifying points of weakness in the parts and applying the glue to those parts during the post processing.)
- Sand the eyes and eyelids to ensure they can move freely and without hindering motion.
- Paint the eyes and eyelids to your desired look and skin tone. (Note: When painting the eyes, be aware of the amount of paint applied as this paint will take away from the tolerancing between the eyes and inside of the eyelids. To maintain this tolerance, do not paint the inside of the eyelids as this will completely remove any tolerance and you will need to sand the inside of the eyelids again.) [Figures 1-2]
- Feel free to drill out holes located on each of the parts using a hand drill. The parts are designed to print such that some holes are undersized enough to be directly screwed into while others are oversized enough so the screw will pass through snugly. We found that all of our holes were printed too small and therefore opened each hole up the slightest bit to ensure proper fit.
Step 5: Eye Mechanism Assembly
Once the parts are printed and post-processed, assembly of the mechanism can commence. It may be helpful to refer to this video taken from another instructable to understand how each piece fits together. There are also reference pictures included within each step for reference.
- Connect the main- and sub- bases with 10mm/12mm M3 bolts. Since we will be constraining the motion of the eyes to just side-to-side, we will want to ensure that the sub-base is not free to rotate. This may require larger bolts depending on the print quality. (Note: Be sure the bolts used will not protrude too far into the gaps where the eyes will be held in place. If the bolts are too long, it may contact the eyes during movement and therefore impede eye motion.) [Figure 1]
- Insert the servo into the sub-base and fix it into place with 4 or 6 mm M2 screws. This servo will be in charge of side-to-side or x-axis motion. [Figure 2]
- Start assembling the x-axis assembly by first screwing the forks into the eye-adaptors with 4/5/6mm M3 bolts. (Note: The fork hole should be oversized so the screws bite into the adaptor. One of the attachment screws will need to be inserted at a funny angle but should be able to get in without breaking anything.)
- Attach the three-point connector to the top of the forks. The M3 screw will bite into the undersized hole in the fork component. [Figure 3]
- Attach the servo arm on the final hole to the center of the three-point connector using a 5mm M3 bolt. (Note: The hole on the servo arm will need to be drilled out to 2.5-2.8 mm to accept the screw.)[Figure 4]
- Once the previous steps are complete, attempt to move the assembly to ensure that all components move freely and are not overtightened.
- Attach the eye holder link to the center of each eye adaptor using 8mm M3 screws. Ensure the flat surface of the eye holder link is facing up and the sloping section is facing downwards. You may now plug in the eye place holders onto the eye adaptors at this point.
- Screw the remaining free holes on the eye holder to the remaining holes on the subbase. Use two 8/12mm M3 bolts and be sure they are rigidly fixed together. [Figure 5]
- Attach 4 servos to the servo block using the self-tapping screws given with the servos. The correct orientation of these servos are shown in the below picture. [Figures 6-9]
- Identify which servo will be used for top or bottom eyelid blinking. In this project, the front servos were used for top eyelid movement and the back servos were used for bottom eyelid movement.
- Connect the relevant eye connectors to their designated servos using a 4 mm or 6 mm M2 screw. Attach the servo arm to the other end using the last hole in the servo arm. (Note: The longer eye connectors will be used for the back servos, while the shorter eye connectors will be used for the front servos. In this project the short eye connectors were used for the top eyelids and long eye connectors were used for the bottom eyelids.)[Figure 10]
- Attach the eyelids to the main base but do not connect any servo arms to the eyelids at this point. Make sure the eyelids are free to rotate in the housing without significant friction. [Figures 11-14]
Step 6: Mouth Mechanism Fabrication and Assembly
The mouth mechanism will utilize a single servo motor, a spacer that can be created out of plastic or wood and a popsicle stick
- Cut out the mouth of the cardboard face. (Note: It is recommended to cut a square so that the mouth is similar to a puppet.)
- Glue the edges of the mouth to strengthen it
- Cut a small slit in the back of the mouth just large enough to fit a popsicle stick.
- Place the popsicle stick into the cut and glue into space.
- Attach the popsicle stick to the paddle of the servo motor
- Place the full face onto the front of the chassis , position it such that the eye mechanism lines up with the eye cutouts and hold the mouth in place so that it is aligned with the face.
- Once in place measure the distance between the wood supporting the eye mechanism and the top of the mouth servo
- Create a spacer to that length, it is best to cut out a C-shape so that height is met but the spacer can be screwed into the wood chassis.
Step 7: Eye Mechanism Wiring
The wiring for the eye mechanism will use the attached servos and ultrasonic sensors. Due to the number of available PWM pins, the eye mechanism will use an Arduino Uno to itself. The ultrasonic sensors will need to be mounted on separate breadboards to allow independent fixation to the supporting structure with each ultrasonic position chosen to limit interference signals between the two sensors.
- Use the figure below to wire each of the components. (Note: There are 6 available PWM pins on the Arduino and we will be using 5 for the servos. Additional digital pins will be used for the echo and trig pins for each ultrasonic sensor.) [Figures 1-6]
- Once all components are wired, this is the opportunity to link all the servo arms to their respective servos. To do this, ensure the eyes are facing forward and in a neutral position. For the eyelids, ensure they are closed and centered along the eye diameter. After this is verified, attach the servo arms to their respective servos. [Figure 7]
- Turn the system on and allow the eyes to blink a couple of times. This will set the correct positioning of the eyelids during blinking and eyes during x-axis motion. (Note: If you hear the servo gears grinding or the eye movement doesn’t seem natural, you may need to change the angles of the servo motion to accommodate your setup.)
- Once the system is working properly, disconnect the power and screw each servo arm into their respective servos to ensure a strong connection.
- At this point, the eye mechanism construction and wiring is complete!
Step 8: Mouth Mechanism Wiring
The mouth needs to be wired together now with an Arduino, mp3 player, microphone and a speaker. The mp3 used is a DFPlayer mini and the naming convention needed to read mp3 files as well as wiring can be found here. To maximize space on the chassis and for better microphone performance, some soldering was performed.
- Get 3 wires that are roughly 3 ft long( these will be used for the microphone so that it is given to whoever interacts with the animatronic).
- The lm393 microphone board has 3 prongs, the first is a 5v power supply, the middle is output and the last is ground. Solder the 3 wires to the microphone chip so that the microphone can be placed away from the animatronic’s speakers.
- Apply hot glue to the microphone chip, this is to protect the chip since it will be handled. Make sure to cover all exposed wires and solder points but do not cover the potentiometer(this is used to adjust the microphones sensitivity)
- On the wire soldered to the output of the chip connect a jumper wire connector, this can be from crimping a connector on or cutting and soldering the end of an existing jumper wire.
- Connect the output of the microphone to the Arduino pin D7.
- Solder the DFPlayer mini chip to an empty PCB board. This board will provide power to the speakers, microphone and Servo.
- On the same row as the power supply pin for the DFPlayer, solder the power cable for the microphone and servo as well as a jumper cable to connect the 5v from the Arduino.
- Once the powers are all on the board, bridge the connectors together with solder so they share the 5v power from the Arduino.
- Repeat the same process with the grounds.
- Wire the rest of the inputs and outputs of the DFPlayer by soldering 2 jumper cables that connect to the Arduino(pins 11 and 12 as seen below) and the cables for the speaker directly onto the PCB board. [Figure 1]
- Connect the input wire for the servo on pin D9 and connect the jumper cables for the 5v and ground directly to the Arduino. The final product should look similar to the images below. [Figures 2-3]
Step 9: Programming
Mouth Sync
- Create instances of Servo and Software Serial objects (DFPlayer)
- Define the pins for the Servo(9), Microphone sensor(7), and the DFPlayer(10 for RX ,11 for TX)
- Define a counter, this will be used to vary the responses Ed gives and define previousMillis, this is to have a timer-based response from Ed when no input is received.
- In Setup(), initialize the servo and DFPlayer by using Serial.begin(115200) and mySoftwareSerial.begin(9600). Also set the volume of the speaker using myDFPlayer.volume() and any number between 0 and 30
- In the loop(),check time using millis() and constantly read the input from the microphone sensor.It is a threshold so if no input is received the value will be 0 and if the threshold is met the value will be 1.
- If the threshold is met then play the sound associated with the initial counter and advance the counter so that a different response is given when the threshold is met again( the second response resets the counter).
- Check the state of the DFPlayer constantly, while it is playing then attach the servo associated to pin 9 and send a signal to the servo motor to alternate between two positions( mouth opened and closed) and reset the timer to 0.
- While the player is not on, set the servo position to mouth closed and disconnect the servo.(The servo is detached to avoid the motor chattering)
- If no input is received after 30 seconds, then play a third response which is Ed’s famous song.
Eye Mechanism
The animatronic eye Arduino code is relatively simple and easy to understand.
- In order for the code to operate correctly, use the Servo.h library of the Arduino.
- First include all the required libraries and define all instances required to control the 5 servo motors used. At this stage define each of the ultrasonic pins and the different parameters that will be used to control the eye tracking of the system (ie. angle of rotation ranges, millisecond intervals for blinking, initial eye angles, scanning workspace, etc.)
- Next, within the setup() function, identify the pins associated with each servo and assign each of the ultrasonic pins as inputs or outputs.
- Initialize the serial for debugging and set the ultrasonics to scan the environment every 8 milliseconds (3 milliseconds for the trigpin at low and 5 milliseconds for the trigpin at high).
- Convert the microsecond delay of the ultrasonic sensors to inches. Take this number and convert to distance to identify the distance an object is from the sensor.
- Create a millisecond timer and counter using a conditional if-statement. Within this statement, open and close the eyes. This statement will allow the eyes to blink without using a delay command and instead will use the millis() command. (Note: If a delay command is used, this will also delay the scanning of the ultrasonic sensors. This is undesired as it will negatively impact the eye tracking capability of the eye mechanism.)
- Create the functions to be used by the code during the eye following and blinking movements. The necessary functions are explained below and should be contained within the code and outside of the main loop.
- follow(): This function is used to have the eyes follow the objects identified by the ultrasonic sensors. The eyes will move at increments of 5 degrees to ensure full range of motion is completed without substantial delay.
- open_eye(): This function is responsible for dictating the servo positions of each eyelid during the eye-opening process.
- close_eye(): This function is responsible for dictating the servo positions of each eyelid during the eye closing process.
- The final encounter with the user should track their movements from left to right and will blink in a random fashion as dedicated with the Arduino code.
Step 10: Final Assembly
Once construction of all subassemblies is complete and programming of all components is finished, it is now time to conduct the final assembly procedures.
- Ensure that the following subassemblies have successfully been built and are on hand:
- Supporting structure (painted if applicable)
- Face mounted on cardboard and with the mouth cutout
- Mouth cutout attached to servo and mounting base
- Eye mechanism
- 2 ultrasonic sensors fixed to separate breadboards and connected with all eye mechanism servos to an Arduino Uno
- A microphone, SD card reader, and speaker soldered to a PCB board and attached to a second and separate Arduino Uno
- To begin, first center the face on the front of the supporting structure to ensure it is aligned horizontally. Mark the location of the face on the center shelf. [Figure 1]
- Place the eye mechanism on the middle shelf of the supporting structure and align it with the face in a location that lines up with the eye cutouts of the face. (Note: Be sure to offset the location of the eye mechanism behind the face to ensure the servo arm or eyelids contact the back of the face cardboard.)[Figure 2]
- Once the location is finalized, take 2 self-tapping wood screws and drill through the main base of the eye mechanism at arbitrary locations to ensure strong fixation of the eye mechanism to the supporting structure. [Figure 3]
- Place the electronics for the eye mechanism on the bottom base of the supporting structure. Independently place each of the ultrasonic sensors to face outwards from the centerline of the supporting structure. (Note: You will have to mess around with the angle of orientation of the ultrasonic sensors to help prevent both ultrasonic sensors from picking up the same object location. This will confuse the eye mechanism if not mounted correctly.)
- Fix each ultrasonic breadboard to the base of the supporting structure using the sticky adhesive on its back. If this is not sufficient, use hot glue to fix them to the base.
- Use hot glue to fix the Arduino Uno to the center of the bottom shelf of the supporting structure. (Note: Ensure the Arduino is located horizontally in the center to ensure the wires do not get bent or pulled out of the Arduino during transport or function.)
- Apply a good amount of hot glue to the front face of the middle shelf of the supporting structure. Align the face with the marks previously made and with the eye cutouts. Firmly press the face onto the supporting structure and do not remove pressure until the glue fully sets.
- Align the mouth and attached servo to fit within the cutout of the face. The mouth should fit snugly but with enough tolerance to move without friction. Mark the location of the mouth bracket on the underside of the middle shelf.
- Take a single self-tapping wood screw to affix the mouth’s support bracket to the bottom the middle shelf of the supporting structure. Ensure the screw does not go up and through the eye mechanism.
- Use self-tapping wood screws to affix the second Arduino and PCB to the back side of the supporting structure that does not over-stretch or damage the wires. [Figure 4]
- Take the speaker and place it in the center of the bottom shelf of the supporting structure, in front of the first Arduino to help conceal its location. The final placement of all electronics should follow as shown in the figures below. [Figures 5-7]
At this point your assembly has been completed and will properly function pending power being provided to each Arduino. We decided to power the device using 9V wall plugs into the associated Arduino ports. Enjoy your animatronic face of Ed from Good Burger!
Step 11: Interaction Check
Step 12: Lessons Learned and Suggestions for Improvement
Lesson of the Day - The microphone used was an electret microphone and an LM393 that only output a binary response depending on threshold. This meant that the animatronics could be activated from an ambient sound if the sensitivity was too high or the animatronic was difficult to activate with a low sensitivity. An improved sensor would be a microphone that outputs the waveform from the sound given. Using a reference waveform of trigger words and a deep learning model to identify patterns in waveforms the microphone sensor could have been more sensitive with less false activations. The types of response could also be altered to be more interactive with more relevant responses depending on the trigger word input.
Second Lesson of the Day - Although the ultrasonic sensors were oriented in a way that should have prevented any crosstalk between them, during operation the animatronic eyes seemed to pick up signals from both ultrasonics quite frequently. Due to this, the eyes had a tendency of moving from far left to far right but without having the functionality of looking straight forward. To alleviate this issue, more code can be produced to make the eyes go to center when both ultrasonics record readings above a certain threshold. This code can, in theory, then differentiate the left region from right region from center region of the scanning workspace.