ラズベリーパイ3でサーボモーターSG90を使ってみた

リーズナブルでよく使われていそうな「SG90」というサーボを買ってラズパイで動かしてみた。
標準入力で角度を指定すると、サーボがその角度動くようにしてみた。
割とすんなり動いて感動しました。

デジタル・マイクロサーボ SG90 (5個)

デジタル・マイクロサーボ SG90 (5個)

SG90とラズパイの配線

ラズベリーパイ3とSG90の配線

上図のように配線した。サーボ制御用のPWM出力のピンをBCMの17番にしている。

ラズパイのGPIOからサーボを直接駆動させるとラズパイに良くないみたいな記事があった気がする。理由は理解できていないが、モータードライバを介してサーボを動かした方がよいかもしれない。(本プログラムでサーボは動くが、動かすとガタガタする。)

サーボの角度制御

SG90のデータシート

秋月にのっていたSG90のデータシートより引用

SG90のデータシートによると、50HzのPWM信号に設定した場合、デューティー比とサーボの角度の関係は、

  • 0.5ms (デューティー比1%)   ⇒ -90°
  • 1.45 ms (デューティー比2.9%)  ⇒ 0°
  • 2.4 ms (デューティー比4.8%)  ⇒ 90°

のようになっている。

デューティー比とサーボの角度は比例関係なので、動かしたいサーボの角度をX[deg]とすると、それに対応するデューティーサイクルY[ms]は以下の式で求まる。

Y = (12-2.5)/180*(X + 90) + 2.5

ラズパイにこの値を渡せば、サーボを動かすことができる。

サーボを動かすプログラム

標準入力でサーボの角度を指定して、サーボを動かせるようにしてみた。while文を使い、繰り返しサーボを動かせるようになっている。endを入力すればサーボは止まる。

動かすと少しガタガタするが、指定した通りの角度にサーボが動く。
次はモータードライバを使って動かしてみたい。

import time
import RPi.GPIO as GPIO
import sys  # 引数取得

# pin number
PIN_servo = 17   # for servo

GPIO.setmode(GPIO.BCM)      # GPIOへアクセスする番号をBCM番号で指定することを宣言
GPIO.setup(PIN_servo, GPIO.OUT)     # 出力ピンに設定

# servo setup
servo = GPIO.PWM(PIN_servo, 50)
servo.start(0)

# サーボの角度を初期化(0degにする、とりあえず)
time.sleep(0.5)
servo.ChangeDutyCycle(7.25)
time.sleep(0.5)

# servo -90deg <= x <= 90deg
# -90deg -> 0.5ms, 90deg -> 2.4ms (from spec. sheet)

# whileで繰り返し処理
while True:
    # 標準入力によりサーボの角度を指定
    print('サーボの角度(-90~90deg)を指定してください。endを入力すると止まります。')
    input_num = input('>')

    if input_num != 'end':
        # サーボを動かす
        move_servo_msec = (12-2.5)/180*(int(input_num) + 90) + 2.5 
        servo.ChangeDutyCycle(move_servo_msec)
        time.sleep(0.5)
    else:
        break

# while文抜けたらサーボストップ
servo.stop()
GPIO.cleanup()