Unpacking the Geekcreit PCA9685 I2C Shield 16 Servos + 2 DC motors for Arduino or ESPDuino (ESP8266)

Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

The Arduino Uno or ESP8266 boards do not deliver enough power to power the 6 robotic arm servo motors discussed earlier in this article. So you have to buy a daughter board with an external power supply that can deliver enough power. There are many boards based on the PCA9685 circuit that can drive up to 16 servo motors via the I2C bus.


I think it is more interesting to be able to control a robotic arm in WiFi. For example, we can develop applications with a WEB interface to control the robotic arm from a tablet or smartphone. You can also take advantage of the integrated accelerometer to control the arm following the movement of his phone. I suggest you to test the PCA9685 16-channel PWM expansion board and 2 DC motors from Doit.am (former Geekcreit). It is compatible with the Arduino Uno connector. As we use the i2c bus to drive the servo-motors, we can also use ESPDuino boards (or Wemos D1 R2), any other clone based ESP8266… and why not a Raspberry Pi!

Unpacking and PCA9685 board Features, 16 Servos + 2 DC Motors (Doit/Geekcreit)

The PCA9685 Must be in the form of an expansion board compatible with the Arduino Uno. It is built around a PCA9685 circuit quite well documented There are several libraries for Arduino and adaptations for modules ESP8266. The advantage of the I2C bus is that it can control up to 16 servomotors using the I2C bus. The U2C bus uses only 2 wires which is perfect for ESP8266 based projects. This board is compatible with the Arduino connectors. She comes to pile on the latter. It can also be used on Arduino clones built around the ESP8266 module. This is the case for example ESPDuino board or the Wemos d1 R2 that I used here. This board costs about $12 / 10€. If you do not need to drive engines, there are also more compact boards for less than $3.5 / 3€.

doit.am geekcreit 16 channel servo motor i2c pca9685pw esp8266 espduino 2

The ESP8266 and the Arduino Uno share the same pins for the I2C bus. GPIO5 for SCL and GPIO4 for SDA. The code will be exactly the same. Servomotors and both motors can use the power supply of the Arduino or Espduino board. If the power delivered is insufficient, a terminal block is used to power the motors and servomotors separately. You can use a DC IN adapter equipped with a terminal block to power the board for example The development bard can be powered between 6 and 18V. A selector allows you to choose between the external power supply and the 5V power supply of the Arduino / ESP8266. The original connectors of the Arduino / Espduino board are deported inside the board. It will suffice to weld a male or female header if you need to drive other actuators or recover sensor measurements (color sensor, proximity…).

doit.am geekcreit 16 channel servo motor i2c pca9685pw esp8266 espduino top

Here are the other features of the board. Sorry, Must not document his boards (or at least, it’s very difficult to find documentation in English!). I had to reconstruct the characteristics by cutting the information and groping!

  • Arduino Uno compatible connector, ESPDuinoWemos d1 R2
  • PCA9685PW circuit (technical documentation) on I2C bus to control up to 16 servos or LEDs, input 2.3V-5.5V, 1MHz cutout, 5.5V / 25mA output, TSSOP-28 box
  • L293DD circuit for controlling 2 DC motors up to 18V.
  • 1x external power terminal block 6 to 18V for motors
  • 1x external power supply terminal block 6 to 18V for servomotors
  • 2x power supply terminals for DC motors (A and B)
  • Power selectors
  • VM / VIN shunted to power the motors from the external power supply
  • VS / 5V shunted to power servos from external power supply
  • 1x orange LED to signal the operation of the PCA9685PW circuit
  • RESET and POWER buttons (?)

Test with Adafruit 12-bit PWM / Servo Driver library for Aduino Uno

This board is built around the same circuit as the Adafruit board, it is very well supported by the manufacturer’s library. Like all Adafruit libraries, it is very easy to install from the Arduino IDE library manager. Do a search with the keywords adafruit PWM to find it.

The library comes with two examples. Here is the example that allows to control the first servomotor connected to the board.

  This is an example for our Adafruit 16-channel PWM & Servo driver
  Servo test - this will drive 16 servos, one after the other

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815

  These displays use I2C to communicate, 2 pins are required to  
  interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution

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

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#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)

