ラズパイでサーボモータ駆動

# 初めに
ラズパイでPC9685ボードを介してサーボモータを駆動します。

# ラズパイ とPCA9685の接続
PCA9685ボードには、サーボ駆動用の電源を接続してください。

ラズパイ|	PCA9685
:---:  | :---:
3V(Pin 01)|	VCC
GND(Pin 06)|	GND
SDA(Pin 03)|	SDA
SCL(Pin 05)|	SCL

ラズパイのピン配置
ラズパイは内側ピンが奇数、外側ピンが偶数です
内側|	外側
:---:  | :---:
3V3(01)|	5V(02)
GPIO2,SDA  (03)| 5V(04)  
 GPIO3,SCL  (05)| GND(06)  

（注）ラズパイの3Vは他に17Pin、GNDは他に9,14,20,25,30,34,39Pin

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2583728/ec0806bb-7092-2310-8714-a514f7c86962.jpeg">

## I2CでPCA9685と通信する
### Ubuntu の場合
ラズパイのI2Cを有効化する。
``` : I2C接続、有効化
sudo apt install i2c-tools -y
sudo apt install python3-smbus -y
sudo adduser ubuntu i2c
sudo i2cdetect -r -y 1
```
I2Cアドレスの確認は以下の通り（-r は無くても可）で、0x40とか0x70などが表示されるはず
``` : I2Cアドレスの確認
sudo i2cdetect -r -y 1
```

### Rapsberry OS でI2Cを有効にする場合
``` : 記載例
$ sudo raspi-config
```
メニューが表示されるので、 "Interfacing Options" を選択する
新たなメニューが表示されるので、 "I2C" を選択する
次の画面で "はい"を選択する
``` : I2C接続、アドレスの確認
$ sudo i2cdetect -y 1
```

## PCA9685ライブラリの導入
PCA9685ライブラリの導入は、adafruitから出ている最新のものを利用する。
以下のうち、名前に circuit が入っていないライブラリは古いので導入しないこと。
これのドキュメント関係は以下のサイトをご覧ください。
https://github.com/adafruit/Adafruit_CircuitPython_PCA9685
``` : PCA9685ライブラリの導入
$ sudo pip3 install adafruit-circuitpython-pca9685
```
This environment is externally managed などのエラーが出る場合は、
仮想環境で使用するか（参考文献 2 参照）、--break-system-package　オプションをつけて無理やり実行する、のいずれかを選択ください。

## 6自由度のロボットアームのデモ用プログラム
サーボモータはMG996Rを使用しました。SG90ではないので注意下さい。
``` Python: servo_control.py
import time
import board
from adafruit_motor import servo
from adafruit_pca9685 import PCA9685

i2c = board.I2C()  # I2C　設定

pca = PCA9685(i2c)  # インスタンス生成
pca.frequency = 50  # 基準周波数50Hz、パルス幅20ms

minp=500
maxp=2500
servo7 = servo.Servo(pca.channels[7], min_pulse=minp, max_pulse=maxp)
servo8 = servo.Servo(pca.channels[8], min_pulse=minp, max_pulse=maxp)
servo9 = servo.Servo(pca.channels[9], min_pulse=minp, max_pulse=maxp)
servo10 = servo.Servo(pca.channels[10], min_pulse=minp, max_pulse=maxp)
servo11 = servo.Servo(pca.channels[11], min_pulse=minp, max_pulse=maxp)
servo12 = servo.Servo(pca.channels[12], min_pulse=minp, max_pulse=maxp)

servo7.angle = 0     # 0(right)-90(center)-180(left)
servo8.angle = 150   # 90(down)-150(up)
servo9.angle = 100   # 60(up)-150(down)
servo10.angle = 180  # 100(up)-180(down)
servo11.angle = 60   # fixed
servo12.angle = 50   # 50(open)-120(close)

while True:
    for i in range(100,60,-1):
        servo9.angle = i
        time.sleep(0.02)
    for i in range(0,90,1):
        servo7.angle = i
        time.sleep(0.02)
    for i in range(60,100,1):
        servo9.angle = i
        time.sleep(0.02)
    for i in range(50,100,1):
        servo12.angle = i
        time.sleep(0.02)
    for i in range(100,60,-1):
        servo9.angle = i
        time.sleep(0.02)
    for i in range(90,0,-1):
        servo7.angle = i
        time.sleep(0.02)
    for i in range(60,100,1):
        servo9.angle = i
        time.sleep(0.02)
    for i in range(100,50,-1):
        servo12.angle = i
        time.sleep(0.02)

pca.deinit()
```
## 参考文献
1) <a href=https://zenn.dev/naoya_oshiro/articles/fa95bd81e3ac8a>ラズパイでサーボモータを制御（PCA9685）</a>
2) <a href=https://github.com/adafruit/Adafruit_CircuitPython_PCA9685>Adafruit_CircuitPython_PCA9685 (github) </a>
<br>
記事内リンク  [初めに戻る] (#参考文献)