ラズベリーパイやラズベリーパイPicoでサーボモーターを使う方法について、PWMの解説もまじえて紹介します。

サーボモーターとは

指定した位置まで回転するモーター

サーボモーターはモーターの一種で、「30度」などと指定した角度だけ回転させたり、指定した位置にぴったり停止させることができる高精度な位置決め性能を持つモーターです。交流電源によって駆動できるのACサーボモーターと、直流電源によって駆動できるDCサーボモーターがあります。

ACサーボモーターは産業用ロボットなどに使用され、小型のロボットや電子工作ではDCサーボモーターがよく使われます。DCサーボモーターには電源とPWM入力の端子がついています。

回り続けるサーボモーター!?

サーボモーターは回転角が0〜180度などに制限されている通常モデルと、通常のモーターのように360度を超えて回転し続けるタイプ(ローテーションサーボ)の2種類があります。

 

回転角度の指定はPWMで

サーボモーター内部に電子回路があり、あとで説明するPWM信号を受け取ると、その信号の特徴に合わせた角度まで回転するしくみになっています。

使い方

電源(5V / GND)をつなぎ、PWM入力ピンをGPIOにつなぎます。

Raspberry Pi サーボモーター
5V 5V
GND GND
GPIO PWM IN

プログラムではGPIOを出力モードにし、回転角に応じたPWM信号をGPIOピンから出力します。

 

PWM (Pulse Width Modulation)

擬似的なアナログ波

ラズパイはコンピューターなので0と1しか扱えません。ところが機器によっては0.3や0.8などが必要な場合があります。

このような中間の値が必要な時に使うのがPWMです。PWMは0と1のデジタル出力を高速にOn/Offすることにより、擬似的にアナログの波を生成することができます。

wikipedia.orgより

Duty比

PWMの設定で必要なのがDuty比(Duty Cycle)です。デジタル出力のOn/Offを1つ見た時、Onの割合を%で表したものです。

このDuty比をいくつにするかで、サーボモーターが何度回転するかが決まります。

wikipedia.orgより

周波数

PWMの設定でもう1つ必要なのが周波数(Frequency)です。デジタル出力の1回のOn/Offを1セットとして、これが1秒間に何回あるか、を表したものです。記号はHz(ヘルツ)、単位は (/s)です。

ロボットや電子工作で使われるDCサーボモーターは1秒間に50回、つまり50Hzに設定すると動く仕様のものが多いです。

 

周期

デジタル出力の1回のOn/Offが、どれぐらいの時間で完結するかを周期といいます。

1秒間に50回の50Hzだと、1周期は1s/50 = 0.02s (20ms) となります。

 

Raspberry Piでの使い方

使用するサーボは以下です。
マイクロサーボ SG-90

電子回路

電源、および使用するGPIOを接続します。

Raspberry Pi サーボ
5V 5V
GND GND(茶)
GPIO 18 PWM IN

Pythonスクリプト

import RPi.GPIO as GPIO
from time import sleep

servo = 18
frequency = 50

angle_0 = 2.5 / 20 * 100  #duty: 12.5%
angle_90 = 1.5 / 20 * 100  #duty: 7.5% 
angle_180 = 0.5 / 20 * 100  #duty: 2.5%

GPIO.setmode(GPIO.BCM)
GPIO.setup(servo, GPIO.OUT)

pwm = GPIO.PWM(servo, frequency)

pwm.start(angle_0)
sleep(1)
pwm.ChangeDutyCycle(angle_90)
sleep(1)
pwm.ChangeDutyCycle(angle_180)
sleep(1)
pwm.ChangeDutyCycle(angle_0)
sleep(1)

pwm.stop()
GPIO.cleanup()

 

Raspberry Pi Picoでの使い方

使用するサーボは以下です。
マイクロサーボ SG-90

電子回路

電源、および使用するGPIOを接続します。

Pico サーボ
5V 5V
GND GND
GPIO 28 PWM IN

MicroPythonスクリプト

from machine import PWM, Pin
from time import sleep

servo = PWM(Pin(28))
servo.freq(50)

angle_0 = int(2.5 / 20 * 65536)
angle_90 = int(1.5 / 20 * 65536)
angle_180 = int(0.5 / 20 * 65536)

servo.duty_u16(angle_0)
sleep(1)
servo.duty_u16(angle_90)
sleep(1)
servo.duty_u16(angle_180)
sleep(1)

servo.duty_u16(0)

 

動作チェック

サーボモーターが0度の位置から、90度、180度と回転して0度に戻りましたか?

 

おわりに

いかがでしたでしょうか? サーボモーターが使えるとできることの幅が広がるので、ぜひ使ってみてください😊

関連記事:使い方