Pico PR

【MicroPython】RaspberryPi Pico/Pico WでサーボモーターSG90を使う方法

記事内に商品プロモーションを含む場合があります

はじめに

RaspberryPi Pico / Pico Wで、サーボモーター(ラジコンサーボ)の「SG90」を使う方法を解説したいと思います。言語はMicroPythonを使います。

RaspberryPi Pico / Pico Wともにピン配列は同じなので、どちらのボードを使う場合でも記事の配線方法とプログラムがそのまま使えます。今回の記事ではPico Wを使って解説します。

ノーマルのRaspberryPiで動かす方法も解説しているので、RaspberryPi + PythonでSG90を動かしたい。という方はこちらの記事をご覧ください。

環境

この記事で使用する環境は以下の通りです。

環境 バージョンなど 備考
開発用PCのOS Windows11 Windows10でもOKです
言語 MicroPython
開発環境 Thonny 3.3.13
ボード RaspberryPi Pico

サーボモーター(ラジコンサーボ) SG90

SG90と付属品の画像
SG90 単三電池は比較用です。

今回の記事で使用するサーボーモーター(ラジコンサーボ)「SG90」です。

ラジコンサーボは、モータ・ギアボックス・制御基板などが1つのケースにまとめられたモーターで、ラジコンカーのステアリング・ラジコン飛行機の翼の操作・ホビーロボットの関節軸など、1回転中の特定の範囲を繰り返し動かすために使います。

配線も「電源・GND・PWM信号」の3本だけです。

SG90の電源は4.8Vですが、PWM信号は3.3Vでも反応してくれるので、RaspberryPiシリーズからPWM信号を直接接続できます。

項目 スペック
電圧 4.8V
動作範囲 180度(±90度)
トルク 1.8kgf・cm
付属品 サーボホーン3種
サーボ固定ねじ×2、ホーン固定ねじ×1

RaspberryPiとの接続

RaspberryPi Pico WとSG90を以下のように接続します。

ピン番号 RaspberryPi Pico 側 サーボモータ
34 GPIO28 PWM
38 GND GND (電池と共通化します)
電池+ 電源
電池 − GND (電池と共通化します)

Pico W ピンアサイン(Pin-Out)

Pico W公式サイトより引用

Picoピンアサイン(Pin-Out)

RaspberryPi Picoのピンアサイン(pinout)の画像

Pico公式サイトより引用

使用する部品

Pico W 本体

Raspberry Pi Pico W本体です。技適対応品かどうか心配…という方は、以下のページで出品者を「共立エレショップAセレクト」(国内の有名ショップ)にして購入してください。

¥1,720 (2024/04/07 20:28時点 | Amazon調べ)

電池ボックス

電源に使う電池用ボックスです。スイッチ付きで何かあってもすぐに電源を切れるので、安心して工作することができます。

記事では単4を使っていますが、容量の大きい単3タイプをお勧めします。単3でも単4でも電圧は変わりません。

電池ボックス(単4)

記事で使っている単4を3本使うタイプはこちらで購入しています。

エネループ

使い捨ての乾電池もいいですが、エネループなら4本充電時の電気代が約1円。モーター・ポンプなどの電池が消耗しやすい実験・工作におすすめです。

※ はじめて使う方は充電器とのセットがおすすめです

ジャンパワイヤ(自作用)

キットだと丁度いい長さや、色がない。という方は以下の配線がおすすめです。ジャンパワイヤとほぼ同じ固さの配線なので、切って曲げるだけで理想のジャンパワイヤが作れます。

プログラム概要

今回のプログラムの概要は以下の通りです。

  • PWMの設定をする。
  • サーボモータを動かす。

実行結果

後述するプログラムの実行結果です。サーボモータが「-90度」「0度」「+90度」の順で、3回動作します。

プログラムを実行して、サーボを-90度に動かしたときの画像
-90度
プログラムを実行して、サーボを0度に動かしたときの画像
0度
プログラムを実行して、サーボを+90度に動かしたときの画像
90度

全体コード

全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。

import machine
import time
from machine import PWM

# GP28をPWMとして使います
pwm  = PWM(machine.Pin(28, machine.Pin.OUT))

# サーボが動作可能な範囲です
ANGLE_RANGE = 180
# サーボに指定するPWMの時間の範囲です
TIME_RANGE  = 1.9
# サーボに指定できる最小の時間です
MIN_TIME    = 0.5
# サーボのPWMの周期時間です
CYCLE_TIME  = 20.0

# 
#  角度⇒PWM信号に変換する関数です
#
def moveServo(pwm, angle ):

    # 入力角度のチェックです。±90以外はエラーにします
    if  angle < -90  or angle > 90 :
        return False

    # 指定角度を、0~180の表現に変えます
    angle = angle + 90

    # 指定角度を、全体(180度)中の割合に変換します
    percent =  angle  / ANGLE_RANGE

    # 割合を時間の範囲に適応して、指定角度を動かす時間を計算します
    addTime = TIME_RANGE * percent

    # 時間範囲は0.5から始まるので0.5に指定角度の時間を足します
    time = MIN_TIME + addTime

    # 指定角度の時間を、20msecの周期中の割合(%)に変換します
    ratio = time / CYCLE_TIME
    
    # 16bit(0~65535)の値(整数)に変換します。
    ratio = (int)(65535 *  ratio)
    
    # 動作実行します
    pwm.duty_u16(ratio)

    return True

#
#  メイン処理
#

