検索コード

PCA9685 16チャンネル 12ビット サーボコントローラ V1 用の Arduino コードとビデオ

PCA9685 16チャンネル 12ビット サーボコントローラ V1 用の Arduino コードとビデオ

このチュートリアルでは、NXPセミコンダクターのPCA9685 16チャンネル 12ビット サーボコントローラの使い方を紹介します。このモジュールを使えば、最大16台のサーボを制御したり、PWM(パルス幅変調)でLED群の明るさを精密に調光したりできます。チュートリアルの終了時には、複数のサーボを個別または同時に制御できる動作するセットアップができあがっているでしょう。

PCA9685 module-0

チュートリアルの内容をさらに明確にするため、セットアップとコーディングの手順を視覚的に示す添付のビデオ(ビデオ内の00:00)をご覧ください。

ハードウェアの解説

PCA9685モジュールは、I2C通信を介して複数のサーボを制御できるコンパクトな基板です。16チャンネルを備えており、それぞれに個別の制御信号を持つ最大16台のサーボを接続できます。モジュールは5Vの電源で動作し、サーボの位置を正確に制御するために不可欠なPWM信号を扱うように設計されています。

この基板には電源(VCC)、グラウンド(GND)、および通信(SDA と SCL)用の専用ピンが備わっています。SDA ピンはデータ送信に使用され、SCL ピンはクロック信号で、両方ともそれぞれ Arduino のアナログピン A4 と A5 に接続されます。この構成により、Arduino と PCA9685 モジュール間で信頼性の高い通信が確保されます。

データシートの詳細

製造元NXPセミコンダクター
部品番号PCA9685
ロジック/IO電圧3.3 V〜5.5 V
電源電圧2.3 V〜5.5 V
出力電流(チャンネルごと)最大25 mA
ピーク電流(チャンネルあたり)最大100 mA
PWM周波数に関するガイダンス24 Hzから1.6 kHzまで
入力論理閾値0.3 V(低)/0.7 V(高)
電圧降下 / Rドレイン・ソース(オン)/ 彩度最大0.5 V
熱限界-40 °C〜125 °C
パッケージHTSSOP-28
注記/バリエーション16チャンネルPWMコントローラ

  • 十分な電流(推奨:1A)を供給できる5V電源を確保してください。
  • 損傷を避けるため、サーボをArduinoから直接給電しないでください。
  • 正しいI2Cピンを使用してください:SDAはA4に、SCLはA5に接続してください。
  • 使用しているサーボに合わせてパルス幅の値を調整してください。
  • 配線の極性(GND、VCC、および信号)が正しいか確認してください。
  • 高電流用途では放熱対策を検討してください。

配線手順

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

PCA9685をArduinoに配線するには、まず電源とグランドを接続します。PCA9685のVCCピンをArduinoの5V出力に接続します。次にPCA9685のGNDピンをArduinoのGNDに接続します。最後にPCA9685のSDAピンをArduinoのピンA4に、SCLピンをピンA5に接続します。

サーボについては、信号線をPCA9685の該当チャンネル(例:最初のサーボはCH0)に接続し、電源線は別の電源に接続してください(サーボはArduinoが供給できる以上の電流を必要とすることがあるため)。接地線はPCA9685と共通のグラウンドに接続します。信号線、電源線、グラウンド線が正しく揃っていることを確認し、部品を損傷しないよう注意してください。

コード例とウォークスルー

コードのセットアップセクションでは、PCA9685モジュールを初期化します。pwm.begin()そして、PWM周波数を…で設定するpwm.setPWMFreq(60);これはサーボの通信周波数を設定します。

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");
  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}

ループ内では、目的の角度に対応するPWM値を設定することでサーボを制御します。その関数angleToPulse(int ang)角度を適切なパルス幅に変換し、これはサーボの正確な位置決めに不可欠です。

void loop() {
  for( int angle =0; angle<181; angle +=20){
    delay(500);
    pwm.setPWM(0, 0, angleToPulse(angle) );
  }
}

最後に、その関数angleToPulse(int ang)定義された最小および最大のパルス長を用いて角度をパルス幅に変換します。これにより、望む角度に基づいてサーボの位置を簡単に制御できます。

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;
}

デモンストレーション/当日のご案内

すべての配線が正しく接続され、コードがアップロードされると、サーボが指定した角度を20度ずつ動くのが見えるはずです。サーボが期待どおりに動作しない場合は、配線の接続が正しいか確認し、電源が十分であることを確認してください(ビデオの12:30を参照)。

動画のタイムスタンプ

  • 00:00- PCA9685の紹介
  • 02:30- 配線手順
  • 05:00- コードのウォークスルー
  • 10:15- サーボ制御のデモ
  • 12:30- よくある問題のトラブルシューティング

画像

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
言語: 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
言語: C++
/*
 * 元のソース: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
 * これはPCA9685 16チャンネルサーボコントローラー用のArduinoコードです。
 * 詳細とデモについては、動画をご覧ください: http://youtu.be/y8X9X10Tn1k
 * 
 * ロボジャックスビデオチャンネルのためにアハマド・ネジャビが執筆しました: www.Robojax.com
 * 日付: 2017年12月15日、カナダ・オンタリオ州アジャックス
 * このコードを共有する許可が与えられています。この
 * メモがコードと一緒に保管される場合に限ります。
 * 免責事項: このコードは「現状のまま」であり、教育目的のみで使用されます。
 * 
 * /
 * /***************************************************
 * これは私たちのAdafruit 16チャンネルPWM & サーボドライバーの例です。
 * サーボテスト - これは16台のサーボを順番に駆動します。
 * 
 * 今日、Adafruitショップで購入してください!
 * ------> http://www.adafruit.com/products/815
 * 
 * これらのディスプレイはI2Cを使用して通信します。インターフェースには2つのピンが必要です。Arduino UNOの場合、SCL -> アナログ5、SDA -> アナログ4です。
 * 
 * Adafruitはこのオープンソースコードを提供するために時間とリソースを投資しています。
 * Adafruitとオープンソースハードウェアをサポートするために、Adafruitの製品を購入してください!
 * 
 * Adafruit Industriesのためにリモール・フリード/レディアダが執筆しました。
 * BSDライセンス、上記のすべてのテキストは再配布に含めなければなりません。
 */
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

 // このように呼ばれ、デフォルトアドレス0x40を使用します。
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
 // 異なるアドレスを使用しても呼び出すことができます。
 // Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

 // サーボのメーカーによって、パルス幅の最小値と最大値は異なる場合があります。
 // これらをハードストップに達しない範囲でできるだけ小さく/大きくしたい。
 // 最大範囲のために。サーボに合わせるために必要に応じて調整する必要があります。
 // 持て!
#define SERVOMIN  125 // これは「最小」パルス長カウント (4096のうち) です。
#define SERVOMAX  575 // これは「最大」パルス長カウント(4096のうち)です。

 // 私たちのサーボ#カウンター
uint8_t servonum = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");

  pwm.begin();

  pwm.setPWMFreq(60); // アナログサーボは約60 Hzの更新で動作します

 // yield();
}

 // loop() 内のコードは 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);


}

必要かもしれないもの

リソースと参考文献

まだリソースはありません。

ファイル📁

Arduinoライブラリ(zip)