はじめに
秋月電子でも入手可能な回転サーボ FS90R を入手したので動かしてみる。
環境はwarrior(Yocto 2.7)でmeta-raspberrypiを使用する。
環境構築
ここの「環境構築」を参照。
local.confに下記の内容を追加する。
IMAGE_INSTALL_append = " rpi-gpio"
core-image-baseを作成する。
$ bitbake core-image-base
ddやEtcherなどでマイクロSDに書き込む。
配線
FS90R側の信号は次のようになる。
色 | 信号 |
---|---|
オレンジ | Signal(PWM) |
赤 | +(V) |
茶 | -(GND) |
駆動電圧は最低4.8Vなので、5V入れてやれば動く。 制御用の電圧は3.3Vでも問題ない様子。
ラズベリーパイの5VのピンはUSBからの電流を分配しているだけっぽいので、
手っ取り早くやるなら、+
のところはラズベリーパイの5Vに接続してしまっても問題ないと思う。
ただし、本体の電源そのものなので、サーボを回すと高頻度で次のように電源低下を検出ようになる。
[ 1747.351869] Under-voltage detected! (0x00050005)
それが気になる場合は、別系統で電源を引っ張ってきてモーターに入れると良い。
筆者は、USB-シリアル変換ケーブルのPCのUSBから出ている5Vをモーターに入れた。 (ラズベリーパイにコンセントの電源をひっぱているので、普段この5Vは余っている)
プログラム
PWMを制御したいので手っ取り早くpythonで書く。GPIOの制御にはRPi.GPIOを使用する。 RPi.GPIOはソフトウェアでPWMをシミュレートすることができ、普通のGPIOピンでもPWMすることができる。
ただし、ハードウェアPWMと比べると制度が低いので、正確なパルス幅が必要な場合は注意が必要となる。
Duty比
パルス幅のレンジは700〜2300usで、1500usで停止。これを境に小さいと時計回り、大きいと半時計回りとなる。
動作 | パルス幅(us) |
---|---|
停止 | 1500 |
時計回り | 1500未満 |
半時計回り | 1501以上 |
RPi.GPIOのPWMではベースとなる周波数とDuty比でパルス幅を指定する。
例えば50Hzの場合、1回の振幅に20msかかるので、1500usのパルス幅を指定したい場合次のように計算する。
1500us = 1500us/(20ms*1000)*100 = 7.5%
停止させておくために設定するDutyは7.5%ということになる。
次のプログラムは制御信号にGPIO21を使用して次の動作を行う。
- 2秒間停止
- 2秒間時計回りで回転
- 2秒間半時計回りで回転
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) gp_out = 21 GPIO.setup(gp_out, GPIO.OUT) servo = GPIO.PWM(gp_out, 50) servo.start(7.5) time.sleep(2) servo.ChangeDutyCycle(5) time.sleep(2) servo.ChangeDutyCycle(10) time.sleep(2) servo.stop() GPIO.cleanup()
しかし、実際に動かしてみるとピッタリと停止しないことがわかる。 これは先述の通りソフトウェアPWMでありパルス幅が正確ではないことが原因とななる。
なので、7.5の時点でどちらに回転しているかを見て値を微調整する。
筆者の環境では7.1
でピッタリと停止した。
まとめ
サーボの電源は本体と別系統が無難。
ソフトウェアPWMでも、値を微調整すれば回転サーボの制御は可能。 ただし正確に制御したい場合はハードウェアPWMのほうが確実。