日記とか、工作記録とか

自分に書けることを何でも書いてゆきます。作った物、買ったもの、コンピュータ系の話題が多くなるかもしれません。

M5Stack + 距離センサーHC-SR04

さて、M5Stackで何か遊ぼうということで、以前買ったまま放置していた距離センサーHC-SR04を取り出してきました。

f:id:WindVoice:20190908175557j:plain
秋月電子の資料のHC-SR04

正面に40kHzの超音波を発射、その跳ね返ってくるまでの時間を計測できるセンサーです。計測できるのは時間なので、距離は自分で計算することになります。私の部屋は25℃くらいなので、音速は346m/秒くらいです。2cm~400cmまで、分解能0.3cmって書いてあるけれど、これは利用する基板側も精一杯センサーの能力を引き出す努力をしないといけないのではないかと思います。

さて、ではさっそくこれを使った工作をしていきましょう。

配線

配線は、秋月電子で手に入るデータシートに従ってつないでいきます。

写真の上からVcc(5Vの電源)、Trig(距離を測りたいときにHighを10マイクロ秒送ってセンサーに合図する)、Echo(跳ね返ってきた音波が届くまでの時間がここから取れる)、GND(0Vにつなぐ)となっています。ここではM5Stack付属のケーブルで、順に紫、灰、白、黒をつなぎました。

f:id:WindVoice:20190907231031j:plain

M5Stack側はこんなです。青で2、5と書いてあるところがGPIOの2番、5番ポートです。5VがVcc、GはGNDのことですね。配線は刺すだけなので簡単です。

f:id:WindVoice:20190908120756j:plain

プログラミング

プログラミング環境は、Visual Studio Code + MicroPythonです。環境の作り方は前回書いたので省略します。アプリの内容についてはいくつかのサイトを参考にさせてもらっていますが、距離を測って数字で表示するだけ、ではなくもう少し面白くしたかったので、距離が緑色のバーの伸び縮みで表現されるようにしたり、音による感覚的なフィードバック(よくゲームなどでみられるようなアレですね)も実装しました。それぞれ何をしているのかはソースコード内のコメントにしてあります。

ところで、M5StackでMicroPythonを使う時のm5stackモジュールの詳細が書かれたドキュメントはないのでしょうか? 今回はインターネット上にばらばらの情報を寄せ集めて書いたのですが、開発元発信の情報がどこかにあるんじゃないかと思っているのですが…… ご存じの方は教えてください。

下の内容を、M5StackのappsフォルダにHC-SR04.pyのような名前で保存しておけば、M5Stack再起動時にBボタンを押したときのAPP.Listに表示されるようになります。アプリが起動後はCボタンで音のON / OFFが切り替えられます。

from m5stack import lcd
from m5stack import *
import sys

import utime, time
import machine
from uiflow import *

############################################################
# GPIO pin設定(距離センサーHC-SR04を使用する準備)
############################################################

# GPIO2を入力ポートとしてECHOにセット
ECHO = machine.Pin(2, machine.Pin.IN)

# GPIO5を出力ポートとしてTRIGGERと接続してLowにセット
TRIGGER = machine.Pin(5, machine.Pin.OUT)
TRIGGER.value(0)

############################################################
# 画面の準備
############################################################

lcd.clear()

left  =  10
top   =  50
right = 310
height = 30

# ゲージを描画
onemeter = int((right - left)/4)
lcd.line(left               , top + height + 1,    right, top + height + 1, lcd.WHITE)
lcd.rect(left               , top + height + 1, onemeter, 6, lcd.WHITE, lcd.WHITE)
lcd.rect(left + 1 * onemeter, top + height + 1, onemeter, 6, lcd.WHITE, lcd.BLACK)
lcd.rect(left + 2 * onemeter, top + height + 1, onemeter, 6, lcd.WHITE, lcd.WHITE)
lcd.rect(left + 3 * onemeter, top + height + 1, onemeter, 6, lcd.WHITE, lcd.BLACK)
lcd.print('0cm',  10, 90, lcd.WHITE)
lcd.print('400', 285, 90, lcd.WHITE)

# ミュートはCボタン
lcd.print('[C:SPEAKER ON/OFF]', 170, 220, 0xFFFFFF)

############################################################
# 音を出す準備
############################################################

vol = 0
speaker.setVolume(vol)
interval = 10
interval_count = interval

############################################################
# Main Loop
############################################################

while True:

    ########################################################
    # 距離を測る
    ########################################################
    # Triggerポートを最低10マイクロ秒Highにすると、計測が始まる。
    TRIGGER.value(0) # Low
    time.sleep_us(5)
    TRIGGER.value(1) # High
    time.sleep_us(10)
    TRIGGER.value(0) # Low

    # ECHOピンがHighになっている時間が返る。単位はマイクロ秒。
    pulse_time_us = machine.time_pulse_us(ECHO, 1, 30000)

    # 計算で前方の障害物までの距離を求める。
    # HC-SR04は2cm~400cmの距離を測ることができる。
    # 音速は25℃で346m/sec.
    # 1マイクロ秒で0.34600mm進むことを逆に考えると、
    # 1mm : x usec = 0.34600 : 1 usec
    # 0.346 x = 1
    # x = 2.890
    # 音波は障害物との間を往復するから、実際にはこの倍で578で割ればよい。
    mm = pulse_time_us * 100 // 578

    ########################################################
    # 計算結果を表示
    ########################################################

    # [1] 普通に文字で表示
    lcd.setCursor(30, 30)
    lcd.print('Distance:  {:>4.0f} mm\n'.format(mm))

    # [2] 四角いバーで表示
    # 0 - 4000mmを 10px - 310px で表現するとして、13.3で割れば良い
    rectwidth = int(mm / 13.3)
    # 緑の部分を描画
    lcd.rect(left                , top,       rectwidth, height, lcd.GREEN, lcd.GREEN)
    # 黒の部分を描画
    lcd.rect(left + rectwidth + 1, top, 320 - rectwidth, height, lcd.BLACK, lcd.BLACK)

    # [3] 音でお知らせ(400Hz - 700Hz、近いほうが高い音、遠いときは頻度を減らす)
    freq = 1400 - rectwidth * 2
    interval = int(mm / 400) + 3
    interval_count = interval_count + 1
    if interval_count > interval:
        speaker.tone(freq, 3)
        interval_count = 0

    #Cボタンで音のON / OFF
    if btnC.wasPressed():
        vol = 1 - vol
        speaker.setVolume(vol)

    utime.sleep(0.1)

試してみた感想など

動作はこんな感じです。Cボタンを押してスピーカーをONにしたあと、センサーに物を近づけたり遠ざけたりすると音が変わります。ちょっと見づらいですが、画面表示も変わっています。距離が正確に測れているかというと…… 正直なところだいたいですね。センサーの正面から15度の範囲で計測できることになっていますが、これを持っていたら見えない場所でも歩けるかというと、正直厳しいと思います。センサーの問題ではなくて実装側の課題だとは思うのですが、改善の方法があるのかはよくわかりません。

動画では音がでるように感じられるかもしれませんが、これはアプリがM5Stackのスピーカーを鳴らしているのであって、センサーの発する音は耳には聞こえません。

www.youtube.com

HC-SR04 超音波距離センサーモジュール For Arduino

HC-SR04 超音波距離センサーモジュール For Arduino