はじめに
私は、電子工作初心者ですが、Raspberry Pi から、サーボモータ4つを動かすことができるようになったので、その時の手順をまとめてみます。
サーボモータ1個であれば、いろいろなブログを参考にして、その通りに動かすことができました。
サーボモータを2個以上動かすときは電源の確保が必要で、何が必要なのか、どんな物を購入する必要があるのか悩んでしまい、なかなか進まなかったのですが、手元にあるUSB充電器や、スマホ用モバイルバッテリーが使えることが分かり解決しました。
使用したプログラミング言語はPythonです。PythonからGPIO制御するライブラリがいくつかあり、どれを使ったらよいのか迷いましたが、いくつか使ってみて、pigpioに落ち着きました。
前提条件/動作環境
ラズパイ:Raspberry Pi 3 B+
OS:Raspbian
プログラミング言語:Python 3.7
Pythonライブラリ:pigpio
サーボモータ:マイクロサーボSG90
電源:家庭用コンセント接続のUSB充電器、スマホ用モバイルバッテリー
要約/ポイント
サーボモータ1個であれば、ラズパイからサーボモータへ電気を供給して、動かすことが可能。
サーボモータ2個以上の場合、ラズパイから供給できる電流が足りなくなるので、外部電源が必要。
マイクロサーボSG90は、電圧4.8~5Vで動作する。必要な電流は、いくつかのブログを見ると、だいたい、通常130~200mA、最大500mAとか1.2Aの模様。
今回、USB充電器やスマホ用モバイルバッテリーのUSBポートを使用した。USBの規格では電圧5Vに決められている。電流は、今回使ったバッテリーだと、1Aと2.1Aの2つの口があった。
今回試していないが、通常単3電池(1.5V)を3個使用し1.5V×3個=4.5V、充電式単3電池(1.2V)を4個使用し1.2V×4個=4.8Vでも良さそう。
サーボモータを動かすためには、PWMという制御信号を送る必要があり、そのための仕組みがラズパイやPythonライブラリに用意されている。
サーボモータ1個を動かす(ラズパイ電源)
pigpioインストール
PythonからラズパイのGPIOを制御するため、pigpioというライブラリを使いました。
次のコマンドでインストールできました。
$ pip install pigpio
インストールしたpigpioを使うためには、事前に常駐させておく必要があるので、次のコマンドを実行しておきました。
$ sudo pigpiod
動作確認
ラズパイで用意されているハードウェアPWMを使用するため、GPIO13を使用しました。ハードウェアPWMについては、次のブログを参考にしました。
Raspberry PiのハードウェアPWMをpigpioで出力する - Qiita
・ラズパイではハードウェアPWMに対応しているピンが4つあり、独立に制御できるのは2組ずつです。
・PWM Channel 0 : GPIO12、GPIO18
・PWM Channel 1 : GPIO13、GPIO19
プログラムは、こんな感じです。上手く動きました。
import pigpio
import time
SERVO_PIN = 13
pi = pigpio.pi()
try:
while True:
pi.hardware_PWM(SERVO_PIN, 50, int(1000000*1.45/20))
time.sleep(3)
pi.hardware_PWM(SERVO_PIN, 50, int(1000000*2.4/20))
time.sleep(3)
pi.hardware_PWM(SERVO_PIN, 50, int(1000000*0.5/20))
time.sleep(3)
except KeyboardInterrupt:
pass
pi.hardware_PWM(SERVO_PIN, 50, 0)
pi.stop()
サーボモータ1個を動かす(外部電源)
サーボモータ2個を動かすためには、外部電源が必要になるので、外部電源を使う練習をしてみました。
外部電源としてUSB充電器を使っています。USBの仕様が次のように決められているので、サーボモータを動かすのにちょうどよいと考えました。
ユニバーサル・シリアル・バス - Wikipedia
・USB2.0 電圧5V、電流500mA
・USB3.x 電圧5V、電流900mA
プログラムは、ラズパイ電源で動かした時と同じです。上手く動かすことができました。
上記では、ハードウェアPWMを使いましたが、ソフトウェアPWMでも動かしてみました。
次のプログラムで、動かすことができましたが、高周波が少し不安定になってしまった気もしました。
import pigpio
import time
SERVO_PIN = 13
pi = pigpio.pi()
try:
while True:
pi.set_servo_pulsewidth(SERVO_PIN, 1450)
time.sleep(3)
pi.set_servo_pulsewidth(SERVO_PIN, 2400)
time.sleep(3)
pi.set_servo_pulsewidth(SERVO_PIN, 500)
time.sleep(3)
except KeyboardInterrupt:
pass
pi.set_servo_pulsewidth(SERVO_PIN, 0)
pi.stop()
サーボモータ2個を動かす
ハードウェアPWMを使うため、GPIO12,13に接続しました。
プログラムは次です。サーボモータ1個のときと同じ処理を、2つのサーボモータに対して行っています。
少し不安定ですが、動かすことができました。
import pigpio
import time
SERVO_PIN_1 = 13
SERVO_PIN_2 = 12
pi = pigpio.pi()
try:
while True:
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*1.45/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*1.45/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*2.4/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*2.4/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*0.5/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*0.5/20))
time.sleep(1)
except KeyboardInterrupt:
pass
pi.hardware_PWM(SERVO_PIN_1, 50, 0)
pi.hardware_PWM(SERVO_PIN_2, 50, 0)
pi.stop()
サーボモータ3個を動かす
サーボモータ3個を動かそうとすると、また電源の壁がありました。
今回使ったUSB充電器では、電流が1Aまでで、サーボモータ3個を動かすのは無理でした。
なので、USB充電器でサーボモータ2個を動かし、ラズパイ電源でサーボモータ1個を動かしました。
あと、USB充電器よりもスマホ用モバイルバッテリーの方が扱いが楽だったので、モバイルバッテリーを使っています。
サーボモータ制御用のGPIOピンですが、GPIO 13,12をハードウェアPWMで使用、GPIO 17をソフトウェアPWMで使用しています。
プログラムを次のようにしました。サーボモータが増えたので、処理が長くなりましたが、やっていることは今までとあまり変わりませんでした。
import pigpio
import time
SERVO_PIN_1 = 13
SERVO_PIN_2 = 12
SERVO_PIN_3 = 17
pi = pigpio.pi()
try:
while True:
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*1.45/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*1.45/20))
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_3, 1450)
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*2.4/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*2.4/20))
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_3, 2400)
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*0.5/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*0.5/20))
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_3, 500)
time.sleep(1)
except KeyboardInterrupt:
pass
pi.hardware_PWM(SERVO_PIN_1, 50, 0)
pi.hardware_PWM(SERVO_PIN_2, 50, 0)
pi.set_servo_pulsewidth(SERVO_PIN_3, 0)
pi.stop()
サーボモータ4個を動かす
サーボモータ4個を動かそうとすると、またまた電源の壁がありました。
モバイルバッテリーだとサーボモータ2個まで、ラズパイ電源だと1個までなので、最大3個までしか動かせられません。
でも、モバイルバッテリーを見ると、USBポートが2つあったので、各ポートでサーボモータ2個を動かし、計4個動かすことにしました。結果、上手く動きました。
サーボモータ制御用のGPIOピンですが、GPIO 13,12をハードウェアPWMで使用、GPIO 27,23をソフトウェアPWMで使用しています。
プログラムを次のようにしました。これも、サーボモータの増加に伴い処理が増えただけで、やっていることは同じです。
import pigpio
import time
SERVO_PIN_1 = 13
SERVO_PIN_2 = 12
SERVO_PIN_3 = 27
SERVO_PIN_4 = 23
pi = pigpio.pi()
try:
while True:
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*1.45/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*1.45/20))
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_3, 1450)
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_4, 1450)
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*2.4/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*2.4/20))
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_3, 2400)
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_4, 2400)
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_1, 50, int(1000000*0.5/20))
time.sleep(1)
pi.hardware_PWM(SERVO_PIN_2, 50, int(1000000*0.5/20))
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_3, 500)
time.sleep(1)
pi.set_servo_pulsewidth(SERVO_PIN_4, 500)
time.sleep(1)
except KeyboardInterrupt:
pass
pi.hardware_PWM(SERVO_PIN_1, 50, 0)
pi.hardware_PWM(SERVO_PIN_2, 50, 0)
pi.set_servo_pulsewidth(SERVO_PIN_3, 0)
pi.set_servo_pulsewidth(SERVO_PIN_4, 0)
pi.stop()
トラブル対応
作業中、躓いたところを書いておきます。
pigpioインストールエラー
Pythonライブラリのpigpioをインストールしようとして、試行錯誤、次のようなコマンドを実行していました。
$ pip install pygpio
そして、Pythonの対話形式モードから使おうとすると次のエラーが発生しました。
In [1]: import pygpio
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-462f3c478519> in <module>
----> 1 import pygpio
~/.pyenv/versions/3.7.3/lib/python3.7/site-packages/pygpio/__init__.py in <module>
1 from __future__ import absolute_import
2
----> 3 from Adafruit_GPIO.GPIO import *
ModuleNotFoundError: No module named 'Adafruit_GPIO'
原因は、ライブラリ名のスペルミスで、誤「pygpio」、正「pigpio」でした。
pigpioインポートエラー
上手くインストールできた後、Pythonからpigpioをインポートしようとすると、次のエラーが発生することがありました。
Can't connect to pigpio at localhost(8888)
Did you start the pigpio daemon? E.g. sudo pigpiod
Did you specify the correct Pi host/port in the environment
variables PIGPIO_ADDR/PIGPIO_PORT?
E.g. export PIGPIO_ADDR=soft, export PIGPIO_PORT=8888
Did you specify the correct Pi host/port in the
pigpio.pi() function? E.g. pigpio.pi('soft', 8888)
これは、事前にpigpiodを起動していないからでした。次のコマンドを実行してから、インポートすると解決です。
$ sudo pigpiod
おわりに
今回、Raspberry Pi から、サーボモータを1個、2個、3個、4個と増やして動かしてみました。電子工作の経験がなく、電源管理に悩まされましたが、動かすことができました。ものが動くと達成感がありますね。
サーボモータ4個を動かした際、4つ足のロボットを作れるかも、と無邪気に素人考えをしてしまいました。
ためしに作成して、何となく歩行した気がするので、動画も作成してみました。良かったらご覧ください。
参考サイト
Raspberry Pi GPIO Pinout
・ラズパイのGPIOピンの配置を確認しました。
マイクロサーボ9g SG-90: パーツ一般 秋月電子通商-電子部品・ネット通販
・マイクロサーボSG90の主な仕様が書かれていて助かりました。
Raspberry Piでサーボモーター動作
Raspberry PiのハードウェアPWMをpigpioで出力する - Qiita
・サーボモータを制御するのに参考にさせていただきました。
ユニバーサル・シリアル・バス - Wikipedia
・USBの電源供給仕様を確認しました。