Search Code

Arduino kód a video pre PCA9685 16-kanálový 12-bitový servoregulátor V1

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.

PCA9685 module-0

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ýrobcaNXP Semiconductor
Označenie súčiastkyPCA9685
Logické/I-O napätie3,3 V až 5,5 V
Napájacie napätie2,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 frekvencia24 Hz až 1,6 kHz
Vstupné logické úrovne0,3 V (nízka) / 0,7 V (vysoká)
Úbytok napätia / RDS(on) / saturáciamax. 0,5 V
Tepelné limity-40 °C až 125 °C
PuzdroHTSSOP-28
Poznámky / varianty16-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

Arduino wiring for PCA9685 to control 16 servo motors
Arduino wiring for PCA9685 to control 16 servo motors

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

Images

PCA9685 module-0
PCA9685 module-0
PCA9685 module-1
PCA9685 module-1
PCA9685 module-2
PCA9685 module-2
PCA9685 module-3
PCA9685 module-3
PCA9685 module
PCA9685 module
Arduino wiring for PCA9685 to control 16 servo motors
Arduino wiring for PCA9685 to control 16 servo motors
36-PCA9685 video V1: Arduino Code to control 16 servo motor, Basic
Language: C++
/*
 * 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;
}
37-PCA9685 video V1: Arduino Code with mapping PWM
Language: C++
/*
 * 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

Resources & references

No resources yet.

Files📁

Arduino Libraries (zip)

Other files