(26) 【連載1-5】マイコンで電子工作入門:サーボモーターを廻す

投稿者: | 2018年5月5日

14,540 views

この記事は最終更新から 1142日 が経過しています。

1. やってみたいこと

Raspberry Piの ハードウェア PWMを使ってサーボモーターを廻してみたい。

2. ハードPWM vs ソフトPWM

(1) ハードPWM

PWMコントローラ(=PWM専用のH/W)で制御するため、指定したパルス幅を安定して維持できる。

(2) ソフトPWM

CPUで制御するため、CPUが高負荷状態のときに PWM周波数が狂ったりパルス幅が広がったりする。

(3) どちらがよいのか?

目的に応じて使い分ければよい。

LED点灯の明るさを PWMで制御する場合、多少パルス幅がぶれても人の目にはよくわからない。
サーボモーターを PWMで制御する場合、パルス幅が一定でないと回転角度が小刻みにぶれてしまう。

3. パーツを調達

(1) モーターを購入

秋月さんで一番安いサーボモーターを購入した。

(2) モーターの仕様

このモーターの仕様は以下の通り。

http://akizukidenshi.com/download/ds/towerpro/SG90_a.pdf

まとめると以下の通り。
・周波数 : 50Hz(1周期が 20ms)
・Duty Cycle 0.50ms : -90度回転
・Duty Cycle 1.45ms :   0度回転
・Duty Cycle 2.40ms : +90度回転
・電圧 : 4.8V ~ 5V
・回転速度 : 0.1s / 60度

4. 設計

(1) GPIOはどう使う?

ラズパイ公式ページの情報によれば、ハードPWMを使いたければ GPIO12,13,18,19を使えと記載されている。

https://www.raspberrypi.org/documentation/usage/gpio/README.md

なので…
今回は GPIO12 をサーボモーター制御のための PWM信号線として使う。

でも…
GPIO12の電圧は 3.3Vだ。
上記のモーターのデータシートには PWM信号線の電圧は 4.8V ~ 5Vと書いてあるがよいのか?

(2) モーターは別電源で駆動する。

消費電力の大きなモーターの電源をラズパイから取ると、ラズパイに大きな電流が流れて壊れてしまうかも…

この制限値はどこに書かれているのか?

公式ページでは見つけられなかったが、こちらのページ(↓)では
https://elinux.org/RPi_Low-level_peripherals#Power_pins
・3.3Vのピンからは合計 50mA
・5Vのピンからは合計 1A からラズパイの動作に必要な分を引いた残りだけ
と書かれている。

50mAといったら LED x 3個しか繋げちゃダメってことか?

よくわからないので…
消費電力の大きなデバイスを駆動するときには、ラズパイとは別に電源を用意した方がよさそうだ。

今回はモーター駆動用に 5Vの電源を別に用意 しよう。

5. 実装

・ラズパイとは別に、サーボモーター用に 5Vの電源を用意する。
・サーボモーターの GNDを ラズパイ側の GNDに繋ぐ。(GNDの電位を共通にするため)

6. マイコンで制御してみる!

今回も (23) 【1-3】マイコンで電子工作入門:LED点滅 と同じように RPi.GPIO を使用する。

(1) ターミナルを起動し、Python3を実行する。

python3

(2) 必要な Pythonモジュール(=パッケージ)を読み込む。

import RPi.GPIO as GPIO

(3) GPIOを初期化する。

GPIO制御関数で制御対象のピンを指定する際に、ピン番号ではなく GPIO番号を指定することにする。
・ピン番号指定: GPIO.BOARD
・GPIO番号指定: GPIO.BCM

GPIO.setmode(GPIO.BCM)

GPIO12を出力ポートとして使用する。

GPIO.setup(12, GPIO.OUT)

GPIO12を PWM(50Hz)として使用する。

pwm = GPIO.PWM(12, 50)
pwm.start(0)

(4) モーターを廻す。

0度

前述のモーターのデータシートに従えば、
・0度の Duty Cycleは 1.45ms
・周波数 50Hz(=20ms)

なので、設定するパルス幅は…
1.45 / 20 = 7.25[%]

pwm.ChangeDutyCycle(7.25)


ここをホームポジションとして記憶する。


+90度

前述のモーターのデータシートに従えば
・+90度の Duty Cycleは 2.4ms
・周波数 50Hz(=20ms)

なので、設定するパルス幅は…
2.4 / 20 = 12[%]

pwm.ChangeDutyCycle(12)


半時計周りに 90度回転した。


-90度

前述のモーターのデータシートに従えば、
・-90度の Duty Cycleは 0.5ms
・周波数 50Hz(=20ms)

なので、設定するパルス幅は…
0.5 / 20 = 2.5[%]

pwm.ChangeDutyCycle(2.5)


時計周りに 180度回転した。


+45度

前述のモーターのデータシートに従えば、
・0度の Duty Cycleは 1.45ms
・+90度の Duty Cycleは 2.4ms
・周波数 50Hz(=20ms)

なので、パルス幅は…
+45度の Duty Cycleは
(2.4 – 1.45) / 90 x 45 + 1.45 = 1.925[ms] ※リニアだとすれば

なので、設定するパルス幅は…
1.925 / 20 = 9.6[%]

