RaspberryPi

ラズパイとサーボドライバ(PCA9685)でサーボモータ制御

本記事では、ラズパイからサーボモーターを制御する方法を紹介します。

ラズパイから直接サーボモータの電源を取ると、

ラズパイ側の動作が不安定になる可能性があるので、サーボモータ用のドライバを使用しています。

この記事で分かること

本記事を読み終わると、下記の内容が分かるようになります。

  • ラズパイからサーボモータを制御するために必要な部品
  • 各部品の接続
  • ラズパイでI2C通信する方法
  • サーボドライバ制御用ライブラリのインストール方法
  • サーボドライバ制御のpythonのサンプルコード

スポンサーリンク

用意したサーボドライバとサーボモータ など

ラズパイからサーボモータを動かすために用意したものは、下の写真のとおりです。

ラズパイとサーボモータ
モータドライバ、サーボモータ、電池ケース、ジャンパワイヤ

リンクがある方が分かりやすいので、部品ごとに改めて紹介します。

サーボモータドライバ

ラズパイとI2C接続することで、16台までのサーボモータを制御出来ます。

PWM制御に対応しています。

この商品は、Adafruit社のPCA9685搭載16チャネル PWM/サーボ ドライバー の廉価版です。

信頼性を重視する用途では、Adafruit社の製品を購入することをオススメします。

筆者は趣味用途での使用のため、価格重視でHiLetgo社製のドライバを購入しました。

サーボモータ

サーボモータの定番の "SG90" を使用しました。

制御角は ±約90°(180°) です。

ジャンパーワイヤー

ラズパイと、サーボモータドライバの結線に、メスメスのジャンパワイヤーが必要です。

こちらのジャンパワイヤは、オスオス、オスメス、メスメスのセットです。

電子工作を楽しみたい方は、持っておくと便利だと思います。

電池ボックス

サーボモータドライバに電圧を供給するための電池ボックスです。

サーボモータの動作電圧が4.8Vのため、単3電池4本用のケースを使用しています。

スポンサーリンク

ラズパイ、サーボドライバ、サーボモータの接続

ここからは、各パーツのつなぎ方を紹介していきます。

ラズパイ4のピン配置

初めに、ラズパイ4のピン配置を載せます。

ラズパイ ピン配置

ラズパイ ピン配置 引用:Raspberry Pi 公式ドキュメント

また、ラズパイのピン配置は、ターミナルからも確認できます。

下記のコマンドを入力すると、ターミナル画面にラズパイのピン配置が表示されます。

$ pinout
ラズパイ4のピン配置
ラズパイ4のピン配置
ラズパイ4のピン配置
ラズパイ4のピン配置

サーボモータは、I2C接続で制御するので、

3ピン:GPIO2(SDA)、5ピン:GPIO3(SCL)を使用します。

以下で、各部品の接続について説明します。

ラズパイ、サーバドライバー、サーボモータの回路図

回路図はこちら。

ラズパイ_モータドライバ(PCA9685)_サーボモータ
ラズパイ_モータドライバ(PCA9685)_サーボモータ

ラズパイとサーボモータドライバ(PCA9685)は、下記のとおり接続しています。

ラズパイ:2ピン(5V)     -  ドライバ : VCC

ラズパイ:3ピン(SDA)   -  ドライバ : SDA

ラズパイ:5ピン(SCL)   -  ドライバ : SCL

ラズパイ:6ピン(GND)   -  ドライバ : GND

各部品を接続すると、こんな感じです。

ラズパイとサーボモータを結線した様子
ラズパイと各部品を接続した様子

ここまでで、ラズパイと各部品の接続は完了しました。

次は、サーボモータを制御するために、I2C接続の設定を行います。

スポンサーリンク

ラズパイとサーボドライバ(PCA9685)のI2C接続設定

ラズパイからサーボモータを制御するために、I2C接続の設定を行います。

I2Cとは、Inter Integrate Circuitの略で、周辺デバイスとシリアル通信を行うための方式になります。

パーティライン構成が可能で、1つのマスタから複数のスレーブを制御することができます。

I2C通信について詳しく知りたい方は、こちらのサイトが参考になります。

では、ラズパイでI2C通信を有効にする手順について紹介していきます。

ラズパイ(Raspberry Pi)のI2C通信を有効にする

ラズパイのI2C通信を有効にします

「設定」 → 「RaspberryPi の設定」の順に進みます。

ラズパイのI2C通信を有効にする
ラズパイのI2C通信を有効にする

インターフェースタブで、"I2C" を有効にします。

ラズパイのI2C通信を有効にする
ラズパイのI2C通信を有効にする

これで、ラズパイでI2C通信ができるようになりました。

PCA9685がI2C接続できているか確認する

PCA9685がI2C接続できているか確認します。

また、この操作により、PCA9685を制御するためのチャンネルを確認できます。

下記のコマンドをターミナルに入力します。

$ sudo i2cdetect -y 1

下記画像のような結果が出れば正しく接続されています。

ラズパイがI2C接続できているか確認
ラズパイがI2C接続できているか確認

