This tutorial is part of: Servomotory
Všetky videá súvisiace so servomotormi sú uvedené tu. Odkazy na ďalšie videá nájdete pod týmto článkom.
Arduino kód a video pre PCA9685 16-kanálový 12-bitový servoregulátor V1
V tomto návode si ukážeme, ako používať PCA9685 16-kanálový 12-bitový servoriadič od NXP Semiconductor. Tento modul vám umožňuje ovládať až 16 serv alebo stmievať pole LED diód s presnosťou pomocou pulznej šírkovej modulácie (PWM). Na konci tohto návodu budete mať funkčné zapojenie, ktoré dokáže ovládať viacero serv jednotlivo alebo súčasne.

Na objasnenie obsahu návodu vám odporúčam pozrieť si sprievodné video (vo videu o 00:00) pre vizuálnu ukážku procesu zapojenia a kódovania.
Vysvetlenie hardvéru
Modul PCA9685 je kompaktná doska, ktorá dokáže ovládať viacero serv cez I2C komunikáciu. Má 16 kanálov, čo vám umožňuje pripojiť až 16 serv, každé s vlastným riadiacim signálom. Modul pracuje s napájaním 5V a je navrhnutý na spracovanie PWM signálov, ktoré sú nevyhnutné na presné ovládanie polohy serv.
Doska obsahuje vyhradené piny pre napájanie (VCC), uzemnenie (GND) a komunikáciu (SDA a SCL). Pin SDA sa používa na prenos dát, zatiaľ čo pin SCL je hodinový signál, pričom oba sa pripájajú na analógové piny A4 a A5 na Arduine. Toto zapojenie zabezpečuje spoľahlivú komunikáciu medzi Arduinom a modulom PCA9685.
Podrobnosti z datasheetu
| Výrobca | NXP Semiconductor |
|---|---|
| Označenie súčiastky | PCA9685 |
| Logické/I-O napätie | 3,3 V až 5,5 V |
| Napájacie napätie | 2,3 V až 5,5 V |
| Výstupný prúd (na kanál) | max. 25 mA |
| Špičkový prúd (na kanál) | max. 100 mA |
| Odporúčaná PWM frekvencia | 24 Hz až 1,6 kHz |
| Vstupné logické úrovne | 0,3 V (nízka) / 0,7 V (vysoká) |
| Úbytok napätia / RDS(on) / saturácia | max. 0,5 V |
| Tepelné limity | -40 °C až 125 °C |
| Puzdro | HTSSOP-28 |
| Poznámky / varianty | 16-kanálový PWM regulátor |
- Zabezpečte 5V napájanie s dostatočným prúdom (odporúča sa 1A).
- Nenapájajte servá priamo z Arduina, aby ste predišli poškodeniu.
- Použite správne I2C piny: SDA na A4 a SCL na A5.
- Upravte hodnoty šírky impulzu podľa vašich konkrétnych serv.
- Skontrolujte zapojenie pre správnu polaritu: GND, VCC a signál.
- Zvážte chladenie pre aplikácie s vysokým prúdom.
Pokyny na zapojenie

