Goku Inspired Anamtronic Face
The character used to create the animatronic is inspired by Son Goku, also known as Goku. This animatronic is able to simulate two of his phases, Super Saiyan (SS) and Ultra Instinct(UI). Each phase triggers two different combinations of LEDs. SS lights all yellow LEDs and Ul lights a combination of white and blue LEDs. This happens in the background and his hair. Additionally, each interaction also counts with an audio and mouth movement. Some materials used are LEDs, ultrasonic sensor, photoresistor, servo motor, 2x6 wood, hot glue and super glue.
Supporting Structure
Three 2x6 and one 1x4 studs are used to create the supporting structure. The three 2x6 are the vertical support and upper horizontal support, while the 1x4 is the base. Additionally, a scrap piece is placed in the middle where the animatronic face will be.
Joint Design
Using solidworks, a rod was created that could be attached to the Servo. This will help in moving the animatronic mouth.
Actuators
As previously mentioned, a servo will be used to control the animatronic mouth. This will move in accordance to which transformation is triggered.
Sensors
Two sensors were considered. One of them being the ultrasonic sensor and the other an Photoresistor sensor.
Programming
1. Brain Arduino – Mode Selector (NORMAL / SS / UI)
Goal:
Continuously measure distance and ambient light, decide which form Goku should be in (NORMAL, Super Saiyan, or Ultra Instinct), then send that mode to the Execution board using two digital pins and print the active mode over Serial.
Initialization (runs once)
- Configure the ultrasonic trigger pin as an output and the echo pin as an input.
- Configure the two “mode” pins as digital outputs. These two pins together encode the mode in binary (00, 01, 10).
- Configure the output pins that go to aura and particle LEDs (even if they are not heavily used in this version, they are set LOW at startup).
- Make sure all outputs (mode pins and LED pins) start in a known OFF / neutral state.
- Start the Serial port at 9600 baud for debugging text output.
Distance measurement helper (getDistanceCm)
Whenever the distance is needed:
- Briefly pull the ultrasonic trigger pin LOW to reset the sensor.
- Send a short HIGH pulse on the trigger pin to start a measurement.
- Use a pulse-measuring function to time how long the echo pin stays HIGH.
- If no echo is received within a timeout, treat the distance as “invalid” (e.g., a large dummy number).
- Convert the measured time to distance in centimeters using the speed of sound and return that value.
Mode encoding helper (setMode)
To send a mode to the Execution:
- Take an integer mode value (0, 1, or 2).
- Extract the least significant bit and write it to the first mode pin.
- Extract the next bit and write it to the second mode pin.
- Together, these two bits represent the current mode in binary.
Main loop (runs repeatedly)
- Measure the current distance using the ultrasonic helper.
- Read the analog value from the light sensor (LDR).
- Start with the mode set to “NORMAL” (mode = 0).
- If the measured distance is valid and less than a preset distance threshold, change the mode to “Super Saiyan” (mode = 1).
- If the light level is below a preset light threshold (i.e., darker environment), override and change the mode to “Ultra Instinct” (mode = 2).
- Send the final chosen mode to the Execution by updating the two mode pins (using the mode-encoding helper).
- Over Serial, print exactly one word indicating the current mode:
- “NORMAL” for mode 0
- “SS” for mode 1
- “UI” for mode 2
- Wait for a fixed delay (e.g., several seconds) before repeating the loop, so modes don’t change too rapidly.
2. Execution Arduino – DC Motor + Servo Mouth + LEDs (L298N)
Goal:
Read the 2-bit mode from the Brain, and based on the mode:
- Control a DC motor through an L298N driver (speed + direction).
- Move Goku’s mouth servo according to precomputed angle patterns that match the audio.
- Turn on/off the correct LED colors for Super Saiyan and Ultra Instinct.
Data / Patterns
- Store a large array of precomputed servo angles for Mode 1 (songoku).
- Store a large array of precomputed servo angles for Mode 2 (SuperSaiyan).
- For each pattern, also store its length (number of elements) so the code knows when it reaches the end.
These arrays encode how open/closed the mouth should be at each step to roughly match the timing of the audio tracks.
Pin setup (runs once)
- Configure the two mode pins (coming from the Brain) as digital inputs.
- Configure the L298N driver pins:
- Two digital pins for direction (IN1 and IN2).
- One PWM-capable pin for speed (ENA).
- Attach the servo object to its dedicated servo pin and set the initial mouth angle to a neutral position (e.g., around 80–90 degrees).
- Configure the yellow LED pins and Ultra Instinct (blue/white) LED pins as digital outputs and set them all OFF initially.
- Initialize Serial for optional debugging.
Helper: readMode
Whenever the current mode is needed:
- Read the digital state of the first mode pin (bit 0).
- Read the digital state of the second mode pin (bit 1).
- Combine those bits into an integer value:
- 00 → mode 0 (NORMAL)
- 01 → mode 1 (Super Saiyan)
- 10 → mode 2 (Ultra Instinct)
Motor control helpers
- motorOff
- Set PWM on the enable pin (ENA) to 0 so the motor stops.
- Set both direction pins LOW so no direction is driven.
- motorForward(speed)
- Clamp the requested speed between 0 and 255.
- Set the direction pins to drive the motor forward (e.g., IN1 HIGH and IN2 LOW).
- Write the speed value to the PWM enable pin (ENA) to set how fast the motor spins.
Generic mouth pattern player (playMouthPattern)
This helper is used by both Super Saiyan and Ultra Instinct modes:
- Accept a pointer to a pattern array, its total length, a reference to a current index, a reference to the time of the last step, and a step interval in milliseconds.
- If the current index is greater than or equal to the pattern length:
- Stop advancing and hold the servo at a neutral angle (mouth relaxed).
- Return immediately.
- Otherwise, check the current time (millis).
- If enough time has passed since the last step (based on the step interval):
- Update the last step time to the current time.
- Read the next angle from the pattern at the current index.
- Move the servo to that angle (open/close mouth).
- Increment the index to prepare for the next step.
- If not enough time has passed, do nothing this loop, so the mouth holds its current position.
Mode 0 – NORMAL
When in NORMAL mode:
- Turn the DC motor off.
- Move the mouth servo to a neutral “closed” or relaxed angle.
- Turn all LEDs off (both yellow and Ultra Instinct LEDs).
- Do not advance any mouth patterns.
Mode 1 – SUPER SAIYAN
When in Super Saiyan mode:
- Run the DC motor forward at a predefined Super Saiyan speed level.
- Turn on all yellow LEDs (left, right, center).
- Turn off all Ultra Instinct LEDs.
- Use the generic pattern player helper to:
- Step through the songoku mouth-angle pattern array.
- Advance the mouth position based on time intervals so that the mouth appears to sync to the “songoku” audio.
Mode 2 – ULTRA INSTINCT
When in Ultra Instinct mode:
- Run the DC motor forward at the Ultra Instinct speed (can be the same or different from Super Saiyan speed).
- Turn off all yellow LEDs.
- Create a “shimmer” effect with the Ultra Instinct LEDs:
- The center Ultra Instinct LED stays ON constantly.
- The left and right Ultra Instinct LEDs toggle alternately (one ON, the other OFF) every fixed time interval to create a flicker or shimmer.
- Use the generic pattern player helper to:
- Step through the SuperSaiyanPattern mouth-angle array.
- Advance the mouth position at its own timing interval to match the second audio track.
Main loop (runs repeatedly)
- Read the current 2-bit mode value from the Brain.
- If the mode has changed since the last loop:
- Reset the indices and time markers used by the pattern player for both patterns (so each mode’s mouth animation starts from the beginning when entered).
- Store the new mode as the lastMode.
- Based on the current mode:
- If mode is 0 → execute the NORMAL mode routine.
- If mode is 1 → execute the SUPER SAIYAN routine.
- If mode is 2 → execute the ULTRA INSTINCT routine.
- Otherwise, fall back to NORMAL as a safe default.
- Wait a very short delay (a few milliseconds) to avoid excessively tight looping while still keeping smooth animations.
Final Product
Lesson Learnt
A couple of lessons learned are how to correctly program an Arduino containing this many components. During the process of making the program, a couple of coding mistakes were made. For example, not setting the correct condition to trigger one of the phases and adjusting the sensor to match the environment. Also, another thing that was learned is how to successfully connect and synchronize two Arduinos. Given the high demand of digital pins, two Arduinos were used.
Some improvements that can be made for the future are creating a better mouth motion and implementing the slider crank mechanism. The current model only includes a servo that can switch between angles, which the mouth follows. This makes the mouth only open at one end. Changing the mechanism where both ends open and closed will increase the aesthetics of the animatrionic. Additionally, a slider crank mechanism that generates vertical motion to the background can be added to the improved version.