Control 16 Servo motor using PCA9685 Module and Arduino V2 Sketch #1 ONE-By-ONE

Project Video
Project Details

In this video we learn how to control 16 Sermo motors using PCA9685 PWM conroller with I2C

Project Code

 * Original sourse:
 * This is the Arduino code PAC6985 16 channel servo controller
 * watch the video for details (V1) and demo
 *  This code is #1 for V2 Video Watch the video :
 *  I have got 3 codes as follow:
   #1-Arduino Code to run one by one all servos from 0 to 180°   
   #2-Arduino Code to control specific servos with specific angle
   #3-Arduino Code to run 2 or all servos at together
 * Written/updated by Ahmad Shamshiri for Robojax Video channel
 * Date: Dec 16, 2017, in Ajax, Ontario, Canada

 * Watch video for this code: 
 * Related Videos
V5 video of PCA9685 32 Servo with ESP32 with WiFi
V4 video of PCA9685 32 Servo with ESP32 (no WiFi):
V3 video of PCA9685 how to control 32 Servo motors
V2 Video of PCA9685 3 different ways to control Servo motors:
V1 Video introduction to PCA9685 to control 16 Servo

 * Disclaimer: this code is "AS IS" and for educational purpose only.
 * this code has been downloaded from
 * Get this code and other Arduino codes from
Learn Arduino step by step in structured course with all material, wiring diagram and library
all in once place. Purchase My course on

Get early access to my videos via Patreon and have  your name mentioned at end of very 
videos I publish on YouTube here: (watch until end of this video to list of my Patrons)

or make donation using PayPal

 *  * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.* 
 * This code has been download from
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .

  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!

  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


// 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!
// Watch video V1 to understand the two lines below:
#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // 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


// the code inside loop() has been updated by Robojax
void loop() {

//watch video for details:
for(int i=0; i<16; i++)
    for( int angle =0; angle<181; angle +=10){
        pwm.setPWM(i, 0, angleToPulse(angle) );
        // see YouTube video for details (robojax)
  // robojax PCA9865 16 channel Servo control
  delay(1000);// wait for 1 second

/* angleToPulse(int ang)
 * @brief gets angle in degree and returns the pulse width
 * @param "ang" is integer represending angle from 0 to 180
 * @return returns integer pulse width
 * Usage to use 65 degree: angleToPulse(65);
 * Written by Ahmad Shamshiri on Sep 17, 2019. 
 * in Ajax, Ontario, Canada
int angleToPulse(int ang){
   int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max 
   Serial.print("Angle: ");Serial.print(ang);
   Serial.print(" pulse: ");Serial.println(pulse);
   return pulse;

If you found this Arduino course helpful, please support me so I can continue creating content like this. support me via PayPal