「ラズパイマガジン」タグアーカイブ

Raspberry Piで超音波距離センサーを操る

有料駐車場にてどの時間帯に駐車数が多いかを検証するシステムの制作依頼が来ました。入出庫台数をカウントすることは簡単ですが、問題はそれを検知する方法です。

そこで色々調べた結果、Raspberry Piで超音波距離センサーを使用してみます。

車が駐車場の出入り口を通過したときに距離の変化をみて入出庫を検知します。駐車場出入り口で上下するバー付近に設置すれば誤って人が通過したことを検知することは無いでしょう。

今回使用したセンサーは、「HC-SR04」という超音波距離センサーで測定距離は2~400cmです。実際に大阪日本橋の千石電商で400円で購入しました。価格比較のためにマルツやシリコンハウスもまわってみましたが、置いていませんでした。

それもそのはず、この「HC-SR04」という超音波距離センサーには2015年の3月からのロットに不具合があるのです。それ以前のロットに不具合はありません。

写真右側が不具合のあるロットです。右端のPINの文字が「GND」となっています。不具合のないロットは「Gnd」です。その他にも違いがあるので探してみて下さい。店舗では在庫が無いところが多いので、Amazonなどネットでの購入をお勧めしますが、購入の際は必ず確認しましょう!

もちろん私の購入したものは不具合なしのロットです。確認せず購入しましたが(^_^;)

ちなみにこちらは浅草ギ研のPING超音波距離センサーです。HC-SR04価格が10倍以上違うので間違って購入しないようにしましょう♪

浅草ギ研PING超音波距離センサー

(注)偽物や不良品ではありません。

しかし、このセンサーいったいどうやって使うのでしょうか?

超音波距離センサーは、超音波を発生し、障害物にぶつかって戻ってくるまでの時間を計測し距離を求めます。

だそうです。

説明書など一切付いてませんので、まずはこのセンサーの仕様をネットで検索しました。

・トリガー(TRIG)を10μ秒以上HIGHにすると、距離の測定を始めます。
・測定後、距離に応じた長さの信号が、ECHOに返されます。
・測定結果から距離への換算は、つぎのように計算します(単位ミリ)。 距離=(ECHOがHIGHの時間 X 340)/2;
・電源:5VDC 待機時消費電流:<2mA 有効な角度:<15° 測定可能距離:2cm〜400cm 分解能:0.3cm

なるほど!よくわからない某雑誌から回路図を拝借しました。

超音波距離センサー「HC-SR04」の回路図




私が接続したものが以下になります。上記回路図はRaspberry Pi 3 Model B用ですが、私の所持しているRaspberry Pi 1 Model Bと使用するGPIOは変わらなかったので同じように接続しました。駐車場入出庫台数管理システム?

次はセンサーを制御するプログラムです。こちらも某ラズパイマガジンから拝借します。

まずは実行にライブラリが必要ということでインストールします。

$ sudo pip3 install wiringpi

WiringPiはRaspberry PiのGPIOを制御するためのC言語ライブラリだそうです。pip3はPython 3のコマンドらしい。pythonは初めてなので、ここでは深く追求しません。

ソースコードは少し変更しました。ある一定の距離を一定時間検知すると入出庫と判断するためです。検証のため5cm未満を5秒間検知すると入出庫と判断しサーバにアクセスします。サーバへのアクセスはwgetコマンドを使用したシンプルな作りにしています。

アクセスを受けたサーバ側では駐車台数を増減します。それをWebで確認できるようにする予定です。

■ultrasonic.py

import os
import time, wiringpi as pi

TRIG_PIN = 23
ECHO_PIN = 24

DURING = 5
CATCH_DISTANCE = 5

pi.wiringPiSetupGpio()

pi.pinMode( TRIG_PIN, pi.OUTPUT )
pi.pinMode( ECHO_PIN, pi.INPUT )
pi.digitalWrite( TRIG_PIN, pi.LOW )
time.sleep( 1 )

def mesure():
    pi.digitalWrite( TRIG_PIN, pi.HIGH )
    time.sleep(0.00001)
    pi.digitalWrite( TRIG_PIN, pi.LOW )
    while ( pi.digitalRead( ECHO_PIN ) == pi.LOW ):
        sigoff = time.time()
    while ( pi.digitalRead( ECHO_PIN ) == 1 ):
        sigon = time.time()
    return (( sigon - sigoff ) * 34000) / 2

count = 0
while True:
    distance = mesure()
    print ("Distance:", distance )
    if distance < CATCH_DISTANCE:
        count = count + 1
    else:
        count = 0
    if count == DURING:
        print ("Parkin in")
        os.system('/usr/bin/wget http://xxxx/parking.php?parking=in')

    time.sleep(1)

ここまでくるとセンサーの使用方法がなんとなくわかってきました。距離の測定はmesure()関数で行っています。

def mesure():
    pi.digitalWrite( TRIG_PIN, pi.HIGH )
    time.sleep(0.00001)
    pi.digitalWrite( TRIG_PIN, pi.LOW )
    =>トリガー(TRIG)を10μ秒以上HIGHにすると、距離の測定を始めます。

    while ( pi.digitalRead( ECHO_PIN ) == pi.LOW ):
        sigoff = time.time()
    while ( pi.digitalRead( ECHO_PIN ) == 1 ):
        sigon = time.time()
  =>測定後、距離に応じた長さの信号が、ECHOに返されます。(ECHOが1になっている時間を計算)

    return (( sigon - sigoff ) * 34000) / 2
  =>距離 = (ECHOがHIGHの時間 X 340) / 2

では動作させてみましょう♪測定距離は正確です!

$ sudo python3 ultrasonic.py

Distance: 55.40204048156738
Distance: 58.818817138671875
Distance: 59.41057205200195
Distance: 58.3040714263916
Distance: 3.416776657104492
Distance: 7.919788360595703
Distance: 4.523277282714844
Distance: 3.789663314819336
Distance: 1.3942718505859375
Distance: 1.3780593872070312
Distance: 1.3942718505859375
Parkin in =>5cm未満を5秒間検知すると入庫したと判断
Distance: 1.2888908386230469
Distance: 2.054929733276367
Distance: 1.6820430755615234
Distance: 2.038717269897461
Distance: 57.64341354370117
Distance: 56.9462776184082
Distance: 57.9676628112793

たった40行程度のプログラムでここまで出来ました!めでたし♪