Googly Eyes
An Arduino-controlled animatronic head with two servo-driven eyes, eyelids, a Person Sensor, and 3D-printed mechanical parts.
What this project is
Googly Eyes is a small animatronic head built around two gaze servos, four eyelid servos, a Useful Sensors Person Sensor, and a 3D-printed mechanical assembly. The repository contains the active Arduino sketch, the Person Sensor protocol header, earlier controller experiments, and an archive of CAD files.
The project archive also contains photographs of an assembled mechanism. The exact board model, servo model, power arrangement, and final physical channel mapping still need to be recorded before this becomes a fully reproducible hardware build.
System overview
Useful Sensors Person Sensor
| I2C, address 0x62
v
Arduino sketch -> PCA9685-compatible PWM driver -> six servos
^ |
| +-> pan, tilt, and four eyelids
|
button on pin 2
The active firmware lives at firmware/googly_eyes/googly_eyes.ino. It uses Wire.h, Adafruit_PWMServoDriver.h, and person_sensor.h.
Firmware behavior
The sketch samples the Person Sensor, selects the largest detected face, and maps the face center into the configured servo range. Sensor coordinates are clamped to 0..255 before mapping to pulses between 150 and 600.
When the sensor has no face to report, the sketch holds the last gaze position instead of writing a new target. This gives the mechanism a defined failure behavior while the sensor is blocked, disconnected, or between detections.
The eyelids have two paths:
- automatic blinking every
2000 ms, subject to the sketch's random blink check; - a momentary eye-close button on pin
2, read as active-low withINPUT_PULLUP.
The PCA9685 driver is configured for 50 Hz, and serial diagnostics use 9600 baud. The six named channels are:
- pan: channel
0; - tilt: channel
1; - upper-left lid: channel
2; - lower-left lid: channel
3; - upper-right lid: channel
4; - lower-right lid: channel
5.
The code decisions that matter
The current sketch is deliberately small. Its useful safety and behavior boundaries are visible in the code rather than hidden behind a control framework:
- face processing is limited to
PERSON_SENSOR_MAX_FACES_COUNT; - the largest face is selected instead of letting the last loop iteration win;
- sensor coordinates and mapped pulses are clamped;
- gaze stays at the last valid position when no face is detected;
- pan, tilt, and eyelid channels have names instead of unexplained numeric literals;
- holding the button closes the eyelids, and releasing it restores the last gaze position.
These are firmware-level guarantees. They do not establish that the physical servos move in the intended direction or that the configured pulse range is safe for the assembled mechanism.
CAD and mechanical archive
cad/archive/ preserves the recovered print files rather than pretending that the repository contains one clean final CAD release. It currently contains:
- 30 3MF files;
- 5 STL files;
- 1 SVG file.
The filenames show several iterations and names associated with different contributors. The exact files used in the photographed assembly, final-part ownership, and mechanical dimensions remain open questions.
Verification
The active sketch has an ad-hoc host-side compile probe using small local stubs for Arduino, Wire, and the Adafruit PWM driver interfaces. That probe exercises the pulse bounds, largest-face selection, and setup initialization.
This is not a canonical Arduino build. arduino-cli is not installed in the current environment, and the following still require the real hardware and board toolchain:
- compilation with the intended Arduino board and actual Adafruit library;
- PCA9685 communication and oscillator behavior;
- servo direction, mechanical travel, and safe pulse limits;
- power delivery and common-ground wiring;
- button wiring and Person Sensor behavior under real conditions.
What is not in this repository
The project export describes Python voice recognition using Vosk and Whisper, along with broader assistant behavior. No corresponding Python source or voice-control implementation is present in this repository, so those features are not presented here as implemented.
Files and references
- Repository: View the project on GitHub
- Active firmware:
firmware/googly_eyes/googly_eyes.ino - Person Sensor header:
firmware/googly_eyes/person_sensor.h - Earlier firmware experiments:
firmware/archive/ - CAD archive:
cad/archive/ - Hardware notes:
docs/hardware.md - Wiring record:
docs/wiring.md
The next useful evidence is not another paragraph of speculative design. It is a board and component inventory, an annotated wiring record, measured servo limits, and a short bench test showing the actual gaze and eyelid motion.