Na zapojenie PCA9685 k Arduinu začnite pripojením napájania a uzemnenia. Pripojte pin VCC na PCA9685 k 5V výstupu na Arduine. Potom pripojte pin GND na PCA9685 ku GND na Arduine. Ďalej pripojte pin SDA na PCA9685 na pin A4 na Arduine a pin SCL na pin A5.
Pre servá pripojte signálny vodič k príslušnému kanálu na PCA9685 (napr. CH0 pre prvé servo), napájací vodič k samostatnému napájaciemu zdroju (pretože servá môžu vyžadovať väčší prúd, ako dokáže Arduino poskytnúť) a uzemňovací vodič k spoločnému uzemneniu zdieľanému s PCA9685. Uistite sa, že signálne, napájacie a uzemňovacie vodiče sú správne zarovnané, aby ste predišli poškodeniu komponentov.
Príklady kódu a vysvetlenie
V časti setup kódu inicializujeme modul PCA9685 pomocou pwm.begin() a nastavíme PWM frekvenciu pomocou pwm.setPWMFreq(60);. Toto nastaví komunikačnú frekvenciu pre servá.
void setup() {
Serial.begin(9600);
Serial.println("16 channel Servo test!");
pwm.begin();
pwm.setPWMFreq(60); // Analógové servá pracujú s ~60 Hz aktualizáciami
}
V rámci slučky ovládame servá nastavením PWM hodnôt zodpovedajúcich požadovaným uhlom. Funkcia angleToPulse(int ang) mapuje uhol na príslušnú šírku impulzu, čo je nevyhnutné pre presné polohovanie serva.
void loop() {
for( int angle =0; angle<181; angle +=20){
delay(500);
pwm.setPWM(0, 0, angleToPulse(angle) );
}
}
Nakoniec funkcia angleToPulse(int ang) prevádza uhol na šírku impulzu pomocou definovaných minimálnych a maximálnych dĺžok impulzov. To vám umožňuje jednoducho ovládať polohu serva na základe uhla, ktorý chcete dosiahnuť.
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;
}
Demonštrácia / Čo očakávať
Keď je všetko správne zapojené a kód je nahraný, mali by ste vidieť, ako sa servo pohybuje cez zadané uhly v krokoch po 20 stupňov. Ak sa servo nespráva podľa očakávania, skontrolujte zapojenie pre správne pripojenia a uistite sa, že napájací zdroj je dostatočný (vo videu o 12:30).
Časové značky videa
- 00:00 - Úvod k PCA9685
- 02:30 - Pokyny na zapojenie
- 05:00 - Vysvetlenie kódu
- 10:15 - Demonštrácia ovládania serva
- 12:30 - Riešenie bežných problémov
This tutorial is part of: Servomotory
- Ovládanie serva pomocou tlačidiel pomocou Arduina
- Control a Servo Motor with a Push Button: Move Servo and Return SPB-1
- Control a Servo Motor with a Push Button: Move Servo in One Direction SPB-2
- Controlling a Servo Motor with a Push Button: Move Servo While Button Is Pressed (SPB-3)
- Riadenie serva potenciometrom pomocou Arduina
- Ovládanie serva potenciometrom a LCD1602 pomocou Arduina
- Controlling Servo Motors Using an Infrared Remote with Arduino
- Ovládanie servomotora Arduino pomocou potenciometra
- Ovládanie pozície serva pomocou gest rúk pre Arduino
- Controlling Two or More Servos with Potentiometers Using an Arduino
- How to Control a 360° Servo with Three Push-Button Switches
- Ako používať kontinuálny 360° servomotor s Arduinom
- Zostavte Arduino servoprepínač s tlačidlom
/*
* Original source: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
* This is the Arduino code for the PCA9685 16-channel servo controller.
* Watch the video for details and demo: http://youtu.be/y8X9X10Tn1k
* get code and wiring diagram from http://robojax.com/RTJ27
* Watch the video for this code:
*
* Related Videos:
V5 video of PCA9685 32 Servo with ESP32 with WiFi: https://youtu.be/bvqfv-FrrLM
V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
V3 video of PCA9685: how to control 32 servo motors: https://youtu.be/6P21wG7N6t4
V2 Video of PCA9685: 3 different ways to control servo motors: https://youtu.be/bal2STaoQ1M
V1 Video introduction to PCA9685 to control 16 servos: https://youtu.be/y8X9X10Tn1k
* Written by Ahmad Shamshiri for Robojax Video channel: www.Robojax.com
* Date: December 16, 2017, in Ajax, Ontario, Canada
* Permission granted to share this code, given that this
* note is kept with the code.
* Disclaimer: This code is "AS IS" and for educational purposes only.
* This code has been downloaded from https://robojax.com
*
*/
/***************************************************
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, that's 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 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.begin(9600);
Serial.println("16 channel Servo test!");
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
//yield();
}
// the code inside loop() has been updated by Robojax
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 degrees and returns the pulse width.
* Also prints the value on the serial monitor.
* Written by Ahmad Shamshiri for Robojax, Robojax.com
*/
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;
}
/*
* Original source: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
* This is the Arduino code for the PCA9685 16-channel servo controller.
we have simple code with mapping PWM for simplicity explained in the video at 18:27
* Watch the video for details and demo: http://youtu.be/y8X9X10Tn1k
get this code and wiring from for this video: http://robojax.com/RJT27
* Written by Ahmad Nejrabi for Robojax Video channel: www.Robojax.com
* Date: December 15, 2017, in Ajax, Ontario, Canada
* Permission granted to share this code, given that this
* note is kept with the code.
* Disclaimer: This code is "AS IS" and for educational purposes only.
*
*/
/***************************************************
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, that's 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 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.begin(9600);
Serial.println("16 channel Servo test!");
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
//yield();
}
// the code inside loop() has been updated by Robojax
void loop() {
pwm.setPWM(0, 0, 125 );
delay(500);
pwm.setPWM(0, 0, 255 );
delay(500);
pwm.setPWM(0, 0, 450 );
delay(500);
pwm.setPWM(0, 0, 575 );
delay(500);
}
Things you might need
-
AmazonPurchase PCA9685 from Amazonamzn.to
-
eBayPurchase PCA9685 from eBayebay.us
-
AliExpressPurchase PCA9685 from AliExpresss.click.aliexpress.com
-
BanggoodPurchase PCA9685 from Bangoodbanggood.com
Resources & references
No resources yet.
Files📁
Arduino Libraries (zip)
-
Adafruit-PWM-Servo-Driver-Library-master
Adafruit-PWM-Servo-Driver-Library-master.zip0.02 MB
Other files
-
PCA9685 Datasheet
robojax_PCA9685.pdf0.39 MB -
PCA9685 Adafruit Library
robojax_PCA9685-Adafruit-Library.zip0.01 MB