#周期を1秒間に50回(50Hz)に設定します
pwm.freq(50)

# -90度、0度,90度に3回動かします。
for i in range(3):

    # -90度
    moveServo(pwm,-90 )
    print("-90")
    time.sleep(2)
    
    # 0度
    moveServo(pwm, 0)
    print("0")
    time.sleep(2)

    # 90度
    moveServo(pwm, 90)
    print("90")
    time.sleep(2)
        

コードのポイント

周期の設定

PWMのピンと周波数を設定します。

秋月電子さんで公開されている「SG90のデータシート」に「50Hz」と記載されているため、PWMの周波数を50Hz(1周期20msec)に設定します。

#周期を1秒間に50回(50Hz)に設定します
pwm.freq(50)

SG90のデータシートの抜粋
SG90のデータシート(抜粋)

Duty比の作成

サーボ角度はPWMのDuty比を変えることで指定できます。角度の変更は何度も実行する処理のため、関数にまとめてメイン処理側のコードが簡潔にしています。

処理内容は以下の通りです。

① 角度を割合に変換

計算を楽にするため、「SG90」が動作できる範囲である±90度を、90度ずらして、0~180度の範囲(表現)に変換します。

0度に指定する例: 0 + 90 = 90度

次に、変換後の入力角度を、SG90の動作範囲(180度)で割り、入力角度が動作範囲対してどの程度の割合であるかを計算します。

0度に指定する例: 90 ÷ 180 = 0.5

角度を0~180に変換するイメージ
角度(表現)変更のイメージ

# 
#  角度⇒PWM信号に変換する関数です
#
def moveServo(pwm, angle ):

    # 入力角度のチェックです。±90以外はエラーにします
    if  angle < -90  or angle > 90 :
        return False

    # 指定角度を、0~180の表現に変えます
    angle = angle + 90

    # 指定角度を、全体(180度)中の割合に変換します
    percent =  angle  / ANGLE_RANGE

    # 割合を時間の範囲に適応して、指定角度を動かす時間を計算します
    addTime = TIME_RANGE * percent

    # 時間範囲は0.5から始まるので0.5に指定角度の時間を足します
    time = MIN_TIME + addTimeGLE_RANGE

② 角度から時間に変換

前述した「入力角度の割合」を使って、PWMのDuty(どれだけの時間、信号をONにすればいいか?)を計算します。

データシートを見ると、ON時間と動作角度は以下のように対応しています。

  • 0.5msec ON -90度
  • 2.4msec ON +90度

上記の範囲は1.9msecなので、ON時間の幅「1.9msec」に、上で計算した角度の割合を当てはめることで、入力角度を動かすためのON時間が計算できます。

0度に指定する例: 1.9 × 0.5 = 0.95

角度の割合を時間に適応するイメージ
角度の割合から時間を計算するイメージ

ここで、ON時間は0.5msecから始まっているため、割合で計算した値に0.5を追加します。

0度に指定する例: 0.95 + 0.5 = 1.45

時間が0.5始まりなので、ON時間に0.5をするイメージ
0.5から始まるイメージ
    # 割合を時間の範囲に適応して、指定角度を動かす時間を計算します
    addTime = TIME_RANGE * percent

    # 時間範囲は0.5から始まるので0.5に指定角度の時間を足します
    time = MIN_TIME + addTime

③ Duty比に変換

前述までの計算で指定角度を動かす場合の、ON時間(1.9msec)が計算できました。

しかし、PWMを設定するduty_u16関数は、初期化時に指定した1周期(20msec)の内、何秒ONにするかの「割合」を「16bit」で指定する必要があるため、ON時間を割合に変換後、16bit(0~65535)の値に変換して指定します。

0度に指定する例: 1.45 ÷ 20 = 0.0725

0度に指定する例: 65535 × 0.0725 = 4751

    # 指定角度の時間を、20msecの周期中の割合(%)に変換します
    ratio = time / CYCLE_TIME
    
    # 16bit(0~65535)の値(整数)に変換します。
    ratio = (int)(65535 *  ratio)
    
    # 動作実行します
    pwm.duty_u16(ratio)

    return True

まとめ

RaspberryPi Pico / Pico Wで、サーボモータ(ラジコンサーボ)SG90を使う方法を解説しました

SG90は簡単に使えて値段もお手軽、「ちょっと動く何かを作ってみたいな」「初めてモーターを触ってみたい」という方にピッタリなモーターです。

動く工作も簡単に作れるので、興味を持ったかたはぜひ遊んでみてください。参考になればうれしいです。

お知らせ

今月号のInterfaceは『RaspberryPi 5』特集

3月25日発売のInterfaceは「RaspberryPi 5」特集!

実験などを通じた性能測定や特徴・変更点の解説。新規に追加されたI/Oボード「RP1」の特徴と謎。Pi5のはじめかたやLinuxコマンド入門などが特集されています。

Pico/Pico W関連のおすすめ本

RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。

見た目のいい工具をお探しの方へ

よく使うツールは『見た目』が重要。モチベもあがりますし、仲間との話のネタにもなります。以下のサイトは、デザイン性の高い工具が集めたサイトなので、興味がある方はぜひご覧ください。

質問・要望 大歓迎です

「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。

使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。

ABOUT ME
えす
現役のソフトウェアエンジニアです。 C++ C# Python を使ってます。10年ちょい設計/開発部門にいましたが、今はQAエンジニアっぽいことをしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Index