サーボモータドライバ（PCA9685)とArduinoを用いて複数(12個)のサーボモータ(mg996r)を動かす

## 用いたデバイス

|デバイス名|型番,リンク|個数|
|---|---|---|
|サーボモータドライバ|[pca9685] (https://www.amazon.co.jp/gp/product/B07SLRG5J1/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1) |1|
|マイコンボード|[Arduino mega](https://www.amazon.co.jp/gp/product/B06ZZ259PM/ref=ppx_yo_dt_b_asin_title_o03_s01?ie=UTF8&psc=1)|1  |  
|サーボモータ|[mg996r](http://akizukidenshi.com/catalog/g/gM-12534/)|12 |  |
|ACアダプター|[5V 4A 最大出力20W 5.5mm×2.1mm](https://item.rakuten.co.jp/cosmone/scl-5v4a-adapter-pse-ty01/?s-id=ph_pc_itemname)|1|  
|DC電源コネクタ ジャック|[5.5mmx2.1mm](https://www.amazon.co.jp/gp/product/B077GV4NVY/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)|1|  

### pca9685(サーボモータドライバ)
[データーシートなど](http://akizukidenshi.com/catalog/g/gK-10350/)
[わかりやすい記事](http://blog.robotakao.jp/blog-entry-148.html)
[英語だけど詳しい](https://learn.adafruit.com/16-channel-pwm-servo-driver?view=all)

・簡単に
I2Cで入力しPWM出力します。
単体で16個のサーボモータを、複数使うことで最大992個のPWM出力を制御することができるものです。


### mg996r(サーボモータ)
[mg996r](http://akizukidenshi.com/catalog/g/gM-12534/)

MG996Rを動かすには500mAから900mA(6V時)の電流が必要です。
Arduinoの5V電源では電流不足で回転しません。

### ACアダプタ類
以下二つをもちいてコンセントから5V,4Aの直流電源を得ます。
[ACアダプタ](https://item.rakuten.co.jp/cosmone/scl-5v4a-adapter-pse-ty01/?s-id=ph_pc_itemname) 
[DC電源コネクタ ジャック](https://www.amazon.co.jp/gp/product/B077GV4NVY/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)
あくまで接続の例です。

## 回路

### 電源
・Arduinoはプログラムの書き込みに使用したPCからUSBでとっています。
何でもいいです。

・モータドライバの外部電源はACアダプタから5V,4A取っています。
mg996r12個動かすには、5V、4Aくらいあった方がよさそうです。
乾電池４本(6V)では電流が足りなく3つしか動きませんでした。
[5V,4Aを用いるのに参考にした記事](https://qiita.com/h_krbys/items/6a2c9f0c375ec9f3b795)
またpca9685は電源をピンヘッダまたはターミナルブロックから、どちらからも取ることができます。
違いとしては、ターミナルブロックには逆極性保護がついています。
今回は上記の理由とケーブルの安定感からターミナルブロックから電力を得ます。

### 配線

PCA9685
GND　　　ArduinoのGND(V+に電源のプラスを指している場合はここに電源のGNDも繋げます)
OE　　　 未接続
SCL　　　ArduinoのSCL表記のあるところ
SDA　　　ArduinoのSDA表記のあるところ
VCC　　　Arduinoの5V
V＋　　　外部電源をターミナルブロックから得るため、今回は未接続

各0-15chにサーボモータを接続します。

<img width="300" alt="S__27066370.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644186/9a1c3045-cdb8-251e-9da7-37a0c8b9fca7.jpeg">

![pca配線.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644186/95bad347-efb9-c536-b06c-7c1db4878d51.jpeg)

![S__27049994.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644186/27b7671f-a1b6-e13a-014d-a63d4647374f.jpeg)

## プログラミング
実行環境:ArduinoIDE

[PCA9682のライブラリ](http://akizukidenshi.com/catalog/g/gK-10350/)
PCA9682のライブラリを導入する必要があります。
[Arduinoライブラリ導入](https://www.arduino.cc/en/Guide/Libraries)


```
#include <PCA9685.h> //PCA9685用ヘッダーファイル

PCA9685 pwm = PCA9685(0x40);    //PCA9685のアドレス指定

#define SERVOMIN 150            //最小パルス幅 
#define SERVOMAX 600            //最大パルス幅

void setup() {
 pwm.begin();                   //初期設定 (アドレス0x40用)
 pwm.setPWMFreq(50);            //PWM周期を50Hzに設定 (アドレス0x40用)
}

int n=0;

void loop() {
//12chすべてのチャンネルより0度～180度の移動を繰り返します。
  for(int i=0; i<12; i++)
      servo_write(i,n);
  n=n+10;
  if(n>=180)n=0;
  delay(500);  
}

void servo_write(int ch, int ang){ //動かすサーボチャンネルと角度を指定
  ang = map(ang, 0, 180, SERVOMIN, SERVOMAX); //角度（0～180）をPWMのパルス幅（150～500）に変換
  pwm.setPWM(ch, 0, ang);
}

```

[このコードを動かした動画]
(https://youtu.be/IWw4JM8pN-E)