こんにちは、あろっちです。
今回は、Raspberry Pi Picoを使って小型サーボモーター「SG90」を制御する方法をご紹介します。
本記事はArduinoやMicroPythonの環境設定などは準備済みであることを前提としています。
サーボモーター(SG90)について
特徴
• 動作電圧: 5V
• 回転角度: 0°~180° (※モデルによりますが、本記事はこのモデルが対象)
• 制御方式: PWM信号 (50Hz)
ピン色 | 機能 |
---|---|
茶 | GND |
赤 | 電源 (5V) |
橙 (または黄) | 信号 (PWM) |

PWMのピン色が上のものは橙、下のものは黄です。色に微妙な個体差がありそうなので上表では色を併記しています。
SG90はPWM信号のデューティー比(パルス幅)によって回転角度を制御します。以下はその対応関係です。
ArduinoのServoクラスでは角度を0°から180°で指定しますが、SG90の回転角度との対応関係も示しています。
SG90の回転角度 (°) | デューティー比 (%) | パルス幅 (ms) | Arduinoの角度 (°) |
---|---|---|---|
-90 (最小角) | 約2.5% | ~0.5ms | 0 |
0 (中心) | 約7.25% | 1.45ms | 90 |
90 (最大角) | 約12% | ~2.4ms | 180 |
パルス幅を0.5msから2.4msの範囲で可変させることで、SG90サーボモーターの回転角度(最小角度から最大角度まで)を制御できます。
参考資料:
準備
使用するもの

配線方法
以下の表を参考に、Raspberry Pi Picoとサーボを接続します。
Raspberry Pi Pico | SG90 | 用途 |
---|---|---|
VBUS | 赤 | 電源 |
GND | 茶 | グラウンド |
GPIO2 | 橙 (または黄) | 信号 (PWM) |
GPIOピンについては、どのピンを使用しても構いませんが、本記事のプログラムではGPIO2を使用します。もし別のGPIOピンを使用する場合は、プログラム内で対応するピン番号を変更してください。
プログラム
SG90を0度から180度までスイープ(往復運動)します。
MicroPython
MicroPythonファームウェアのインストール方法は以下の記事を参照してください。
from machine import Pin, PWM
from time import sleep
# GPIO2をPWMとして使用
servo_pin = Pin(2)
servo = PWM(servo_pin)
servo.freq(50) # サーボモーターは50Hzで制御
# 事前計算した定数
MIN_DUTY = 500 * 65535 // 20000 # 500μsを16ビットスケールで
MAX_DUTY = 2400 * 65535 // 20000 # 2400μsを16ビットスケールで
DUTY_RANGE = MAX_DUTY - MIN_DUTY # 差分を定数として計算
# 角度をデューティー比に変換する関数
def angle_to_duty(angle):
return int(MIN_DUTY + DUTY_RANGE * angle // 180)
# サーボの動きをスイープ
try:
while True:
# 0度から180度まで
for pos in range(0, 181): # 0から180の1度刻み
servo.duty_u16(angle_to_duty(pos))
sleep(0.015) # 応答性に合わせて調整(15ms)
# 180度から0度まで
for pos in range(180, -1, -1): # 180から0の1度刻み
servo.duty_u16(angle_to_duty(pos))
sleep(0.015) # 応答性に合わせて調整(15ms)
except KeyboardInterrupt:
# 終了前にサーボを初期位置に戻す
print("サーボを初期位置(0度)に戻しています...")
servo.duty_u16(angle_to_duty(0)) # 0度
sleep(0.5) # 少し待機
# プログラムを停止する際にPWMを無効化
servo.deinit()
print("サーボ制御を終了しました。")
Arduino
Raspberry Pi Pico/RP2040ボード(Arduino-Pico)を使用します。
/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.
modified 28 May 2015
by Michael C. Miller
modified 8 Nov 2013
by Scott Fitzgerald
http://arduino.cc/en/Tutorial/Sweep
*/
#include <Servo.h>
Servo myservo;
void setup() {
myservo.attach(2, 500, 2400); // attaches the servo on GIO2 to the servo object
}
void loop() {
int pos;
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
ArduinoのRaspberry Pi Pico/RP2040ボード(Arduino-Pico)で提供されるServoクラスでは、制御信号のリフレッシュ間隔(REFRESH_INTERVAL)が20ms(50Hz)に固定されているため、今回動かすSG90はこのクラスをそのまま利用できます。
ただし、Servoクラスのデフォルト定数(min: 1000μs、max: 2000μs)は、SG90のパルス幅(min: 500μs、max: 2400μs)と異なるため、attach関数で明示的に指定します。
まとめ
今回は、Raspberry Pi PicoとSG90サーボモーターを使った基本的な制御方法を紹介しました。
こちらは面白いかなという遊び心で作ってみました。
サーボモーターを操作して、透明OLEDの画面を滑らかに起こす仕組みは、本記事のプログラムで実装したロジックを使用しています。サーボは0度(水平方向)から90度(垂直方向)まで動作させています。
Picoのリアルタイム性を活かし、サーボモーターを組み込んだプロジェクトを楽しんでみてください!
関連記事
当ブログのマイコン記事です。ぜひご覧ください。
コメント