top of page

EYEMECH 3.2 – Mega with PCA9685 Servo Controller

Updated: 3 days ago

For robotics and animatronics enthusiasts, Will Cogley’s EYEMECH is a famous open design of realistic animatronic eyes.


This post showcases an adaptation of the EYEMECH 3.2 control code for ESP32, using the PCA9685 servo controller to drive multiple servos smoothly via I²C.

ree

Project Overview

  • Platform: ESP32 (MicroPython)

  • Servo Driver: PCA9685 (16‑channel PWM over I²C)

  • Servos Controlled: 6 (Left/Right, Up/Down, 4 eyelids)

  • Modes:

    • Calibration mode – eyes centered, eyelids closed

    • Auto mode – random blinks and movements

    • Controller mode – joystick/potentiometer control with eyelid following

The system replicates natural eye movements while allowing manual controller input, making it a strong foundation for props, robots, or interactive art pieces.


⚙️ How It Works

  1. PCA9685 Driver (pca9685.py)

    • Initializes the PWM chip over I²C

    • Provides functions to set PWM frequency and servo angles

    • Maps 0–180° angles into pulse widths (servo‑friendly 50 Hz PWM range)

  2. Main Control Script (main.py)

    • Imports and uses the PCA9685 class

    • Defines servo limits for realistic eyelid motion (some inverted)

    • Adds calibration, neutral, blink, and coordinated movement functions

    • Supports potentiometer/joystick control via ADC inputs on ESP32

    • Includes random movement logic for lifelike animation in auto mode


📂 Code Files

Below are the full original source codes as provided.


Simplied Arduino Code with Wire Library


#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>


Arduino Code with  I²C Communication




#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Create the servo driver instance
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); 

// Define servo pulse limits
#define SERVOMIN  150  // Minimum pulse length count
#define SERVOMAX  600  // Maximum pulse length count

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel servo test!");

  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz

  delay(10);
}

void loop() {
  // Sweep all servos one by one
  for (uint8_t servoNum = 0; servoNum < 4; servoNum++) { // Example: 4 servos
    for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
      pwm.setPWM(servoNum, 0, pulselen);
    }
    delay(500);
    for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
      pwm.setPWM(servoNum, 0, pulselen);
    }
    delay(500);
  }
}

Comments


bottom of page