LoginSignup
3
0

More than 5 years have passed since last update.

M5BALAに超音波距離センサーを載せて障害物回避

Last updated at Posted at 2018-11-12

概要

M5BALAに超音波距離センサーを載せて障害物を検知し、右折して障害物を回避します。

  • M5Stack FIRE に超音波距離センサーを接続
  • 前方に障害物を検知し、設定した距離より近い場合は右折して障害物を回避
  • 右折時はジャイロのZ軸の回転角を参照して(ほぼ)90度回転

環境

  • M5BALA + M5Stack FIRE
  • M5UI.Flow (Firmware 0.9.0 で確認)
  • 超音波距離センサー HC-SR04

実行例

超音波距離センサーの実装

超音波距離センサーをミニブレッドボードを使って PORT B に接続し、ブレッドボードを M5Stack FIRE の上に載せて輪ゴムで固定しました。

IMG_1903-s.jpeg IMG_1904-s.jpeg

PORT B と HC-SR04 の接続は以下の通りです。

PORT B HC-SR04
(GND) Gnd
(5V) Vcc
(G26) Trig
(G36) Echo

接続時の注意点として、Grove に慣れている方は問題ないかもしれませんが、以下の左側の写真のように M5Stack FIRE 付属の説明書にはケーブルの色が左から、黒、赤、黄色、白と書かれており、M5GO付属のケーブルも実際その色の並びになっています。しかしながら、本来のGrove のケーブルは、黒、赤、白、黄色の順であり、今回接続用に購入したジャンパーピン変換ケーブルも黒、赤、白、黄色の順でした。私は最初、説明書を見て黄色が Pin 26、白が Pin 36 と思って接続したため、しばらく距離が取得できず悩むことになりました。

M5Stack Fire の説明書
M5GO付属のケーブル
ジャンパーピン変換ケーブル
黒、赤、黄色、白の順 黒、赤、白、黄色の順
IMG_1899.jpeg IMG_1900.jpeg

M5BALA制御用プログラム

以下のプログラムを M5UI.Flow から実行しました。

m5bala_hcsr04.py
from m5stack import *
from m5bala import M5Bala
import i2c_bus
import machine

# PORT B に接続する場合のピン定義
TRIGGER_Pin = 26
ECHO_Pin    = 36

# 距離を測定する時間間隔
DISTANCE_INTERVAL = 250 # ms

# 正面の障害物が以下の距離より近くなったら避ける
TURN_DISTANCE = 20 # cm この距離以内に障害物があれば避ける
TURN_ANGLE    = 80 # 度 回りたいのは90度だが、回りすぎるので控えめに設定

# 左右の動き&前進のためのパラメータは実際の動きに合わせて要調整。
# 障害物に近づいたら右折する。
TURN = [15, -25]

# 障害物がなければ前進する。
# 値は 0 だが、重心が前にあるようにしているので前進する。
MOVE = [0,    0]

# M5BALA
m5bala = M5Bala(i2c_bus.get(i2c_bus.M_BUS))

# 距離センサー
trigger = machine.Pin(TRIGGER_Pin, machine.Pin.OUT)
trigger.value(0)
echo = machine.Pin(ECHO_Pin, machine.Pin.IN)

# LED
ledbar = machine.Neopixel(machine.Pin(15), 10)
ledbar.brightness(0)

distance_timer = 0
turn_in_progress = False
while True:
    # 障害物を見つけたら指定角度まで回転する
    if turn_in_progress:
        if m5bala.imu.angleZ < target_angle:
            turn_in_progress = False
            m5bala.left, m5bala.right = MOVE
            # 回転が終わったらLEDを消灯
            ledbar.set(1, lcd.BLACK, num=10)
    else:
        # 指定間隔で正面方向の距離を測定する
        if time.ticks_diff(time.ticks_ms(), distance_timer) > 0:
            distance_timer = time.ticks_add(time.ticks_ms(), DISTANCE_INTERVAL)

            # トリガーピンを 10us HIGH にすることで超音波を送信
            trigger.value(1)
            time.sleep_us(10)
            trigger.value(0)

            # エコーピンが HIGH になっている時間が超音波の応答までの時間
            # 応答にかかった時間から距離を計算する
            # 前方の障害物を判定するのでタイムアウトは短め
            # 10000us = 340cm / 2 = 170cm までの距離測定
            pulse_time = machine.time_pulse_us(echo, 1, 10000) 
            if pulse_time > 0:
                # 障害物までの距離(cm)を計算する
                distance = (pulse_time / 2) * 0.034 # cm
                if distance < TURN_DISTANCE:
                    # 障害物を検知したらLEDを点灯
                    ledbar.set(1, 0x070707, num=10)
                    turn_in_progress = True
                    target_angle = m5bala.imu.angleZ - TURN_ANGLE
                    m5bala.left, m5bala.right = TURN
                else:
                    m5bala.left, m5bala.right = MOVE

    m5bala.balance()

おまけ

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0