🤖

【Raspberry Pi】 モーターを回そう。「サーボモーター編」

2022/08/20に公開

砲身の制御

戦車を走らせることは出来ましたので、 次の目標である砲塔について考えます。

現状、固定砲塔どころか、上下にすら動かないため、
照準どころの話ではありません。

砲塔や砲身の制御に使おうと思っているのが、サーボモータです。
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脚歩行ロボットにもサーボが使われていました。

GitHubで編集を提案

Discussion