Tim's PCA9685 Controller




Introduction: Tim's PCA9685 Controller

Many projects done with the Arduino, involve using a Servo.

If using only one or two servo, these can be controlled direct from an Arduino using a library and allocating pins to do this.

But for projects needing many servo to be controlled, the (lets give it its full name) PCA9685 16-channel, 12-bit PWM Fm+ I2C-bus LED Controller, may be the better choice.

The PCA9685 LED controller although designed to control LED's, can be configured to control Servo. (Data Sheet)

The PCA9685 communicates via I2C and has 64 possible address, this means that 64 of these devices can be daisy chained one after the other, each with 16 servo or LED attached to each. That totals 1024 number that can be controlled from one Arduino.

Now having a project that has many Servo to control, lets say a four legged robot. Each leg having two servo to control it. (we start simple, in theory my app can control 1024)

Setting up eight servo, finding the trim setting for each, determining there max. and min. positions, can be very time consuming.

Writing and re-writing code to see what happens, can be quite a pain.

So I decide to make an application to make things simple, and help find each Servo setting required and be able to run sequences (script) to test commands sent to the servo.

Step 1: Connections

The connections are quite simple.

The PCA9685 Breakout Board has six connection. (The same connections are repeated at the opposite end of the board, to make it easy for daisy chaining)

  1. GND Ground (negative power connection).
  2. OE Output Enable (making this Logic High, disables the PWM).
  3. SCL I2C Bus, Signal Clock Line.
  4. SDA I2C Bus, Signal Data Line.
  5. VCC +5 volt. (logic positive voltage).
  6. V+ +5 volt High Current Power Line.

Top right as shown in photo, there are six solder able links that can be soldered to change the address of the PCA9685, should more than one be connected. (these links are linked Binary, e.g. 000000, 000001, 000010, 000011 etc. It's actually it is 8 bit but you don't see the first or last bit)

A note about Power (No. 6)

If you are using power from the Arduino, don't have the Arduino power just by a USB, have at least 9 volt powering it on the power VIN. (if just powered of the USB, there will be a voltage drop of about 1.5v through the voltage regulator)

I recommend having a separate voltage supply for the PCA9685 V+ power (No. 6). 5 volt, a minimum of 2 Amps. (each servo under load, can peek over 1 Amp)