なお、PCA9685との通信用のチャンネルとして、0x40を使用すれば良いことも読み取れます。

必要なライブラリのダウンロード

サーボドライバを制御するために必要なライブラリを準備します。

AdafruitのGitサイトから、必要なライブラリをダウンロードします。

ターミナルに、下記のコマンドを入力すると、ライブラリをダウンロードできます。

$ git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
$ git clone https://github.com/adafruit/Adafruit_Python_GPIO.git
$ git clone https://github.com/adafruit/Adafruit_Python_PureIO.git

ライブラリは、/home/"ユーザー"の階層にダウンロードされています。

ダウンロードしたライブラリをPythonにインストールします。

下記のコマンドをターミナルに入力します。Python3にも念のためインストールしています。

$ cd Adafruit_Python_PCA9685
$ sudo python setup.py install
$ sudo python3 setup.py install

$ cd ../Adafruit_Python_GPIO
$ sudo python setup.py install
$ sudo python3 setup.py install

$ cd ../Adafruit_Python_PureIO
$ sudo python setup.py install
$ sudo python3 setup.py install

Pythonのサンプルコード

ここからは、サーボモータを制御するためのPythonのサンプルコードを紹介します。

制御コードを理解する前に、サーボモータの仕様を理解する必要があるので、

はじめに、サーボモータ SG90の仕様を載せておきます。

サーボモータ SG90の仕様

サーボモータ SG90の仕様

項目仕様
PWMサイクル20ms
制御パルス0.5ms~2.4ms
制御角±約90°(180°)
動作速度0.1秒/60°
動作電圧4.8V(~5V)

色々書いてありますが、制御パルス0.5ms ~ 2.4ms で、制御角:±90° という情報がポイントです。

ラズパイにサーボモータを直接接続する場合は、この制御パルスに従ってコードを作成する必要があります。

しかし、今回はモータードライバ(PCA9685)を介して繋いでいるので、

先ほどインストールした、モータードライバ用のライブラリを用いて、

モータードライバ用のパルスを送信します。

サンプルコード

モータードライバ(PCA9685)でサーボモーターを制御するサンプルコードを紹介します。

コードは、下記のサイトを参考にさせていただきました。

Hobby robot laboratory

Qiita : PCA9685で複数サーボモーターをコントロール

SG90の制御角は180°なので、0~180°を1°ずつ動かしてみています。

import Adafruit_PCA9685
import time

class servo_Class:
    #ChannelはPCA9685のサーボモータの接続チャンネル
    #ZeroOffsetはサーボモータの基準位置調節用パラメータ
    def __init__(self, Channel, ZeroOffset):
        self.Channel = Channel
        self.ZeroOffset = ZeroOffset

        #Adafruit_PCA9685の初期化
        self.pwm = Adafruit_PCA9685.PCA9685(address=0x40)
        self.pwm.set_pwm_freq(int(60))

    # 角度設定
    def SetPos(self,pos):
        #PCA9685はパルスで角度を制御しており、パルス150~650が角度0~180に対応
        pulse = int((650-150)/180*pos+150+self.ZeroOffset)
        self.pwm.set_pwm(self.Channel, 0, pulse)

    # 終了処理
    def Cleanup(self):
        #サーボを90°にセット
        self.SetPos(int(90))
        print('90')

if __name__ == '__main__':
    Servo0 = servo_Class(Channel=0, ZeroOffset=0)

    try:
        while True:

            for deg in range(180) :
                Servo0.SetPos(int(deg))
                print(deg)
                time.sleep(0.05)

    except KeyboardInterrupt:
        print("\nCtl+C")
    except Exception as e:
        print(str(e))
    finally:
        Servo0.Cleanup()

        print("\nexit program")

※このコードでラズパイ上は動作していますが、サイト移植時にインデントを手打ちしています。

もしエラーが出た場合は、インデント部分を確認いただければと思います。

その他不具合がある場合は、コメント欄に記載いただければこちらで確認します。(可能な範囲で笑)

~コマンドの簡単な解説~

★Channel

今回はサーボモータは1つしか制御していないので、Channelは0しかありませんが、

Channelを増やすことで複数のサーボモータを制御できるようになります。

Servo0 = servo_Class(Channel=0, ZeroOffset=0)

Servo1 = servo_Class(Channel=1, ZeroOffset=0)

Servo2 = servo_Class(Channel=2, ZeroOffset=0)

★角度設定

角度をパルス値へと変換しています。

PCA9685では、パルス150~650が角度の0~180に対応しています。

そのため、 (650-150)/180 で1度あたりのパルスを算出した後、所望の角度をかけることで、

角度をパルス値に変換しています。

また、0degがパルス値150に対応するため、150を足しています。

最後に、サーボモータが動いている様子を載せます。

スポンサーリンク

まとめ

ラズパイで、モータードライバ(PCA9685)を介してサーボモーターを制御する方法を紹介していきました。

サーボモータの制御は、電子工作の基本なので、初心者の方は是非チャレンジしてみてください。

スポンサーリンク

-RaspberryPi
-