はじめに
Raspberry Pi Pico でサーボモーターを簡単に制御してみます。PWM(Pulse Width Modulation)制御を利用します。
サーボモーターの動作原理
サーボモーターは、PWM信号のデューティ比(パルス幅)によって回転角度を制御するモーターです。
一般的な特徴は以下です。
・50Hz(周期20msec)のPWM信号を使用する
・パルス幅が1~2msecで回転角度を決定する
例えば
・1msec → 最小角度0°
・1.5msec → 中間角度90°
・2msec → 最大角度180°
PWM信号のパルス幅を変化させることで、サーボモーターの角度を指定できます。
サーボモータの内部構造
一般的な サーボモーター(例: SG90, MG996R)は、以下の4つの主要部品で構成されています。
DCモータ(駆動部)
・サーボの原動力となる小型のブラシ付きDC(直流)モーター
・PWM信号によって制御回路がモーターの回転方向と速度を決定
減速ギア(ギアボックス)
・DCモーターは回転速度が速すぎるため、内部のギア減速機構を使ってトルクを増幅し、適切な速度に調整する
・プラスチック製(軽量だが耐久性が低い)や、金属製(耐久性が高く強力)などの種類がある。
ポテンショメータ(フィードバック機構)
・サーボ内部の軸の回転角度を検出するための可変抵抗(ポテンショメータ)
・軸が回るとポテンショメータの抵抗値が変化し、現在の角度情報が制御回路に送られる
制御回路(サーボドライバ)
・受信したPWM信号を解析し、目標角度を判断
・現在のポテンショメータの値と比較し、DCモーターを正しい角度まで動かすよう制御
サーボモーターの種類
標準RC(ラジオコントロール)サーボ(一般的な角度制御)
・制御範囲 : 0 ~ 180°(270°)
・角度を保持し続ける
・ラジコン、ロボット、アームに最適
連続回転サーボ(360°回転サーボ)
・回転角度ではなく回転速度を制御
・ポテンショメータの代わりに速度制御
・ホイールロボットやコンベアなどに使用する
配線
配線はシンプルです
RaspberryPi Pico | サーボモーター |
VSYS(39番) | 赤線 |
GND(38番) | 茶線 |
GP15(20番) | 黄線 |

サーボモータを動かす
連続的に動きます。
from machine import Pin, PWM
from time import sleep
from math import floor
pwm = PWM(Pin(15))
pwm.freq(50)
duty = 0
pwm.duty_u16(duty)
sleep(0.1)
min_duty = 2500
max_duty = 8050
min_degrees = 0
max_degrees = 180
def degrees_to_duty(degrees):
# increment value per degree
duty_step = ((max_duty - min_duty) / max_degrees)
if degrees > max_degrees:
degrees = max_degrees
elif degrees < min_degrees:
degrees = min_degrees
# Get the duty value for the degrees
duty = floor((duty_step * degrees) + min_duty)
# Check value not out of bounds
if duty > max_duty:
duty = max_duty
elif duty < min_duty:
duty = min_duty
return duty
while True:
for degrees in range(min_degrees, max_degrees, 1):
print(degrees)
duty = degrees_to_duty(degrees)
pwm.duty_u16(duty)
sleep(0.1)
for degrees in range(max_degrees, min_degrees, -1):
print(degrees)
duty = degrees_to_duty(degrees)
pwm.duty_u16(duty)
sleep(0.1)
ポテンショメータをGP26に接続して角度を制御します。
from machine import Pin, PWM, ADC
from time import sleep
servo = PWM(Pin(15))
servo.freq(50)
pot = ADC(Pin(26)) # 可変抵抗をGP26に接続
def set_angle(angle):
min_pulse = 1000
max_pulse = 2000
pulse = int(min_pulse + (angle / 180) * (max_pulse - min_pulse))
duty = int((pulse / 20000) * 65535)
servo.duty_u16(duty)
while True:
value = pot.read_u16() # 0〜65535の範囲
angle = (value / 65535) * 180 # 0〜180度に変換
set_angle(angle)
sleep(0.1)
まとめ
今回の記事ではサーボモータを動かしてみました。可変抵抗はもちろん、加速度センサの値などを使って動かせば水平を出せたりすると思います。
紹介しているモータは非常に大きなトルクを発揮します。いろいろなことに使えると思いますのでぜひご検討ください。
コメント