Servo Motor PWM 16 Channel 12Bit Driver Shield PCA9685

AED 49.35



The PCA9685 is an I2C-bus controlled 16-channel controller shied, This PWM Servo Driver uses the chip PCA9685 for control. With only 2 pins, Each output has its own 12-bit resolution (4096 steps) fixed frequency individual PWM controller that operates at a programmable frequency from a typical of 24Hz to 1526Hz with a duty cycle that is adjustable from 0 % to 100 % to allow the Output to be set to a needed value. All outputs are set to the same PWM frequency.
It can drive 16 servos, which greatly reduces the I/O occupation. In addition, you can connect up to 62 driver boards in a cascading way, thus amazingly driving 992 servos in total.


  •  I2C Protocol Interface.
  • Any MCU with 5V 3.3V can be used.
  • Frequency: 24Hz to 1526Hz 
  • PWM provides 16 channels
  • Supply Voltage: 2.3 V to 5.5 V
  • Temperature: -40 °C to +85 °C
  • Resolution: 12 bit

Important Files:

Arduino Sample code for the PCA9685 Servo PWM 16 Channel 12Bit Driver Shield 


// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVOMIN  150 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // This is the 'maximum' pulse length count (out of 4096)
#define USMIN  600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX  2400 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

// our servo # counter
uint8_t servonum = 0;

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


  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates


// You can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. It's not precise!
void setServoPulse(uint8_t n, double pulse) {
  double pulselength;
  pulselength = 1000000;   // 1,000,000 us per second
  pulselength /= SERVO_FREQ;   // Analog servos run at ~60 Hz updates
  Serial.print(pulselength); Serial.println(" us per period"); 
  pulselength /= 4096;  // 12 bits of resolution
  Serial.print(pulselength); Serial.println(" us per bit"); 
  pulse *= 1000000;  // convert input seconds to us
  pulse /= pulselength;
  pwm.setPWM(n, 0, pulse);

void loop() {
  // Drive each servo one at a time using setPWM()
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    pwm.setPWM(servonum, 0, pulselen);

  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    pwm.setPWM(servonum, 0, pulselen);


  // Drive each servo one at a time using writeMicroseconds(), it's not precise due to calculation rounding!
  // The writeMicroseconds() function is used to mimic the Arduino Servo library writeMicroseconds() behavior. 
  for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
    pwm.writeMicroseconds(servonum, microsec);

  for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
    pwm.writeMicroseconds(servonum, microsec);


  if (servonum > 7) servonum = 0; // Testing the first 8 servo channels