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.
49.35 AED 49.35 AED Tax Included
49.35 AED Tax Included

Not Available For Sale

This combination does not exist.

Servo Driver

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
}