🚘

ラズパイ-ラジコン+αを自作する - その2(モータ制御)

2021/09/19に公開

🏁デモ

📚記事一覧

📍本記事の範囲

まずは、モータを制御し、移動できるようにします。
モーター管理について説明します。

🔧パーツ一覧

部品名 個数 内容 備考
RaspberryPiZeroWH 1 ラズベリーパイゼロ本体 秋月電子
カムロボット 1 カムロボット本体 Amazon
モータドライバ(DRV8835使用) 1 モーラドライバ本体 秋月電子
電池ケース 単3×2本 1セット DCモータ動作用 秋月
電池 単3 2 DCモータ動作用 -

※全パーツは、その1-コンセプトを参照のこと

接続図

ピンの接続

ラズパイ側

Pin ドライブモジュール 備考
GND [6]GND -
BCM13 [7]BIN2 -
BCM24 [8]BIN1 -
BCM23 [9]AIN2 -
BCM18 [10]AIN1 -
GND [11]MODE DCモータモードのため、GND
3.3V [12]VCC -

ドライブモジュール側

ドライブモジュール 接続先 備考
[1]VM 電池+ 電池のマイナスは、GNDに接続
[2]AOUT1 カムロボットモータへ -
[3]AOUT2 カムロボットモータへ -
[4]BOUT1 カムロボットモータへ -
[5]BOUT2 カムロボットモータへ -
[6]GND 電池- -

💻環境

開発環境

  • ラズベリーパイ
    • Linux rpi 5.10.17-v7l+ #1403 SMP Mon Feb 22 11:33:35 GMT 2021 armv7l GNU/Linux
  • Python
    • Python 3.7.3 (default, Jan 22 2021, 20:04:44)

ラズベリーパイの設定

特になし

モジュールのインストール

apt

pigpioライブラリは、Raspberry PiのGPIOを制御するためのライブラリです。
以下のコマンドは、はじめてインストールする場合のみ必要です。

$ sudo apt install pigpio
$ sudo service pigpiod start
$ sudo systemctl enable pigpiod.service

pip

Pythonに関するモジュールをインストールします。

$ python3 -m venv env
$ source env/bin/activate
(env) $ pip install pigpio
(env) $ pip install gpiozero
(env) $ pip install icecream

📝手順

最終的に、すべてのモジュールが連携するため、キューを使用しています。

コード

dcm.py
from queue import Queue
import threading
import time

from gpiozero import Motor
from time import sleep
from gpiozero.pins.pigpio import PiGPIOFactory

import sys
from icecream import ic

PIN_AIN1 = 18
PIN_AIN2 = 23
PIN_BIN1 = 24
PIN_BIN2 = 13

dcm_pins = {
    "left_forward": PIN_AIN2,
    "left_backward": PIN_AIN1,
    "right_forward": PIN_BIN2,
    "right_backward": PIN_BIN1,
}

MAG_TBL = {
    "slow" : 0.5,
    "mid" : 0.75,
    "fast" : 1.0,
}

class DcmThread(threading.Thread):
    """
    サーボ管理
    例:
    queue経由で、{'action': 'right', 'speed': 'fast', 'type': 'dcm'}
    """
    def __init__(self):
        threading.Thread.__init__(self)
        self.stop_event = threading.Event()
        self.setDaemon(True)

        self._rcv_que = Queue()

        factory = PiGPIOFactory()
        self._motor_left = Motor( forward=dcm_pins["left_forward"],
                            backward=dcm_pins["left_backward"],
                            pin_factory=factory)
        self._motor_right = Motor( forward=dcm_pins["right_forward"],
                            backward=dcm_pins["right_backward"],
                            pin_factory=factory)
        return

    def stop(self):
        self.stop_event.set()
        self._motor_left.value = 0.0
        self._motor_right.value = 0.0
        return


    def run(self):
        while True:
            item = self.rcv_que.get()
            ic(sys._getframe().f_code.co_filename, sys._getframe().f_code.co_name, item)
            
            if "dcm" not in item["type"]:
                ic(sys._getframe().f_code.co_filename, sys._getframe().f_code.co_name, "Error!!!")
                continue

            action = item["action"]
            mag = MAG_TBL[item["speed"]]
            if "forward" in action:
                self._motor_left.value = 1.0 * mag
                self._motor_right.value = 1.0 * mag
            elif "back" in action:
                self._motor_left.value = -1.0 * mag
                self._motor_right.value = -1.0 * mag
            elif "left" in action:
                self._motor_left.value = -1.0 * mag
                self._motor_right.value = 1.0 * mag
            elif "right" in action:
                self._motor_left.value = 1.0 * mag
                self._motor_right.value = -1.0 * mag
            else:   #"stop"
                self._motor_left.value = 0.0
                self._motor_right.value = 0.0
        return

    @property
    def rcv_que(self):
        return self._rcv_que


def main():
    import time

    dcm_th = DcmThread()
    dcm_th.start()
    q = dcm_th.rcv_que

    q.put({"type": "dcm", "action": "forward", "speed": "fast"})
    time.sleep(1)

    q.put({"type": "dcm", "action": "back", "speed": "fast"})
    time.sleep(1)

    q.put({"type": "dcm", "action": "left", "speed": "fast"})
    time.sleep(1)

    q.put({"type": "dcm", "action": "right", "speed": "fast"})
    time.sleep(1)

    q.put({"type": "dcm", "action": "stop", "speed": "fast"})
    time.sleep(1)

    dcm_th.stop()
   
    return

if __name__ == "__main__":
    main()

実行手順

(env) $ python dcm.py

以下の順番でカムロボットが動作します。

  • 1秒 - 直進
  • 1秒 - バック
  • 1秒 - 左に転回
  • 1秒 - 右に転回
  • 停止

デモの結果になります。

🔎ポイント

モータドライバ(DRV8835使用)

モータドライバ(DRV8835)にてのモータを制御します。
本製品は、DCモータまたはステッピングモータ用のドライバとして使用できます。
カムロボットに搭載されているモータは、DCモータのため、[11]MODEピンをLOW(GND接続)にする必要があります。

IN1/2に対する正転/逆転/ブレーキの関係は以下となります。

xIN1 xIN2 xOUT1 xOUT2 動作 コード上の紐づけ
0 0 HiZ HiZ 空転 stop
0 1 L H 逆転 back
1 0 H L 正転 forward
1 1 L L ブレーキ brake

2回路分のDCモータの制御ができます。

今回、使用するモータは、1.5~3.0Vで駆動するモータを使用しています。。
本ドライバは、モータ電源は2V~11Vでの動作となります。
電源が大きいモータを動かす場合は、使用できないので注意してください。

以下が、電源に関する情報です。

電源使用 動作範囲 該当ピン
モータ電源 2-11V AOUT,BOUTが該当
ロジック電源 2-7V AIN,BINが該当

速度制御(PWM制御)

速度を調整するのに、パルス幅変調(PWM:Pulse Width Modulation)調光方式を使用しています。
ONしている時間が長ければ速く(/短ければ遅く)移動します。

コードの対応は以下となります。

self._motor_left.value = 1.0 * mag
self._motor_right.value = 1.0 * mag

さいごに

次は、腕の動作について記載したいと思います。

あと、それ以外のラズパイの活用方法を

https://zenn.dev/kotaproj/books/raspberrypi-tips

としてまとめ中です。

GitHubで編集を提案

Discussion