Details of the module with chip PCA9685
Servo Pins:
- PWM: Pulse Width Modulation
- V+: Positive
- GND: Ground
PCA9685 Power Pins
- VCC - This is the logic power pin, should be 3 - 5V at max, get the power from arduino.
- GND: This is the power and signal ground pin, must be connected
-
V+: This is the power pin that will supply distributed power to the servos. You can also provide
power from the 2-pin terminal block at the top of the board. but if you mess up and connect VCC to
V+ you could damage your board.
5V- high current can be supplied from the arduino but if you are using multiple servos you are required to supply DC from an external source
PCA9685 Control Pins
- SDA: 12C data pin, SDL is connected to Arduino Analog In [pin4] [A4]
- SCL: 12C clock pin, SCL is connected to Arduino Analog In [pin5] [A5]
Connecting to the Arduino
-
Classic Arduino Wiring:
- +5v -> VCC (this is power for the BREAKOUT only, NOT the servo power!)
- GND -> GND
- Analog 4 -> SDA
- Analog 5 -> SCL
-
R3 and later Arduino wiring (Uno, Mega & Leonardo):
- +5v -> VCC (this is power for the BREAKOUT only, NOT the servo power!)
- GND -> GND
- SDA -> SDA
- SCL -> SCL
Arduino and Power Supply
Circuit Diagram
Servo Motor Setup
-
Servo Driver Library Download [for PWM]
To begin reading sensor data, we have to install the Adafruit_PWMServo library
-
Servo Setup Code
Finding Maximum and Minimum Pulse for Servo
#include < Wire.h > #include < Adafruit_PWMServoDriver.h > Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); void setup() { Serial.begin(9600); Serial.println("16 channel Servo test"); pwm.begin(); pwm.setPWMFreq(60); yield(); } void loop() { pwm.set(0, 0, 125); delay(500); }Servo Setup
#include <Wire.h> #include <Adafruit_PWMServoDriver.h> Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); /* Depending upon the servo motor we have to set the pulse width modulation max and min values. We need this 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 that we have */ // this is the 'minimum' pulse length count (out of 4096) #define SERVOMIN 125 // this is the 'maximum' pulse length count (out of 4096) #define SERVOMAX 575 // our servo # counter uint8_t servonum = 0; void setup() { // set up serial monitor to display the test Serial.begin(9600); Serial.println("16 channel Servo test"); // initialize the pulse width modulation // helps begin the communication with the board pwm.begin(); // Analog servos run at ~60 Hz updates pwm.setPWMFreq(60); // yield() makes sure that other processes that take longer are finished before the next process yield(); } void loop() { // Drive each servo one at a time Serial.println(servonum); for(unit16_t pulselen = SERVOMIN; pulselen < SERVOMAX; purlselen++){ pwm.setPWM(servonum, 0, pulselen) } delay(500); for(unit16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--){ pwm.setPWM(servonum, 0, pulselen) } servonum++; /* the number 15 represents the number of the servo motors that are connected to the PCA9685, change the number depending upon the number of servo motors that we want to control. */ if(servonum > 15) servonum = 0; }Pulse to Angle
#include < Wire.h > #include < Adafruit_PWMServoDriver.h > Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // this is the 'minimum' pulse length count (out of 4096) #define SERVOMIN 125 // this is the 'maximum' pulse length count (out of 4096) #define SERVOMAX 575 void setup() { Serial.begin(9600); Serial.println("16 channel Servo test"); pwm.begin(); pwm.setPWMFreq(60); yield(); } void loop() { int angle = 180; int pulse = map(angle, 0, 180, SERVOMIN, SERVOMAX); Serial.print("Angle: ");Serial.print(angle); Serial.print(" pulse: ");Serial.println(pulse); pwm.setPWM(0, 0, pulse) }Code to test the the servos with angle instead of pulse width:
#include < Wire.h & gt; #include < Adafruit_PWMServoDriver.h & gt; Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); #define SERVOMIN 125 #define SERVOMAX 575 // our servo # counter uint8_t servonum = 0; void setup() { Serial.begin(9600); Serial.println("16 channel Servo test!"); pwm.begin(); pwm.setPWMFreq(60); yield(); } void loop() { for (int angle = 0; angle < 181; angle += 20) { delay(500); pwm.setPWM(0, 0, angleToPulse(angle)); } delay(1000); } /* * angleToPulse(int ang) * gets angle in degree and returns the pulse width * also prints the value on seial monitor * written by Ahmad Nejrabi for Robojax, Robojax.com */ int angleToPulse(int ang) { int pulse = map(ang, 0, 180, SERVOMIN, SERVOMAX); Serial.print("Angle: "); Serial.print(ang); Serial.print(" pulse: "); Serial.println(pulse); return pulse; }
MG955 Servo Motor control using PCA9685
MG955 Servo Motor Control using PCA9685