Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

ESP32-Controlled 32-Channel Servo Motor Driver with Dual PCA9685 Modules

View and Edit Project In Cirkit DesignerImage of ESP32-Controlled 32-Channel Servo Motor Driver with Dual PCA9685 Modules

Circuit Documentation

Summary of the Circuit

The circuit is designed to control multiple MG90S micro servo motors using two Adafruit PCA9685 PWM Servo Breakouts, which are interfaced with an ESP32 microcontroller. The ESP32 is responsible for generating PWM signals through the PCA9685 breakout boards to control the position of the servo motors. The circuit is powered by a 5V battery connected to the PCA9685 boards and a 3.3V battery connected to the ESP32. The I2C communication protocol is used between the ESP32 and the PCA9685 boards to send control commands.

Component List

Micro Servo Motors

PWM Servo Breakout Boards

Microcontroller

Power Sources

Wiring Details

MG90S Micro Servo Motors

Each MG90S servo motor is connected to the Adafruit PCA9685 PWM Servo Breakout board as follows:

Adafruit PCA9685 PWM Servo Breakout Boards

The two PCA9685 boards are daisy-chained for I2C communication and share a common power supply:

ESP32 Microcontroller

Power Sources

Documented Code

The following code is written for the ESP32 microcontroller to control the MG90S servo motors via the Adafruit PCA9685 PWM Servo Breakout boards.

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

Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);

#define SERVOMIN  125
#define SERVOMAX  575

int servoNumber = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("32 channel Servo test!");

  board1.begin();
  board2.begin();  
  board1.setPWMFreq(60);
  board2.setPWMFreq(60);
}

void loop() {
  for(int angle = 0; angle < 181; angle += 10) {
    for(int i = 0; i < 16; i++) {
      board2.setPWM(i, 0, angleToPulse(angle));
      board1.setPWM(i, 0, angleToPulse(angle));
    }
  }
  delay(100);
}

int angleToPulse(int ang) {
  int pulse = map(ang, 0, 180, SERVOMIN, SERVOMAX);
  Serial.print("Angle: "); Serial.print(ang);
  Serial.print(" pulse: "); Serial.println(pulse);
  return pulse;
}

This code initializes two PCA9685 boards and sets their PWM frequency to 60 Hz, which is suitable for analog servos. It then enters a loop where it increments the angle of the servos from 0 to 180 degrees in steps of 10 degrees. The angleToPulse function converts the angle to a corresponding pulse width modulation value, which is then used to set the PWM for each servo motor on both PCA9685 boards.