PCA9685 Servo Control on ESP32-CAM

I'm working with an ESP32-CAM and a PCA9685 to control a servo, but I'm facing an issue where the serial monitor shows no errors and indicates that the code should be working, but my servo is not moving at all.

Connections:

  • Using custom I2C pins on the ESP32-CAM:
    • SDA → GPIO 15
    • SCL → GPIO 14
  • The PCA9685 is properly powered via 5V for the servos.
  • Servo is connected to Channel 1 on the PCA9685 (signal to the second pin).

Code:
Should be no issues with the code as the output looks good.

  • I’m using the Adafruit_PWMServoDriver library and initialized the PCA9685 with pwm.begin() and set the PWM frequency to 50Hz.
  • The servo is connected to Channel 1, and I'm using pwm.setPWM(1, 0, pulse) to send the PWM signal.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// Define custom I2C pins for the ESP32-CAM
#define I2C_SDA 15
#define I2C_SCL 14

// Initialize the PCA9685 object
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// Servo parameters
#define SERVOMIN 150  // Minimum pulse length for 0 degrees
#define SERVOMAX 600  // Maximum pulse length for 180 degrees

void setup() {
  // Initialize Serial Monitor
  Serial.begin(115200);
  delay(2000); // Allow time for Serial Monitor to connect
  Serial.println("Starting...");

  // Initialize I2C with custom SDA and SCL pins
  if (Wire.begin(I2C_SDA, I2C_SCL)) {
    Serial.println("I2C initialized successfully.");
  } else {
    Serial.println("I2C initialization failed!");
    while (true); // Stop execution if I2C fails
  }

  // Initialize PCA9685
  pwm.begin();
  pwm.setPWMFreq(50); // Set frequency to 50 Hz for servos
  Serial.println("PCA9685 initialized.");
}

void loop() {
  Serial.println("Moving servo on channel 1...");

  // Sweep the servo on channel 1 from 0 to 180 degrees
  for (int pulse = SERVOMIN; pulse <= SERVOMAX; pulse++) {
    pwm.setPWM(1, 0, pulse); // Move servo on channel 1
    delay(10); // Delay for smooth motion
  }

  // Sweep the servo back from 180 to 0 degrees
  for (int pulse = SERVOMAX; pulse >= SERVOMIN; pulse--) {
    pwm.setPWM(1, 0, pulse);
    delay(10);
  }

  delay(1000); // Wait a bit before repeating
}

Serial Output:

  • The servo should be sweeping back and forth according to the code, but there’s no movement.

I’d appreciate any help. Thanks!!

Instead of this
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
I use this
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);

Can You decribe that in more detail? From what device is that 5 volt coming?

The most common mistake is to attempt to power the servo from the Arduino 5V output, which can actually damage the Arduino. Power the servo separately from a source capable of supplying 4.8 to 6V at 1 Ampere each for very small servos, 2.5 A each for large ones.

Suspected this but being Chirstmas the soft gloves were used.
Most of us helpers have a pretty good knowledge about insufficient powering being a usual cause for failure. Making a controller board conductor glow like a toster never ends well.....

Thanks, I tried that! However, still the same issue: the servos aren't moving. I think it may be a hardware issue but I'm not sure where since everything looks right.

I'm using an Agilent E3631A to supply power. Also, there is no PWM signal;I measured.

Unknown to me.
What is its data? How much current can it deliver?

What does that mean? Does the ESP provide PWM on that pin? Check the ESP dokumentation.

I’m using an ESP32-CAM with a PCA9685 to control a servo. The servo is not moving, and I’ve confirmed with a logic analyzer that there is no PWM signal being output on the PCA9685's Channel 1. The serial monitor indicates that the code is running successfully, but there’s no movement or signal.

Code:

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

#define I2C_SDA 15
#define I2C_SCL 14

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);

// Servo parameters
#define SERVOMIN 150  
#define SERVOMAX 600  

void setup() {
  Serial.begin(115200);
  delay(2000); 
  Serial.println("Starting...");

  // Initialize i2c
  if (Wire.begin(I2C_SDA, I2C_SCL)) {
    Serial.println("I2C initialized successfully.");
  } else {
    Serial.println("I2C initialization failed!");
    while (true);
  }

  // Initialize PCA9685
  pwm.begin();
  pwm.setPWMFreq(50); 
  Serial.println("PCA9685 initialized.");
}

void loop() {
  Serial.println("Moving servo on channel 1...");

  // Sweep the servo on channel 1 
  for (int pulse = SERVOMIN; pulse <= SERVOMAX; pulse++) {
    pwm.setPWM(0, 0, pulse); // Move servo on channel 1
    delay(10); // Delay for smooth motion
  }

  // Sweep the servo back 
  for (int pulse = SERVOMAX; pulse >= SERVOMIN; pulse--) {
    pwm.setPWM(0, 0, pulse);
    delay(10);
  }

  delay(1000); // Wait a bit before repeating
}

Connections:

  • ESP32-CAM:

    • SDA (Pin 15) → PCA9685 SDA
    • SCL (Pin 14) → PCA9685 SCL
    • 5V → PCA9685 VCC
    • GND → PCA9685 GND (shared with servo and power supply)
  • PCA9685 Power:

    • Green terminal block connected to an external 5V power supply.

Does anyone have any suggestions on how I can get the PWM signal + the servo motors to work? Thank you!

What address is returned for the PCA9685 when you run an I2C scanner sketch ?

0x40, the standard one

I have merged your cross-posts @sb12369 .

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting can result in a suspension from the forum.

In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

1 Like

How do you know the servo is connected to the correct channel? Schematics, board pin out, silk screened label? The board looks like a clone of the Adafruit PCA9685 board but it is hard to tell from a photo. On the Adafruit board, channel 0 is on the side of the board with the large electrolytic capacitor. If that fails, check all the pins for PWM.

When you used the i2c_scanner sketch, did you change the Wire.begin() call?