// our servo # counter
uint8_t servonum = 0;

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

  pwm.setPWMFreq(60);  // Analog servos run at ~60 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. its not precise!
void setServoPulse(uint8_t n, double pulse) {
  double pulselength;
  pulselength = 1000000;   // 1,000,000 us per second
  pulselength /= 60;   // 60 Hz
  Serial.print(pulselength); Serial.println(" us per period"); 
  pulselength /= 4096;  // 12 bits of resolution
  Serial.print(pulselength); Serial.println(" us per bit"); 
  pulse *= 1000;
  pulse /= pulselength;
  pwm.setPWM(n, 0, pulse);

void loop() {
  // Drive each servo one at a time
  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);

  servonum ++;
  if (servonum > 15) servonum = 0;

The Adafruit PCA9685 library is not compatible with ESP8266. It is marked as tested and functional on GitHub but I encountered this compilation error on the Wemos d1:

/Users/christophe/Documents/Arduino/libraries/Adafruit_PWM_Servo_Driver_Library/Adafruit_PWMServoDriver.cpp:25:15: error: 'Wire1' was not declared in this scope
  #define WIRE Wire1

On Arduino Uno, the library is perfectly managed. I have not been further because the goal is to use an ESP8266-based board in the next tutorials.

Test with an ESPDuino / Wemos d1 R2 (Sumotoy library)

If the Adafruit library does not work at home too, you can use the library developed by Sumotoy. You can retrieve it on GitHub here. Start by downloading the deposit. Unzip the ZIP file and copy the uncompressed folder to the Library directory of the Arduino IDE. It is (most of the time) in your Documents folder. Restart the Arduino IDE to add the examples to the menu. The library comes with 4 examples that can drive PWM servos.

sumotoy drivers servo led pca9685PW

The library is used like any other. A servo object is created which is attached to the I2C bus. By default, the SCL pin is on the GPIO5 (D1), the SDA pin on the GPIO4 (D2). The PCA9685 is by default at 0x40, which is also the case for the Geekcreit / Doit development board. Then, we have several methods to manipulate the servomotors:

  • setServoType(), we pass the STANDARD constant for servos from 0 to 190 °. CONTINUOUS (or nothing) for a 360 ° continuous rotation servomotor
  • setPWMFreq(float freq), to adjust the PWM frequency. Adjust the setting according to the manufacturer’s specifications if needed
  • moveServo(uint8_t servo, uint8_t pos) moves the servo to the specified angular position.
  • Read or modify the characteristics of each servomotor
    • getServoMin, getServoMax
    • setServoMin, setServoMax

Create a new sketch and paste the following code. It just sweeps from 0 to 180°. The position changes every 200ms. When it reaches 180°, it returns to the original position.

  Test PCA9685 driver Doit.am 16 servos I2C shield
  Compatible Arduino Uno / Espduino / ESP8266

#include <Wire.h>
#include <servo_PCA9685.h>

#define MAX_SERVOS 16

 * ESP8266 I2C - pins
 * SDA: 4 - D2
 * SCL: 5 - D1

servo_PCA9685 servo = servo_PCA9685();

uint8_t servonum = 0;

void setup() {
#if defined(ESP8266)
  Serial.println("\nservo start");
int angle = 0;

void loop() {
  if ( angle == 180 ) {
    angle = 0;
  Serial.println("Move to "+angle);

MicroPython test

The PCA9685 is also very well supported in MicroPython. There is a library developed by Adafruit and McHobby. I tested both without success with my coard. As soon as I execute the code, the board disconnects from the USB port without the servomotor moving. If anyone has any information, I’m interested.


That’s it, everything is in place to drive the robotic arm. We now have a board to control each joint of the robotic arm separately. By using a Espduino development board, we can even control the arm in WiFi from a Web App or a browser.

Click to rate this post!
[Total: 0 Average: 0]

Are you having a problem with this topic?

Maybe someone has already found the solution, visit the forum before asking your question
Ask your question

Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

Did you like this project ? Don't miss any more projects by subscribing to our weekly newsletter!

  1. i have one of these. im new to arduino. i cant figure out how to reverse the dc motors. servos work. dc speed works and one direction.

    Leave a Reply

    DIY Projects
    %d bloggers like this: