Raspberry PiのGPIO操作(2)サーボモータを動かす

raspbian-sg90.jpg

Arduinoでもおなじみのサーボモータ「SG-90」の制御をRaspberry Piでも試してみました。
SG-90は5V動作ですが、制御信号は3.3Vでもなんとか動作するようです。
ただし、Raspberry Piのピンヘッダの5VはUSBの5Vを分配しているだけなので、USBの電源出力が弱いとモータの動作に影響が出ます。

サーボモータの制御はPWMで行いますが、そのためのパッケージは「WiringPi」がメジャーなようです。
Stretch Liteにはデフォルトではインストールされていませんでしたが、

sudo apt-get install wiringpi

でインストールできます。

このパッケージには「gpio」というコマンドが含まれており、このコマンドでPWMの制御も行えます。

まず、GPIOピンをPWMモードにします。使えるピンは、前回の表を参照するとGPIO12、13、18、19となっています。

しかし、WiringPiのマニュアルによると、PWMが使えるのは18だけで、かつアナログオーディオ出力を使っていないこと、という条件があります。
GPIO12、13、19が使えないのは、初代Raspberry Piではピンヘッダが26本で、その中にはGPIO12、13、19が含まれていなかったからだと思われます。
RaspberryPi Zero/Zero Wではアナログオーディオ出力はありませんが、他のRaspberry Piのアナログ音声の出力はPWMで行っているようです。(音質は低そうですね。)

もう一つ注意しなければならないのは、WiringPiでのピン番号がGPIOのピン番号とは異なる点です。
いつもの以下の図を見てください。

GPIO18の前のカッコ書きで、「GPIO_GEN_1」とあります。この「1」がWiringPiでのピン番号になります。
なお「-g」オプションをつければ、WiringPiではなくGPIOのピン番号を使用することができます。

GPIO18を使う場合のSG90との結線は下図のようになります。

rpi-sg90.png

gpioコマンドを以下のように使うと、サーボを動かすことができます。
パラメータの「1」はGPIO_GEN_1、つまりGPIO18を表しています。

この例は「Software | Adafruit’s Raspberry Pi Lesson 8. Using a Servo Motor | Adafruit Learning System」から拝借しました。

GPIO12, 13, 19も同様にPWM制御できますが、WiringPiのピン番号は定義されていませんので、-gオプションを使って指定する必要があります。

また、gpio modeコマンドでPWMの設定をピンに割り当てるとPWMの設定がリセットされるようなので、都度

gpio pwmr 2000
gpio pwmc 192
gpio pwm-ms

を行う必要があります。

これらのパラメータの意味は以下の通りです。

まず、PWMにはbalancedモードとMark:Spaceモードがあります。

・balancedモード
指定されたデューティ比を、できるだけ高い周波数で再現する。デューティ比50%のとき、最も高い周波数が得られる。デューティ比が0%や100%に近づくと周波数が下がる。

・Mark:Spaceモード
指定された周波数で、1周期内の1(Mark)と0(Space)の比を指定されたデューティ比で再現する。どのようなデューティ比でも周波数は変わらない。

以下のスライドに、両者の違いが視覚的に表現されています。

また、両者の波形の違いは以下のビデオをご覧ください。(PWMモードがBalancedモードに相当します)

デジタルアンプのように、アナログ値でPWM変調した信号をローパスフィルタを通してアナログ値に戻す前提ならば、Balancedモードのほうが波形が歪まないと思われます。
しかし、今回のサーボモータは信号周期が20ms(50Hz)と決まっていますのでMark:Spaceモードを使う必要があります。

sg90.png

PWMの周波数は、以下の式で決まります。

19.2MHz / (pwm range * pwm clock divider)

pwm rangeとpwm clock dividerはそれぞれgpio pwmrおよびgpio pwmcで指定されています。

19,200,000 / (2,000 * 192) = 50 (Hz)

となります。

デューティ比は、0~pwm rangeの範囲で指定します。0のとき0%、pwm rangeのとき100%です。
今回の設定ではpwm rangeが2000ですので、1000を指定したときデューティ比50%(H, Lの長さがそれぞれ10msec)となります。

SG90の仕様では、0.5ms~2.4msの範囲で指定するようになっていますので、

-90度:0.5ms/20ms = 0.025; 0.025 * 2000 = 50
0度:1.45ms/20ms = 0.0725; 0.0725 * 2000 = 145
90度:2.4ms/20ms = 0.12; 0.12 * 2000 = 240

と指定すれば良いはずですが、私のSG90は50を指定すると「ジー」と振動音が出てしまいました。
一般的には、サーボでは1.5msのとき0度となる製品が多いようですので、

-90度:60
0度:150
90度:250

としておくのが良さそうです。
90度のとき240なら、1増やせば1度動くという感じになって覚えやすいのですが、実際には240だと90度までは回りきらず、250でちょうど回りきる感じでした。

コメント