サーボドライバ PCA9685 を使って複数のサーボモータ MG996R を制御してみた

# ハードウェアの準備

### 用意するもの

動かしたいサーボモータを複数用意します。
ここではMG996Rを12個動かすことを目標としますが、他のサーボモータや個数でも同様だと思います。
Jetson Nano単体では、せいぜい数個程度のサーボモータしか制御できません。
そのため、サーボドライバ PCA9685を使用します。
PCA9685は16チャンネルあるので、サーボモータを最大16個まで制御することができます。
ここでは12個のサーボモータを動かしたいので、１つあれば充分です。

|デバイス|個数|説明|
|---|:-:|---|
|Jetson Nano|1  |  |
|PCA9685|1|サーボドライバ  |
|MG996R|12|サーボモータ  |
|ACアダプタ 5V-4A|2|Jetson NanoおよびPCA9685用の電源  |
|ジャンパワイヤ　メスーメス  |4 |Jetson NanoとPCA9685を接続  |

### 回路図

Jetson NanoのGPIOピンのレイアウトは次のようになっています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/2f3027be-ba78-7def-204c-4e224c8a507c.png" width=50%>
以下のように繋ぎます。
Jetson NanoとPCA9685の外部電源は、ともに5V 4Aを使用します。

|Jetson Nano GPIOピン番号|<--->|PCA9685|
|:-:|---|:-:|
|1|<--->|VCC|
|3|<--->|SDA|
|5|<--->|SCL|
|9|<--->|GND|

![servo_test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/7ae17920-5cee-76fb-144e-53d0316ce8ae.png)

![top.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/f847336f-b508-4aa0-9a8c-416c59523421.jpeg)

![detail.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256233/b0248e14-74e9-9dee-ea0c-c43ad1772e45.jpeg)

# ソフトウェアの準備

### ライブラリのインストール

[こちらのサイト](https://kokensha.xyz/jetson/jetson-nano-pca9685-i2c-error-resolution/)を参考に各種ライブラリをインストールしていきます。

### 接続確認

インストールが完了すれば、以下のコマンドで接続確認ができます。

```
$ sudo i2cdetect -y -r 1
```

正しく接続されていれば、次のような表示になるはずです。

```
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --
```

### モータ制御プログラム

```python:joint_control.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import Adafruit_PCA9685
import time

# Initialise the PCA9685 using desired address and/or bus:
pwm = Adafruit_PCA9685.PCA9685(address = 0x40, busnum = 1)

# Number of servo
servo_num = 12

# Configure min and max servo pulse lengths
servo_min    = 150 # min. pulse length
servo_max    = 600 # max. pulse length
servo_offset = 50

# Set frequency to 60[Hz]
pwm.set_pwm_freq(60)

while True:
    # Move servo on each channel
    for i in range(servo_num):
        print('Moving servo on channel: ', i)
        pwm.set_pwm(i, 0, servo_min + servo_offset)
        time.sleep(1)
    for i in range(servo_num):
        print('Moving servo on channel: ', i)
        pwm.set_pwm(i, 0, servo_max - servo_offset)
        time.sleep(1)
    # Move servo on all channel
    for i in range(servo_num):
        print('Moving servo on channel: ', i)
        pwm.set_pwm(i, 0, servo_min + servo_offset)
    time.sleep(1)
    for i in range(servo_num):
        print('Moving servo on channel: ', i)
        pwm.set_pwm(i, 0, servo_max - servo_offset)
    time.sleep(1)

```

# サーボを動かす

ここまで準備ができたらいざ動かしてみましょう！
実行権限を与えてから実行すればサーボが動くはずです。

```
$ chmod +x joint_control.py
$ python3 joint_control.py
```

[![Couldn't find video ...](http://img.youtube.com/vi/6QJoNsWQZ9A/0.jpg)](http://www.youtube.com/watch?v=6QJoNsWQZ9A)

# おまけ

PCA9685の外部電源として、5V-4Aではなく5V-2Aを供給した場合の動作と外部電源の電圧が以下になります。
単体で動かす分には充分ですが、複数個動かす場合には電流が足りず、電圧が低下してしまうためうまく動いてくれません。
定格電流には注意しましょう。
[![Couldn't find video ...](http://img.youtube.com/vi/kqB9U2uB_Xo/0.jpg)](http://www.youtube.com/watch?v=kqB9U2uB_Xo)

# 参考

1. https://kokensha.xyz/jetson/jetson-nano-pca9685-i2c-error-resolution/