はじめに
今回は Raspberry Pi Pico とサーボ拡張ボードを使い、複数のサーボモーターをまとめて制御する方法を解説します。記事内の実演は「2軸カメラ(パン・チルト)」としてサーボ2個を動かしますが、このボードの本来の用途はそれだけではありません。
最大16台のサーボモーターを1枚の基板に接続できます。
ロボットアーム、四足歩行ロボット、カメラ雲台、展示ギミックなど、“たくさんの可動部をまとめて動かしたい” ときに非常に便利なモジュールです。


ボードの役割
このサーボボードは「サーボを制御するIC」ではありません。役割は次の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)今回できること
この段階でのようなアイデアが浮かびます
- カメラ雲台
- 展示装置
- ロボット関節
- 多軸ギミック
まとめ
サーボモータは動きを目視でき、成功体験を得やすいパーツです。
次回は超音波距離センサを接続し、物体の方向へ自動的に向くカメラシステム を作り、センサの連携を試します。
コメント