【Raspberry Pi】 モーターを回そう。「サーボモーター編」
砲身の制御
戦車を走らせることは出来ましたので、 次の目標である砲塔について考えます。
現状、固定砲塔どころか、上下にすら動かないため、
照準どころの話ではありません。
砲塔や砲身の制御に使おうと思っているのが、サーボモータです。
DCモータとは異なり、ある角度にするためのモータがサーボモータです。
今回は入門キットについてきた、SG-90 という安価な有名サーボモータを利用します。
サーボモータもDCモータと同じく、PWMを利用して動かしますが、
サーボモータは厳密な制御が必要であるため、ハードウェアPWMを利用します。
DCモータは雑で良いため、ソフトウェアPWMで良いそうです。
このハードウェアPWMを出力できるピンが、ラズパイには2つあり、
PWM0(GPIO18 or GPIO12) および PWM1(GPIO19 or GPIO13) なんだそうです。
ですので、このピンはなるべく開けておきましょう。
Arduino だともっと多いみたいです。
サーボモータは、モータドライバなどは不要で、
接続も3つの端子しかないため簡単です。
制御のためのプログラムは以下のようなものです。
from time import sleep
import wiringpi
pinSrv = 12;
wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(pinSrv, wiringpi.GPIO.PWM_OUTPUT)
wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)
wiringpi.pwmSetClock(375)
wiringpi.pwmWrite(pinSrv,0)
# TOWER PRO SG90
home = 75
plus90 = 29
muinus90 = 129
list = [home]
for x in range(plus90, muinus90+1, 10):
list.append(x)
list.append(home)
try:
for duty in list :
wiringpi.pwmWrite(pinSrv, int(duty))
sleep(1)
except KeyboardInterrupt:
pass
wiringpi.pwmWrite(pinSrv,home)
ハードウェアPWMの制御のため、GPIO.PWMではなく、wiringpi という
モジュールを利用します。
githubからクローンし、ビルドするタイプのモジュールです。
教本を参考に準備しました。
大雑把にみれば、GPIO.PWMと似通ったソースの流れです。
Pythonっぽく書いてみました。
line11 wiringpi.pwmWrite
のようにPWMの値を設定します。
教本にもありましたが、通常であれば、動かしたい角度から、設定値を計算します。
なかなか複雑な計算でしたので、すっ飛ばしました。
簡単な方法を発見しました。メソッドの引数の範囲が、0-1024となっています。
そこで実際に0-1024までを書き込んで挙動を見てみればよいのです。
戦車に搭載する際は、数段階の変化が出来れば十分で、
厳密に何度ということは不要という判断です。(手抜き)
結果的に、29~129 あたりで、だいたい180度動きました。(値が近くて良かった)
半分の79が90度かと思いきや、やや傾いていたので、75に微調整。
ソースを動かしてみた結果です。
この範囲で動かせていれば、サーボの利用用途としては十分でしょうか。
おまけ
秋月で間違って買ったローテーションサーボも動かしてみます。
ローテーションサーボは、通常のサーボと違い、限界の角度がありません。
回転し続けるので、ゆっくり動くDCモータみたいなイメージです。
似たような方法で、静止および回転する値を割り出します。
from time import sleep
import wiringpi
pinSrv = 12;
wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(pinSrv, wiringpi.GPIO.PWM_OUTPUT)
wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)
wiringpi.pwmSetClock(375)
wiringpi.pwmWrite(pinSrv,50)
#S35 STD
rightcyc = 70
leftcyc = 80
stop = 75
list = [rightcyc, stop, leftcyc, stop]
try:
while True:
for duty in list:
wiringpi.pwmWrite(pinSrv, duty)
if duty == stop:
sleep(1)
else:
sleep(3)
except KeyboardInterrupt:
pass
wiringpi.pwmWrite(pinSrv,stop)
砲塔旋回に使えそうですが、軸が弱そうなので心配です。
素直にステッピングモーターを使うことにしましょう。
まとめ
サーボはいろいろな場所で使われています。
4脚歩行ロボットにもサーボが使われていました。
Discussion