ラズパイ5でサーボモーターSG90を動かしてみました。
配線は
赤:2番ピン(5V)
茶:6番ピン(0V)
黄:12番ピン(GPIO18)
です。

コードは
from gpiozero import Servo from time import sleep servo = Servo(18, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000) while True: servo.value = -1.0 #(0°) sleep(1) servo.value = 0.0 # (90°) sleep(1) servo.value = 1.0 #(180°) sleep(1)
実行すると動きましたが、停止した時にジジジジと僅かに振動します。
ジッターと呼ばれる症状で、ソフトウェアPWMだと発生するらしい。
そのためハードウェアPWMで動作させる必要があるのですが、ハードウェアPWMを使用するためには、はじめにIOの割り当てをしなければなりません。
ラズパイ5はハードウェアPWMを2軸使用することができるようです。
PWM1:GPIO12,18,40,52
PWM2:GPIO13,19,41,53
設定するには、ターミナルを開いて、下記を入力
sudo nano /boot/firmware/config.txt
すると、nanoというエディターが開くので、末尾に以下を追記します。
[all] dtoverlay=pwm-2chan
Ctrl + Oの後、ENTERを押すと保存。Ctrl + Xで閉じます。その後リブートすると適用されます。
適用されたかを確認するには、ターミナルで
pinctl -p
と入力すると、現在割り当てられたIOの項目が表示されます。
1: 3v3 2: 5v 3: no pu | -- // GPIO2 = none 4: 5v 5: no pu | -- // GPIO3 = none 6: gnd 7: no pu | -- // GPIO4 = none 8: no pd | -- // GPIO14 = none 9: gnd 10: no pd | -- // GPIO15 = none 11: no pd | -- // GPIO17 = none 12: a3 pd | lo // GPIO18 = PWM0_CHAN2 13: no pd | -- // GPIO27 = none 14: gnd 15: no pd | -- // GPIO22 = none 16: no pd | -- // GPIO23 = none 17: 3v3 18: no pd | -- // GPIO24 = none 19: no pd | -- // GPIO10 = none 20: gnd 21: no pd | -- // GPIO9 = none 22: no pd | -- // GPIO25 = none 23: no pd | -- // GPIO11 = none 24: no pu | -- // GPIO8 = none 25: gnd 26: no pu | -- // GPIO7 = none 27: ip pu | hi // GPIO0 = input 28: ip pu | hi // GPIO1 = input 29: no pu | -- // GPIO5 = none 30: gnd 31: no pu | -- // GPIO6 = none 32: no pd | -- // GPIO12 = none 33: no pd | -- // GPIO13 = none 34: gnd 35: a3 pd | lo // GPIO19 = PWM0_CHAN3 36: no pd | -- // GPIO16 = none 37: no pd | -- // GPIO26 = none 38: no pd | -- // GPIO20 = none 39: gnd 40: no pd | -- // GPIO21 = none
ここで、「12: a3 pd | lo // GPIO18 = PWM0_CHAN2」と「35: a3 pd | lo // GPIO19 = PWM0_CHAN3」にPWMが割り当てられたとわかります。
GPIO18はCHAN2,GPIO19はCHAN3ということを覚えておいてください。
ハードウェアPWMを使う場合は、コードも変わります。
ライブラリのインストールが必要なので、仮想環境下でrpi_hardware.pwmをインストールします。
pip install rpi_hardware.pwm
pythonコードは以下の通り
from rpi_hardware_pwm import HardwarePWM import time pwm = HardwarePWM(pwm_channel=2, hz=50) pwm.start(0) step = 0 while True: pwm.change_duty_cycle(2.5) # 0 time.sleep(1) pwm.change_duty_cycle(7.5) # 90度 time.sleep(1) pwm.change_duty_cycle(12.5) # 180度 time.sleep(1)
pwm_channelに、接続したピンが割り当てられたPWMのチャンネル番号を指定します。
GPIO18 = PWM0_CHAN2でしたので、チャンネル番号は2です。
hz=50は、SG90の仕様が20msの周期で動作するため、逆数の50hzを設定します。(周波数=1/周期)
角度の指定は、デューティ比で指定します。SG90は、20msの周期の中に0.5msがONしていると0°、2.5msがONしていると180°動きます。
デューティー比というのは、周期に対するONする時間の割合(パルス幅/周期)ですので、0°は0.5/20*100=2.5、180°は2.5/20*100=12.5という風な計算です。
実行すると、ソフトウェアPWMよりもはるかに滑らかな動作を確認できました。
SG90は速度の変更ができないので、ゆっくり動かすには、少しずつステップさせて動かす制御をすることで、疑似的にスローな動作をさせることができます。
from rpi_hardware_pwm import HardwarePWM import time pwm = HardwarePWM(pwm_channel=2, hz=50) pwm.start(0) step = 0 while True: #ステップ動作(疑似的なスイープ動作) for step in range(0, 180, 1): # 0度から180度まで1度ずつ増加 sita = 5/90*step + 2.5 # 0度から180度まで5/90ずつ増加 pwm.change_duty_cycle(sita) time.sleep(0.01) for step in range(180, 0, -10): sita = 5/90*step + 2.5 pwm.change_duty_cycle(sita) time.sleep(0.1)
range(0, 180, 1)や、time.sleep(0.01)の数字を変えることで、自分好みの動作が可能となりました。