サーボモーターはSG-90を使います。
このSG-90を動かすにはPWM制御を使います。PWM制御といえばLEDの明るさを変化させるのにも使いましたがこれはソフトウェアで行うものでした。ソフトウェアでPWMのパルス幅を作っているので、それ以外の処理の負荷によってこのパルス幅が不規則に変動します。サーボモーターはPWMのパルス幅によって動かす角度を決定しているのでより高い精度で動かしたいものです。そのようなときにはハードウェアによるPWM制御を使うのが良いでしょう。
ここではpigpioライブラリを使ったハードウェアPWM制御でSG-90を動かします。
SG-90とのインターフェース
SG-90の電気的な仕様が書かれたデータシートを見つける事ができず、秋月電子の商品ページのリンクにあるSG-90 PDFデーターシートを参考にします。これにはSpecificationsとしてOperating Voltage:3.3V(〜6V)と記載されているのですが、タイミング図ではPower and Signalが4.8V(〜5V)となっていて何が何やらです。
Raspberry Pi Zero W(以下Pi Zero)のGPIOのVOH(Highレベルの出力電圧)の最小値は3Vですので、SG-90を5Vで使った場合のVIH(Highレベルの入力電圧)を知りたいのですが、わからなかったので回路図に示すように3.3Vから5Vへのレベル変換回路を挿入することにします。5VはPi Zeroからではなくモバイルバッテリーから供給しています。
レベル変換前後の波形をオシロスコープで観測した画像です。CH1(黄)がGPIO18、CH2(青)がSG-90のPWM入力波形です。
ハードウェアPWMでサーボモーターの角度を制御
ハードウェアでPWM波形を出力できるGPIOピンは以下の4つに限られています。また、独立して出力できるのはChannel 0とChannel 1の2組になります。
- PWM Channel 0 : GPIO12、GPIO18
- PWM Channel 1 : GPIO13、GPIO19
以下のソースはGPIO18ピンをハードウェアPWMの出力ピンとして使い、1秒毎にサーボホーンの位置を-90 -> -45 -> 0 -> 45 -> 90に移動させるプログラムです。ファイル名はtest9.pyです。
#!/usr/bin/python import pigpio # pigpioモジュールの読み込み import time # timeモジュールの読bみ込み gpio_pwm = 18 # PWMピンのGPIO番号を定義 pig = pigpio.pi() pig.set_mode(gpio_pwm, pigpio.OUTPUT) # PWMピンを出力に設定 try: while True: pig.hardware_PWM(gpio_pwm, 50, 25000) # PWM周波数を50Hz,dutyを2.5%(0.5mS) time.sleep(1) pig.hardware_PWM(gpio_pwm, 50, 50000) # PWM周波数を50Hz,dutyを5%(2.5mS) time.sleep(1) pig.hardware_PWM(gpio_pwm, 50, 72500) # PWM周波数を50Hz,dutyを7.25%(1.45mS) time.sleep(1) pig.hardware_PWM(gpio_pwm, 50, 100000) # PWM周波数を50Hz,dutyを10%(2mS) time.sleep(1) pig.hardware_PWM(gpio_pwm, 50, 120000) # PWM周波数を50Hz,dutyを12%(2.4mS) time.sleep(1) except KeyboardInterrupt: pig.set_mode(gpio_pwm, pigpio.INPUT) pig.stop()
ハードウェアPWMは
hardware_PWM(GPIO_Pin, Frequency, Duty)
のようにGPIOピン番号、PWMの周波数そしてデューティー比を指定します。デューティー比を5%とするには、1,000,000に0.05を乗じた50,000になります。
GPIOライブラリのpigpioは使用する前にデーモンを起動させておく必要があります。Raspberry Piを起動したら一度だけ、ターミナルからルート権限で実行します。
$ sudo pigpiod
そして、ターミナルから以下のように実行します。
$ python test9.py