nyabot’s diary

電気猫の夢を見るお話

ラズベリーパイとPCA9685で複数のサーボモータを動かす

前回まではソフト面をいじっていたけれど、今回からハードを作っていく。

電子工作の基礎知識の習得

ラズパイは色々できるらしいものの具体的なことはさっぱりわかっていなかったので、まずは基礎知識を習得する。

「カラー図解 最新 Raspberry Piで学ぶ電子工作」という本を買った。

ラズパイを用いた電子工作について、本当に基礎から細かく丁寧に書かれていて、わかりやすい良書でした。
特に、電流や抵抗の話から説明してくれるのはとてもありがたかった。「そういえば小中学校でやったような…」という程度の知識しかなかった、つまり知識が全くなかった私も、すんなり理解することができた。
ラズパイや電子工作の書籍って入門書ちっくなものでも2、3000円するものが多いので、この価格でこの内容はすごくお買い得な感じ。

書籍の演習で用いるパーツセットが秋月電子通商で購入できるので、それを合わせて購入して学ぶと吉。
書籍をざっと読んでから、必要なパーツだけバラで買ってもいい。

Lチカができたところで多少の感動を覚えたりする。
モーターを動かすところあたりまで進めると、なんとなくラズパイを用いた電子工作のやり方がわかってくる。

複数のサーボモータを動かす(前準備)

書籍にも書かれているが、ラズパイはそのままではサーボモータを2台までしか動かすことができないらしい。
今回はドライバを用いて、16台のサーボモータを動かすことに挑戦する。

多脚歩行するロボットを目指す

これから作ろうとしているのは、ロボットのボディ。ラズパイやバッテリーをのせる土台と、それを支えて動かすための足。
電子工作初心者向けの指南でありがちなのは四輪とかキャタピラとかで、でもそれじゃロマンがない。
二足や四足は姿勢の制御が大変らしい。また、それぞれの足にかかる負担も大きいので、しっかりした構造やサーボが必要な模様。
当初から予定していた6足なら、3本ずつ足を前に出すことで安定して歩行できる。という理由もあり、6(+2n)足で歩行するロボットを作ることに決定。

色々調べる中で、日本では他国と比べて多脚ロボットの人気が低いらしい、という話を読んだ。真偽はわからないものの、確かにロボットといえば二足歩行のイメージが強い。漫画やアニメの影響が強いのかもしれない。多脚好きとしては少し悲しい。

PCA9685とサーボモータを購入

「ラズパイ サーボ 複数」でググるとこれを使うといいらしいことがわかる。
とりあえずAmazonで購入する。高いものもあるけど、精度を求めないなら安いやつでいいらしい。懐に優しい。

サーボモータも必要数購入する。メジャーな製品だと、TowerProのSG90というものがよく使われるらしい。秋月電子通商で1個400円。

同じ大きさで、別のメーカーが出しているものもあったりする。壊れやすいらしいがよくわからない。安いものだと、10個セットで2,000円強くらいでAmazonで売っている。

今回は12個(6足×2自由度)、または16個(8足×2自由度)、将来的には24個(8足×3自由度)+αくらい使いたいなと思っていたので、安価なもので試してみることに。
サーボモータには色々種類があり、1,000円〜2,000円以上のものもいくつもあるみたいなので、お金に余裕があればそういうのを買うといいと思う。買いたい。

一つのPCA9685で操作できるサーボモータは最大16個。6足でも3自由度にしてしまうと足りないので、今回は6足2自由度の足に12個、加えて2自由度の足兼アームを二つで4個使用することにし、合わせて16個のサーボモータを用意する。

安価なサーボモータは消耗品、というのをネットで読んだので、10個セットを2つ購入して、4個は予備にした。
また、サーボモータの動力には乾電池(単三4本)を用いる。前述の書籍連動キットには電池ボックスが含まれるので、それを使う。

複数のサーボモータを動かす(配線)

電池ボックス、PCA9685、ラズパイをそれぞれ接続する。

ラズパイ PCA9685
3.3V(1番ピン) VCC
GND(6番ピン) GND
SDA(3番ピン) SDA
SCL(5番ピン) SCL

PCA9685と電池ボックスの接続方法はこちらがわかりやすい。

https://snapguide.com/guides/bezeri-pi-tosabodoraibanojie-sok/

ネジを緩めて、コードを差し込んで、閉める。右(V+)が赤、左(GND)が黒。
ネジを開け閉めする際、一般的な家庭にあるような太めのドライバーだと入らないことがあるので、精密ドライバーがあると良い。

続いて、PCA9685にサーボモータを接続する。
サーボモータのオレンジが黄、赤が赤、茶色が黒になる向きでつなぐ。

複数のサーボモータを動かす(プログラム)

ラズパイの設定

Raspberry PiのI2Cを有効にする。以下の記事が詳しい。

qiita.com

$ sudo raspi-config

「Interfacing Options」 → 「I2C」 → 「はい」を選択。

上記記事にあったので、通信速度の設定追記もしておく。
初期値は100000では通信速度が早すぎてエラーが生じるとのこと。

$ sudo nano /boot/config.txt

最終行に以下の記述を追加。

dtparam=i2c_baudrate=10000

ラズパイの更新、I2Cのチャンネルチェック

$sudo apt-get update
$sudo apt-get upgrade
$sudo apt-get dist-upgrade
$sudo apt-get install python-dev and python3-dev
$sudo apt-get -y install python-smbus i2c-tools

$sudo i2cdetect -y 1

最後のコマンドで、PCA9685が接続されているチャンネルが表示される。
0x40と0x70の二つで、後ほどプログラムを書く際にこれを用いる。

Adfruitのライブラリをインストール

$ cd ~

$ 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

$ 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

python3は違いがまだよくわかっていないが、とりあえず入れとこうというよくない考えによるインストール。

動作させるプログラム

以下で公開されているコードを拝借。色々ご説明がありとても助かる。動かすサーボの数など、必要に応じて書き換える。

Raspberry Pi講座 PWMコントローラ ( PCA9685 ) - Hobby robot laboratory

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

#!/usr/bin/env python
# -*- coding: utf-8 -*-
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(60)

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

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

if __name__ == '__main__':
    Servo0 = servo_Class(Channel=0, ZeroOffset=0)
    Servo1 = servo_Class(Channel=1, ZeroOffset=0)
    Servo2 = servo_Class(Channel=2, ZeroOffset=0)
    Servo3 = servo_Class(Channel=3, ZeroOffset=0)

    try:
        while True:
            print '30'
            Servo0.SetPos(30)
            Servo1.SetPos(30)
            Servo2.SetPos(30)
            Servo3.SetPos(30)
            time.sleep(2)

            print '150'
            Servo0.SetPos(150)
            time.sleep(0.1)
            Servo1.SetPos(150)
            time.sleep(0.1)
            Servo2.SetPos(150)
            time.sleep(0.1)
            Servo3.SetPos(150)
            time.sleep(2)

    except KeyboardInterrupt:
        print("\nCtl+C")
    except Exception as e:
        print(str(e))
    finally:
        Servo0.Cleanup()
        Servo1.Cleanup()
        Servo2.Cleanup()
        Servo3.Cleanup()
        print("\nexit program")

こんな感じでテストしてみた。動いた。楽しい。
実際には上記のコードに少し書き加えて、PCA9685一つで動かせる最大数の16個のサーボモータを動かしてみた。動いた。とても楽しい。

つづく。