Skip to Content

Servo Motor PWM 16 Channel 12Bit Driver Shield PCA9685

The PCA9685 is an I2C-controlled 16-channel PWM controller shield, using the PCA9685 chip for precise servo control. It requires only two pins for communication and provides each output with a 12-bit resolution (4096 steps). The PWM frequency is programmable from 24 Hz up to 1526 Hz, with a duty cycle adjustable from 0% to 100%. All channels share the same PWM frequency. This shield can drive up to 16 servos simultaneously, greatly reducing microcontroller I/O usage. Moreover, up to 62 driver boards can be cascaded, enabling control of up to 992 servos in total.
Servo Driver
49.35 AED 49.35 AED (Tax included)

Terms and Conditions
30-day money-back guarantee
Shipping: 2-3 Business Days

 

Specifications:

  • I2C Protocol Interface
  • Compatible with 3.3V and 5V MCUs
  • Frequency range: 24 Hz to 1526 Hz
  • 16 PWM output channels
  • Supply Voltage: 2.3 V to 5.5 V
  • Operating Temperature: -40 °C to +85 °C
  • Resolution: 12-bit (4096 steps)

Important Files:

Arduino Sample Code:

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

// Use default I2C address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVOMIN 150  // Min pulse length out of 4096
#define SERVOMAX 600  // Max pulse length out of 4096
#define USMIN 600     // Min microsecond length
#define USMAX 2400    // Max microsecond length
#define SERVO_FREQ 50 // Typical servo frequency ~50 Hz

uint8_t servonum = 0;

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

  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz
  delay(10);
}

// Optional function to set pulse length in seconds (not precise)
void setServoPulse(uint8_t n, double pulse) {
  double pulselength = 1000000;  // 1,000,000 us per second
  pulselength /= SERVO_FREQ;     // us per period
  Serial.print(pulselength);
  Serial.println(" us per period");
  pulselength /= 4096;           // us per bit
  Serial.print(pulselength);
  Serial.println(" us per bit");
  pulse *= 1000000;              // convert to us
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}

void loop() {
  // Sweep each servo from min to max and back using setPWM()
  Serial.println(servonum);
  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);

  // Sweep servo using writeMicroseconds() (less precise)
  for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
    pwm.writeMicroseconds(servonum, microsec);
  }
  delay(500);
  for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
    pwm.writeMicroseconds(servonum, microsec);
  }
  delay(500);

  servonum++;
  if (servonum > 7) servonum = 0;  // Cycle through first 8 servos
}