PCA9685 +RaspberryPi Zeroでサーボモータを動かす
はじめに
Aliexpressでサーボモーターや電子部品をいろいろ購入したので、
サーボモータを試しにで動かしてみます。
ようやくサーボモーターとか届いた。
— やまだ (@dayamax259) 2020年5月21日
中国からの物流も回復しつつあるようで安心 pic.twitter.com/HA4ha5sA8m
準備
用意したもの
複数のサーボモータを動かせるように、サーボモータ制御ボード(PCA9685搭載)と小型サーボモータ(MG90S互換品)をAliexpressで購入しました。
RaspberryPiZeroW
品薄が続いているようで少し高いですが、それでも2500円程度なので一つ購入しました。
Raspberry Pi Zero W - ヘッダー ハンダ付け済み - ラズベリー・パイ ゼロ W ワイヤレス
- メディア: エレクトロニクス
MG90S
まずは小型かつ安価にロボットを作りたいので、MG90を購入しました。
Aliexpressだと1個350円程度で互換品を購入することができます。
※安い分不良品が多少含まれてます....
https://ja.aliexpress.com/item/32840704368.html?spm=a2g0s.9042311.0.0.1b6c4c4dfkxLhk
- PCA9685
RaspberryPiの事前設定
raspi-configでI2C有効化
"sudo raspi-config"を実行して、I2Cを有効化する。
I2c通信速度設定
以下を実行して、I2C通信速度を設定する。
$ sudo su $ echo "dtparam=i2c_baudrate=10000" >> /boot/config.txt $ reboot
ライブラリインストール
Adafruit Python PCA9685のサンプルを参考に進めます。
https://github.com/adafruit/Adafruit_Python_PCA9685
pipでのインストールがお手軽ですが、サンプルコードがインストールされないため下記手順でインストールしました。
$sudo apt-get install git build-essential python3-dev python3-pip $cd ~ $git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git $cd Adafruit_Python_PCA9685 $sudo python3 setup.py install
PCA9685接続実施
接続構成
PCA9685をRaspberryPiのGPIOに接続します。
製品によってピン配置が微妙に違うので基板に記載されたピン配置の確認が必要です。
Raspbery PiのGPIOピン配置
GPIOのピン配置は以下の図の通りです。
RaspberyPiZeroも同じ配置ですので、以下に従ってPCA9685と接続します。
※https://www.raspberrypi.orgより引用
PCA9685の配線
以下のように接続します。
V+ 未接続
VCC ⇔ Pin2 (5V)
SDA ⇔ Pin3 (SDA)
SCL ⇔ Pin5 (SCL)
OE 未接続
GND ⇔ Pin6 (GND)
接続確認
PCA9685接続後にi2c動作確認
$ sudo i2cdetect -y 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 -- -- -- -- -- -- --
動作確認
以下のソースコードでサーボモータを0~180度で動かします。
servo.py
import Adafruit_PCA9685 import time #サーボモーターをコントロールするためのクラス class servo: PULSE_MIN = 150 # パルス最小値(若干の個体差分あり) PULSE_MAX = 650 # パルス最大値(若干の個体差分あり) MAX_ANGLE = 180 # サーボモータの最大角度 def __init__(self, Channel): self.Channel = Channel self.pwm = Adafruit_PCA9685.PCA9685(0x40) self.pwm.set_pwm_freq(60) def setPos(self,pos): # PLUSE_MIN~PULSE_MAXの値が 0 度 ~ MAX_ANGLE度に対応するため、 # 指定した角度になるようにパルスを計算する pulse = int((self.PULSE_MAX - self.PULSE_MIN) / self.MAX_ANGLE * pos + self.PULSE_MIN) self.pwm.set_pwm(self.Channel, 0, pulse) pos = 0 s = servo(0) s.setPos(0) while True: # 2秒間隔で0~90~180度を繰り返す # 設定した角度にならない場合は、PULSE_MIN、PLUSE_MAX、MAX_ANGLEが間違っている time.sleep(2) s.setPos(pos) pos += 90 if (pos > 180): pos = 0
トラブルシューティング
問題:コード実行時に以下のエラーが発生して実行できなかった。
原因:VCCの配線が抜けていた。
PCA9685ボードの外部電源を接続していたが、それでもVCC接続は必要な模様
Traceback (most recent call last): File "servo.py", line 4, in <module> pwm = Adafruit_PCA9685.PCA9685() File "/usr/local/lib/python3.7/dist-packages/Adafruit_PCA9685-1.0.1-py3.7.egg/Adafruit_PCA9685/PCA9685.py", line 77, in __init__ File "/usr/local/lib/python3.7/dist-packages/Adafruit_GPIO-1.0.4-py3.7.egg/Adafruit_GPIO/I2C.py", line 116, in write8 File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO-1.1.5-py3.7.egg/Adafruit_PureIO/smbus.py", line 322, in write_byte_data OSError: [Errno 121] Remote I/O error