pwm.ChangeDutyCycle(9.6)


確かに 45度の位置まで回転した。

(5) 終了処理

pwm.stop()
GPIO.cleanup()

問題発生!

意図した通り、確かにモーターは指定した角度に回転してくれた。

でも…

勝手に動く…

ビリビリと音を立てて振動したり、突然豪快に 180度回転したりする。
パルスの立ち上がりタイミングや幅など時間軸方向で乱れる ジッタ というやつか?

ToDo: ACアダプターが 5V 1.5Aの物を使用していた。電流値 2Aなどの大きな物に変更して試してみる。

回りすぎて振り切って戻ってこなくもなった。
モーターが動かなくなり「壊れたか…」と覚悟したが、これは無理やり手で回して復旧させた。

ひょっとしてソフトPWMで動いている?

RPi.GPIO.PWM(12, 50)

RPi.GPIOモジュールのこの使い方では、ハード PWM制御をしてくれていない?

オシロで PWM信号線を覗き見ると 20ms周期でパルスが流れ、パルス幅が乱れているようには見えない。
こんな状態でも不安定&豪快に回転したりする。

・パルス幅が一定範囲からはみ出したとき、
・信号の立ち上がりのタイミングがずれたとき、
にトリガーをかけてオシロの表示を停止させてみたいが、できない…
ソフトPWMで本当におかしな信号を出力しているのか? が確認できない…

(5) ハードウェアPWMでモーターを廻す。【仕切り直し】

RPi.GPIOの中身を未確認だが、RPi.GPIO.PWM() はソフトPWMであることはほぼ間違いない。

そこで…
wiringpi でハード PWMが出来るという情報に辿り付き、これを試してみる。

Super Userで Pythonを起動する。

sudo python

Python Shellで以下を打ち込む。

import wiringpi

wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(18, wiringpi.GPIO.PWM_OUTPUT)
wiringpi.pwmSetMode(wiringpi.GPIO.PWM_MODE_MS)
wiringpi.pwmSetRange(1024)
wiringpi.pwmSetClock(375)

wiringpi.pwmWrite(18, 74) # 0deg. (1024 x 7.25% = 74)

wiringpi.pwmWrite(18, 123) # +90deg. (1024 x 12% = 123)

wiringpi.pwmWrite(18, 26) # -90deg. (1024 x 2.5% = 26)

・PWM_MODE_MS : PWM周波数固定モードを選択する。 参考情報
・pwmSetRange(1024) : Duty Cycle = 100% のときに 1024とする。
・pwmSetClock(375) : PWM周波数 = ラズパイ内蔵PWMコントローラの動作クロック周波数{19.2MHz} / (PWM信号の周波数{50Hz} x レンジ{1024})

今度はモーターが ピタッ と止まり、ビリビリしびれたような動きは全く見せない。
これがハード PWMの安定感だ。すばらしい!

(6) もし自分でちゃんと作りたければ…

ラズパイに搭載されているマイコンの仕様書を見て、PWMコントローラのドライバを自作する。(P.138 ~)

https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf

wiringpi の中ではこの制御をしているのだろうから、プログラムの中身を覗いて制御方法を理解するのもよい。

いつか余裕が出来たらやってみよう。

7. 所感

今回はモーターがおかしな挙動を見せたので、不良品なのではないかと疑ってしまった。
実際にはラズパイのソフトウェア PWMの不安定さがモーターの誤作動となって表れていた。
※近いうちに「5V出力昇圧DCDCコンバーター」を使ってPWM信号の電圧を上げて実験してみよう。

それに比べてハードウェア PWMは安定感がすばらしい!
いつかラジコンカーのステアリングに使ってみたい。

また、PWMを使えば、アナログデバイスをデジタル信号で制御できる。
例えば、
・LEDの明るさを好きに変える。
・モーターの回転速度を好きに変える。
など、各デバイスに入力する電圧を変えなくても制御できてしまう。

いつかきっと何かの役に立つだろう。

いつかきっとラジコンが作りたくなるはず…

参考情報

ありがとうございます。 m(_ _)m
https://www.slideshare.net/YoshimotoYukiyoshi/raspberry-pipwm

連載

Raspberry Piの初期設定から簡単な動作実験まで、以下はマイコン制御入門の連載です。
(21) 【連載1-1】マイコンで電子工作入門:選定
(22) 【連載1-2】マイコンで電子工作入門:ラズパイ初期設定
(23) 【連載1-3】マイコンで電子工作入門:LED点滅
(24) 【連載1-4】マイコンで電子工作入門:時報を作る
(26) 【連載1-5】マイコンで電子工作入門:サーボモーターを廻す
(27) 【連載1-6】マイコンで電子工作入門:合成音声で時報 ←次回


(26) 【連載1-5】マイコンで電子工作入門:サーボモーターを廻す」への2件のフィードバック

  1. 通りすがり

    サーボへの信号レベルが足らないです。
    ソフトPWMは悪くないかと、

    返信
    1. papa 投稿作成者

      ありがとうございます。
      ソフトPWM, ハードPWMともに出力信号レベルは 3.3Vなのです…
      このため、時間軸の方を疑ってしまうのです。

      返信

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)