サーボモータを動かす
今回作成するspot microでは、MG996Rという以下のモータを使用します。
https://akizukidenshi.com/catalog/g/gM-12534/
MG996Rは11kg/cmを発揮できる、大きさの割には高トルクなサーボです。
サーボの制御はPWMを使用しますが、RaspberryPI単体ではPWM波形を出せるピン数が足りないので、PCA9685を使用します。
これとRaspberryPIとをIC2で繋いであげることで、最大16個までの制御が可能になります。
そしてMG996Rをこれに繋いでPWM信号を送ることで制御できるのですが、ここで問題が・・
Duty比がわからない。。
どのDataシート漁っても正確な数字が書いておらず、ネットにある情報では150~650ぐらいのパルス幅を渡せば大丈夫という情報しかない問題に陥りました。
https://qiita.com/h_krbys/items/6a2c9f0c375ec9f3b795
ひとまず150~650で動かしてみましたが、どう見ても180度回っている様には見えません。
そもそも、ここのパルス幅には、サーボに合わせて、
PWMパルス値 = 設定角度のパルス幅[ms] / (周波数のパルス幅[ms] / 分解能[ステップ数])
で指定してあげる必要があります。150~600が仮に正しいとすると、 Duty比0.7 ~ 2.9msのサーボということになりますが、どうにもキリが悪すぎる様に見えます。
https://components101.com/motors/mg995-servo-motor
そこで引き続き色々漁ったところ見つかったのが↑のシート。
MG996ではなく、改良前の995のものでしたが、0.5 ~ 2.5msとの記載がありました。
これを元に、50Hz幅(20ms)で考えると、
最小パルス幅:0.5 / 20 × 4096 = 102
最大パルス幅:2.5 / 20 × 4096 = 512
と割り出せ、それを元にプログラムを実行してみたところ、
きっちり180度動くようになりました!
参考までに動作したプログラムを置いておきます。
import Adafruit_PCA9685
import time
def pulse(deg):
# MAX = 512
# MIN = 102
return int((512 - 102) * deg / 180 + 102)
pwm = Adafruit_PCA9685.PCA9685(address = 0x40, busnum = 1)
servo_num = 2
pwm.set_pwm_freq(50)
while True:
for i in range(servo_num):
print('servo channel: ', i)
pwm.set_pwm(i, 0, pulse(0))
time.sleep(1)
for i in range(servo_num):
print('servo channel: ', i)
pwm.set_pwm(i, 0, pulse(180))
time.sleep(1)
for i in range(servo_num):
print('servo channel: ', i)
pwm.set_pwm(i, 0, pulse(0))
time.sleep(1)
for i in range(servo_num):
print('servo channel: ', i)
pwm.set_pwm(i, 0, pulse(180))
time.sleep(1)
ネットにある情報がノー根拠で使いまわされてるといった事例はよくありますが、今回もそれにぶち当たってしまいました。。