Also most breakout boards I have seen come with a capacitor. (if it hasn't got one, get one) I recommend the bigger the better. (I have seen 16v 10,000 uF Capacitors)

Mine currently has 1,000uF and struggles to keep 8 Servo in sync. (I have some 10,000 uF on order)

Power is what limits the number of Servo.

Arduino connections are:

  • A4 to SDA
  • A5 to SCL
  • 5V to VCC
  • GND to GND
  • D13 to OE
  • VIN to Battery (9 to 12 volt)
  • USB to Computer

Step 2: Firmware

Here is a link to my software: Tims_PCA_9685_Controller.zip

Inside the zip file will be the setup file for my Application.

Also there will be a folder called Arduino. In that folder will be three HEX files, and a zip for XLoader.

XLoader is a simple application for installing Hex files to an Arduino.

Just choose the HEX file to Upload:

Tims_PCA9685_16_LED_Servo_Controller_UNO.hex is for the Arduino UNO.

Tims_PCA9685_16_LED_Servo_Controller_NANO.hex is for the Arduino NANO.

Tims_PCA9685_16_LED_Servo_Controller_NANO_Old.hex is for the Arduino NANO with Old Bootloader.

Select which Arduino you are uploading to.

Select the port it is connected to.

Click Upload.

Once the firmware is uploaded to the Arduino, My application will be able to control Servo or LED attached to the PCA9685.

Step 3: Install the Aplication

In the zip file from the previous step, the will be a file called setup.exe

Run it and install the software.

I have tried to catch most errors in my code, but if you want to brake it, I'm sure it is possible.

Once installed run the application.

Obviously you will need you Arduino connected to the computer via USB, and the PCA9685 and Servo connected to the Arduino.

When the application starts most of the controls will not be active. all the controls work live, so the first thing to do is connect to the Arduino.

Top left is the connect button, chose the COM port the Arduino is connected, set the BAUD to 115200, then click connect. (some times when the Arduino is first powered on, handshaking is out of sync, click DC and connect again)

When connected feedback will appear in the Feedback window, and all the controls will become active.

Each slider represents the corresponding Servo connection on the PCA9685 breakout board. The sliders move the Servo, -90 or +90 degrees from the centre position.

Each slider has a Zero button, this centres the Servo.

Above the Zero button is a numeric box which you can entre -90 deg. to 90 deg.

Above the numeric box is the Pulse Width value the PCA9685 channel is set to. This is the value used when writing your code.

Lets say we are using the most common PCA9685 library,

#include <Adafruit_PWMServoDriver.h>
#define PCA9685_ADRRESS 0x40

Adafruit_PWMServoDriver PCA9685_01 = Adafruit_PWMServoDriver(PCA9685_ADRRESS);

PCA9685.setPWM(Servo_Number, 0, Value); // command to set value of server

Atop the sliders are two tabs, the other tab is for controlling LED, it has sliders similar to the Servo tab.

At the top left of the application is a drop down list of all the possible address used with the PCA9685, I put them in binary with the addition of the left bit which is always 1. (I haven't included the right hand bit RW to keep it simple) so that it matches the solder bridges on the breakout board.

Set this to the address of the board you want to control.

At the bottom left of the application is a button "settings and Info". Click this to set the trims of each Servo.

Chose the Servo to adjust from the list on the left, adjust the appropriate setting and click test for the setting you want to check. (the setting is changed when the test button is pressed)

If you have the newer Servo that don't have physical stops at there extreme positions (they can be manually turned continually), I recommend centring the arm/lever at the 307 value, then adjust the 90 deg. -90 deg. positions.

When the trims are done, movement of the sliders in the main application will calculate the correct position/value.

The three buttons in the "Move All Servos" section, just move all, they don't change any settings.

To the right of the "Settings and Info" button is the "Disable PWM x 16" button. This button Disable/Enables the PWM, that is, it turns on/off the signal to all pins.

The "Zero All" button is equivalent to pressing all the "Zero" buttons

Step 4: Script

The Script section is the fun part, this is where you can create sequences of Servo positions.

Get your project to do what you want it to do.

  • The Add Value button, adds the current slider settings.
  • The Add Delay button, adds a delay in milliseconds set in the box next to the button.
  • The Add Address button, adds a command switch to a different PCA9685, (change address to top left) it also used to change mode, Servo mode or LED mode.
  • The Run Script F button, runs the current script forward.
  • The Run Script R button, runs the current script in reverse.
  • The Loop checkbox makes the current script run over and over, when one of the Run Script buttons is pressed. To stop the loop un-check the checkbox.
  • The Clear Script button, does just that, it clears all script comands.
  • The Load button, loads a previously saved script.
  • The Save button, saves the current script.


I have not written any script checking into the application, the scrip must follow the following rules:

One line per command, values separated by a space.

  • Servo command starts with "S" followed by sixteen values, each value between 0 and 600
  • LED command starts with "L" followed by sixteen values, each value between 0 and 4095
  • Dely command starts with "D" followed by one value, between 0 and 10,000
  • Address command starts with "A" followed by one value and a word. The value between 0 and 64. The word being "Servo" or "LED".

The application can control Servo or LED, Don't put LED and Servo on the same Breakout Board, Servo and LED need different frequency to run correctly.

If you try to control servo with the LED settings, they may freak out, it wont harm them, but if they are installed in a project, you may not want them to move to some possition.

I have done video of some simple script.

Step 5: Epilogue

As instructions go on Instructables, most people expect to end up with a physical item at the end of an instruction.

I find there is no realistic category for software.

I suppose you could class it as a tool, even so, the instruction is not how to make the tool, it is how to use it.

Hopefully by having a tool like this, people will be able to make better projects with the Arduino using Servos or LED arrays.

Please excuse the in video of the project in action, I was using an ESP32-CAM breakout board with another application I made to view images from ESP32-CAM.


I have improved it.

Updates can be found here: Tims_PCA_9685_Controller

Arduino Contest 2020

Participated in the
Arduino Contest 2020

4 People Made This Project!


  • Tinkercad to Fusion 360 Challenge

    Tinkercad to Fusion 360 Challenge
  • Trash to Treasure Contest

    Trash to Treasure Contest
  • Origami Speed Challenge

    Origami Speed Challenge



Question 5 months ago

Hello Tim
I am a beginner in robotics
It is a wonderful project "Tims PCA 9685 Controller"
I managed everything works.
But is it possible to make the servos run slower?
Thank you


Answer 5 months ago

This software/firmware is primarily for saving time in creating sequences for the project you are building.
Normally the primary firmware in your project would add any delays during the movement of your servos.
Take a look at this video, I think it explains what you may be after.
AD How To Make Robots Move Smoothly | Arduino Tutorial - YouTube


1 year ago

I'm working with these for the first time and wondering if I can chain them with only 4 connections?
  • SDA
  • SCL
  • VCC
  • GND
I need to separate them with a small slip ring and was hoping a 4 conductor 3.5mm headphone jack would do the trick.
So far my testing has been unsuccessful and resulted in the damage of my Nano.


Reply 1 year ago

If you are running a lot of servos, you need a separate power supply connected to the V+ pin. 5 volt several amps. You need to check the data sheet for your servos.
(Amps for each multiplied by number of servo).
Also good sized capacitors if you have modules without capacitors.
I would say: The Nano power is only good for one servo.
(You may have just blown the protection diode on your Nano.)
This means you will need 5 wires, the GND and V+ should be a good AWG to handle the power.
Are you using something like this slipring?
This one say it say it take 2A 240v if you are passing more current I would double up the GND and V+ connections through it.
If you are limited by the number of connections, I suppose you could power the Vcc from the V+, I would put a resister in series to limit the power that could pass through.
To connect the wires from a slipring I just use 2.54mm header pins.
There is a picture of a connection in this blog I did. it may give you ideas in the project you are doing.
Hope this was of help.


Reply 1 year ago

Thanks for the reply.
Attached is a schematic of what I am attempting to do. The slip ring I used was similar to your link, but what I want to use is a Male to Female Phone Headphone Conversion Cord 3.5mm 4 Pole Audio Adapter.
Everything works if I use 6 wires between the two controllers, however if I can just carry SCL, SDA, GND, and Pwr then I can tap off my 5V stepdown converter bringing 5v to the second controller rather than passing VCC and V+ from 1 to 2.
However in my testing, that didn't seem to work.

Schematic_Capture.PNG3.5,, Jack Capture.PNG

Reply 1 year ago

What you have done in the circuit looks good to me.
I have made some small changes to the sketch that should work.

I see you are using soft serial for the Bluetooth (max speed will be 57600). I like to to use the the hard serial connected to the USB, Nano Pins 0 and 1. You just have to unplug the Bluetooth module while using the USB, but you can run the serial at 115200, also gives you 2 extra pins on the Nano.
See my blog here: Tim's Bluetooth Configuration.
It also shows a voltage converter for the data lines, I like to alter it both ways.

Do you have another free cable on your slipring to double up the GND?
Or if you are happy with the current the slipring can handle, I suppose you could loose one of the 5v if you need it for something else.


Reply 1 year ago

Thanks, I'll investigate the Bluetooth alternative. Looking at your modifications it still looks like I would need a 5 wire slip ring, if that is the case then the 3.5 mm jack will not work. I am curious as to why the 5v is needed to be tapped on both sides of the slip ring?


Reply 1 year ago

I was double up the wires so more current can pass through the slip ring.
4 wires are the minimum. See picture.
Your 3.5mm jack will be ok.
The slip ring may not handle the current. I don't know how many wires your slipring has?
I was just going on some experience I had in one of my projects, I had to use two wires of the slipring for the positive supply and two wires of the slipring for the GND.
Using only one wire for each gave too much resistance and I had a voltage drop through the slipring.
It's just something I thought I would mention.


Question 1 year ago

A really REALLY great project here. Would be ideal for use in robotics projects! Is there currently a way to upload the routines into the arduino so they can be run without the USB connected to the PC?


Answer 1 year ago

If you read my blog here: Tim's XY Plotter Bluetooth it gives you information on how to configure a Bluetooth module.
And if your computer has Bluetooth. (can use a Bluetooth dongle)
You will be able to connect remotely.

The Bluetooth module needs to be set to 115200, and connected to the TX and RX pins of the Arduino (D0 and D1) and don't forget about the 3.3volt data lines.

Here is an example using Bluetooth:


Reply 1 year ago

Beautiful - thanks for the additional information and video!.

If you ever figure out how to compile the routines as an unloadable code, and speed control - you'd be on to a top notch winner, vey limited commercially available out there, closest I've seen with PC software is an on an Indian site and the pololu units are expensive for playing with.

Keep up the excellent work!


1 year ago on Step 5

Sorry for the late response here is a video of tims program controlling my robot, https://youtu.be/KgP5XPwpFd0 great program i will definitely be using this with future projects.


Reply 1 year ago

OMG you have made my day.
That is awesome.
Thank you for showing.


Reply 1 year ago

No problem, and thank you for this great program.


Question 1 year ago

The file won't upload to my arduino nano, it get stuck uploading in the hex file uploader


Answer 1 year ago

I did two hex files for the Nano, one with settings for the old bootloader and one for the new bootloader.
Do both not work?
Which Nano do you have?


Reply 1 year ago

Ok got it fixed i hat to raise baud rate to 115200 to upload hex file from xloader connected to servo sequencer and everything is working again. Thank again so much for this app. Ill be waiting on future updates.


Reply 1 year ago

I am glad you managed to get it sorted out.


Reply 1 year ago

Thanks, your programs works 100% i figured out it was the pins to my pca9685.


Reply 1 year ago

Please take a picture of your success and place it in I mad it.