Raspberry Pi Picoでサーボモーターを動かす|SG90を安全に制御する方法(電源・可動域調整・複数接続)

目次

はじめに

今回は Raspberry Pi Pico とサーボ拡張ボードを使い、複数のサーボモーターをまとめて制御する方法を解説します。記事内の実演は「2軸カメラ(パン・チルト)」としてサーボ2個を動かしますが、このボードの本来の用途はそれだけではありません。

最大16台のサーボモーターを1枚の基板に接続できます。

ロボットアーム、四足歩行ロボット、カメラ雲台、展示ギミックなど、“たくさんの可動部をまとめて動かしたい” ときに非常に便利なモジュールです。

ボードの役割

このサーボボードは「サーボを制御するIC」ではありません。役割は次の2つです。

  1. サーボへ十分な電源を供給する
  2. PicoのPWM信号を最大16個のサーボへ配線する

つまり構成はこうなります

Raspberry Pi Pico(制御本体)
        ↓
PWM信号
        ↓
サーボ拡張ボード(配線と電源供給)
        ↓
最大16個のサーボ

Pico自体がサーボコントローラの役割を持ち、ボードは「拡張コネクタ」と「電源分配器」として働きます。

なぜこのボードが必要か

サーボは見た目より電力を消費します。9gサーボ1個でも起動時に700mA近く流れることがあります。
もし直接Picoへ複数接続すると

  • 電圧降下
  • 誤動作
  • USB切断
  • 最悪はPico破損

が起きます。このボードは外部電源からサーボへ直接5Vを供給し、Picoは「信号だけ」を送るため安全に多台数制御ができます。

電源供給について

このボードは4.5~26Vの外部電源から電源供給が可能です。自動的に5Vに降圧されるため、安全に使えます。
また、外部電源供給のスイッチもついています。ただし、picoをUSBで接続している場合は注意が必要です。

下部にジャンパpinがついていますので必要に応じて設定を変更してください。以下のような記載があるはずです。
 ・VIN5V:外部電力の5Vのことです
 ・VIN_CFG:モーターを動かすための入力電圧です
 ・Pico_VSYS:Picoを動かすための入力電圧です
 ・USB:PicoにつないでいるUSB電源です
 ・VSYS:PicoのVSYS端子から供給される電源です。


つまり、PicoにUSBを繋がず、外部電源ですべてをまかないたい場合は、
VIN5VとVIN_CFG を接続。VIN5VとPico_VSYS を接続
、となります。
USBを繋いでいる場合は、
VIN5VとVIN_CFG を接続。USBとPico_VSYS を接続、となります。

サーボは「角度」で動いていない(復習)

サーボは内部にモーターと制御回路を持っており、Picoから送られる「パルス信号の長さ」で位置が決まります。
周期は50Hz(20ms)

パルス幅位置
約0.6ms左端
約1.5ms中央
約2.2ms右端

つまりPicoがやっているのは特定の長さの信号を送り続けることです。

サンプルコード

0番と1番にSG90サーボを接続した状態です。以下のコードをそのままコピーすれば動きます。

from machine import Pin, PWM
import time

pan  = PWM(Pin(0))
tilt = PWM(Pin(1))

pan.freq(50)
tilt.freq(50)

def set_angle(servo, angle):
    duty = int(1639 + (angle/180)*6553)
    servo.duty_u16(duty)

while True:
    set_angle(pan, 90)
    set_angle(tilt, 90)
    time.sleep(2)

    set_angle(pan, 40)
    set_angle(tilt, 140)
    time.sleep(2)

    set_angle(pan, 140)
    set_angle(tilt, 40)
    time.sleep(2)

SG90が震える・ジー音が出る原因

サーボは「180°回る」と書かれていても実際には個体差があり、限界位置が異なります。
限界を超えるパルスを与えると:

  • ジーという音
  • 微振動
  • 発熱

が起きます。これはギアを押し続けている状態で、破損の原因になります。

可動域(キャリブレーション)の調整方法

以下を動かして
 ・動き始める最小値
 ・それ以上回らない最大値
を記録しておいてください。

from machine import Pin, PWM
import time

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

def pulse(us):
    duty = int(us * 65535 / 20000)
    servo.duty_u16(duty)

while True:
    for p in range(500, 2500, 50):
        print(p)
        pulse(p)
        time.sleep(0.5)

記録した最大、最小値を以下のように設定すればサーボを壊すことなく使えるはずです。

from machine import Pin, PWM
import time

PAN_MIN_US  = 650
PAN_MAX_US  = 2150

TILT_MIN_US = 700
TILT_MAX_US = 2100

def set_angle(servo, angle, min_us, max_us):
    angle = max(5, min(175, angle))
    us = min_us + (max_us - min_us) * angle / 180
    duty = int(us * 65535 / 20000)
    servo.duty_u16(duty)

servo_tilt = PWM(Pin(1))
servo_tilt.freq(50)

servo_pan = PWM(Pin(0))
servo_pan.freq(50)

set_angle(servo_tilt, 90, TILT_MIN_US, TILT_MAX_US)
set_angle(servo_pan, 90, PAN_MIN_US, PAN_MAX_US)

今回できること

この段階でのようなアイデアが浮かびます

  • カメラ雲台
  • 展示装置
  • ロボット関節
  • 多軸ギミック

まとめ

サーボモータは動きを目視でき、成功体験を得やすいパーツです。
次回は超音波距離センサを接続し、物体の方向へ自動的に向くカメラシステム を作り、センサの連携を試します。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次