超音波センサーで物体の距離を測ってみます
〔Arduinoの動かせ方入門に戻る〕
物体の距離を測るには色々有りますが、
先ず近距離(0cm-3cm位)の物体を測ると言いますか物体の存在を検知する為のセンサーが、
近接センサー(磁気センサー)やリードスイッチに光電センサー(フォトセンサー)です。
近接センサー・フォトセンサーの話はこちらを参照して下さい。
そして中距離(3cm-5m位)の物体を測るのに超音波距離センサーと赤外線距離センサーです。
最後に長距離(5m-数百m)の物体を測るのにはレーザー距離センサーでしょうか。
尚、赤外線距離センサーについてはこちらを参照して下さい。
このページではArduinoを使った超音波距離センサーについて記述します。
また、PIC16F1827で超音波距離センサーを利用する場合はこちらの記事を参照下さい。
人間に聞こえる音の周波数は、約30Hz〜20kHz位と言われてます、この範囲を可聴周波といます。
そして、20kHz〜数GHzを超音波と言い、今回のセンサーは40KHzの音を出します。
ちなみにぃ、犬は80KHzまでは聞こえるらしい、また、コウモリは20KHz〜100KHzを出すらしい。
また、超音波は色々な分野で利用されています、ソナーや魚群探知機(測深機)に、
医療関係では超音波治療器(ME)や超音波検査などですね。
後ぉ、音波の性質として、電波や光に比べたら伝搬速度は結構遅いです、それに速度はその物質の状態や温度・湿度・圧力
などにより変化します。
なので、何時でも精度のよい測距を求めるなら温度センサーを付けて補正をする事を進めます。
空気中の音の伝搬速度は約340m/sですが、水中では約1530m/sでぇ、鉄では約5km/sです。
超音波の伝搬速度は「気体→液体→固体」の順で伝搬速度(効率)が良くなります。
あ、今回利用するセンサーは空中用ですよ、間違わない様に。
《配線図1》
このセンサーはスイッチサイエンスのこちらで購入しました。
製造元はseeed studioの製品です、
最近お気に入りですよぉ、安いしぃ、色々あるしぃ、Arduinoのサンプルスケッチもあるしぃ。
検出範囲 3cm〜4m と書いて有りますが、
私の物は 3cm〜3m までの様です。
なのでスケッチは3mまでとしています。
センサーはArduinoのデジタル7番ピンに接続していますが、異なるピンを使用する場合は、
下記スケッチの
#define pingPin 7 // センサー接続のピン番号
を変更して下さい。
こちらやこちらのセンサーが
お安くて良いかもですね。
(持っていないのでぇ未実験ですがぁ) *3)
《スケッチ1》
@まずは、上記図画面の様に配線しましょう。
Aarduinoボード(Arduino Duemilanove 328)はUSBケーブルで接続して、arduinoIDEを起動させます。
BIDEに下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
---------------------------------------------------------------------
#define pingPin 7 // センサー接続のピン番号
// 電源起動時とリセットの時だけのみ処理される関数(初期化と設定処理)
void setup() {
Serial.begin(9600) ; // 9600bpsでシリアル通信のポートを開きます
}
// 繰り返し実行される処理の関数(メインの処理)
void loop() {
int cm ;
cm = UsonicMeasurRead(pingPin) ; // センサーから距離を調べる
Serial.print(cm) ; // 距離を表示する
Serial.println("cm") ;
delay(1000) ; // 1s後に繰り返す
}
// 超音波センサーから距離を得る処理
// pin=センサーに接続しているピン番号
// 距離をcmで返す(検出できない場合は0を返す)
int UsonicMeasurRead(int pin)
{
long t ;
int ans ;
// 超音波センサーに5usのパルスを出力する
pinMode(pin, OUTPUT) ; // ピンを出力モードにする
digitalWrite(pin, LOW) ;
delayMicroseconds(2) ;
digitalWrite(pin, HIGH) ;
delayMicroseconds(5) ;
digitalWrite(pin, LOW) ;
// センサーからの反射パルスを受信する
pinMode(pin, INPUT) ; // ピンを入力モードにする
t = pulseIn(pin, HIGH) ; // パルス幅の時間を測る
if (t < 18000) { // 3m以上の距離は計算しない
ans = (t / 29) / 2 ; // 往復なので2で割る
} else ans = 0 ;
return ans ;
}
---------------------------------------------------------------------
CIDEツールバーの赤枠部分「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを
行います。
D正常終了後、ツールバーの右側のアイコン「SerialMonitor」ボタンをクリックしてシリアルモニター
画面を起動させます。
E赤外線距離センサーの前に物体をかざしてみましょう、モニター画面に物体までの距離がcmで表示
されます。
この図の様にセンサーへ5usの開始信号を送ります、その後センサーから信号がエコーバックされます。
エコーバック信号は物体の距離に比例したパルス幅です、この長さをカウントしましょう。
(全く障害物が検出されない場合は、出力ピンは38msハイレベルの信号を与えます。)らしいです。
尚、今回はArduinoの標準関数でpulseIn()を利用して長さをカウントしています。
パルス幅は往復の長さなので2で割ります、また今回は1秒毎に繰り返していますが、
最低50ms以上の間隔を空けないとだめです。
《配線図2》
こんどは秋月電子のこちらのセンサーを利用した回路です。
回路はデータシート(部品に付属)に記載の受信回路を手持ちの部品で構成しました。
NJM4580Dは左下が1番ピンです、
下図はLM358NですがNJM4580Dも同じです。
センサーはブレッドボードには刺さりません、なので、下図の様な物を作りました。
受信センサーの出力をオペアンプNJM4580Dの1回路目で100倍増幅し、2回路目で22倍増幅なので
2200倍の交流増幅(反転増幅)を行っています、
この信号をショットキー・バリア・ダイオード(BAT43)を使用して半波整流(直流)にし超音波信号を検出する為に検波を行っています。
で、この後はArduinoのアナログ0番ピンに入力しています。
上の配線図には、NJM4580Dの電源接続を省いています注意願います。
尚、ゲイン調整を行いたい人は220KΩ抵抗を100k〜330kΩ辺りで行ってみて下さい。
センサー自体は4mまでOKの様ですが、この回路では4cm〜100cmまでしか測定出来ません。
送信側センサーの電圧が20Vp-pまでOKなので送信出力電圧を上げられれば距離を伸ばせると思いますがぁ....
《スケッチ2》
---------------------------------------------------------------------
#define USS_T_PIN 7 // 送信側センサー接続のピン番号(デジタル接続)
#define USS_R_PIN 0 // 受信側センサー接続のピン番号(アナログ接続)
// 電源起動時とリセットの時だけのみ処理される関数(初期化と設定処理)
void setup() {
Serial.begin(9600); // 9600bpsでシリアル通信のポートを開きます
}
// 繰り返し実行される処理の関数(メインの処理)
void loop() {
int ans ;
ans = UsonicMeasurRead(USS_T_PIN,USS_R_PIN,20,30) ;
Serial.print(ans) ; // 表示を行う
Serial.println("mm") ;
delay(500) ; // 500ms後に繰り返す
}
// 超音波センサーから距離を得る処理
// txpin=送信接続ピン rxpin=受信接続ピン temp=周辺温度 correction=距離補正
// 距離をmmで返す(検出できない場合は0を返す)
int UsonicMeasurRead(int txpin,int rxpin,int temp,int correction)
{
unsigned long t , t2 ;
int ans , val ;
ans = 0 ;
tone(txpin,40000) ; // 送信センサーに40KHz信号を200us出力
delayMicroseconds(200) ;
noTone(txpin) ; // 40KHz信号停止
t = micros() ; // 現在の時間を記憶する
while(1) {
val = analogRead(rxpin) ; // 受信センサーの値を読む
t2 = micros() - t ; // 時間をカウントする
if (val >= 410) break ; // 受信値の電圧が2V以上なら反射信号とする
if (t2 >= 30000) break ; // 反射信号が返って来なかった場合の処理
}
if (t2 < 30000) {
t = 331500 + (600 * temp) ; // 音波の伝搬する速度を求める
t = (t * t2) / 1000000 ; // 距離の計算
ans = t / 2 ; // 往復なので÷2
ans = ans + correction ; // 距離の補正値を加える
}
return ans ;
}
---------------------------------------------------------------------
送信器センサーにArduinoの7番ピンから40KHzの信号を200us出力します、40KHz信号はArduinoの標準関数tone()を使用して行っています。
その後アナログ0番ピンより受信器センサーの値を読み続け2.0V(410)以上なら超音波の反射が有ったと判断しています。
(送信器から回り込む直接波が有る為に2.0Vとしています)
で、その間の時刻カウントはArduinoの標準関数micros()で行い、30ms以上反射波が無かった場合はタイムアウトです。
超音波センサーから距離を得る関数の説明
ans = UsonicMeasurRead(txpin,rxpin,temp,correction)
txpin :送信側センサーに接続しているピンの番号を指定します。
rxpin :受信側センサーに接続しているピンの番号を指定します。
temp :超音波周辺の温度を指定します(今回は20℃を設定)
correction:距離の補正値を指定します(今回は30mmを設定)
ans :距離をmmで返します、反射波が無かった場合は0を返します。
何時でも何処でも正確な距離を測りたい人は温度センサーを付けて補正を行って下さい。
また、今回のこの回路ではどの距離でも常に約30mm程短く測量されました、
なので距離補正値30mm入れています。
アナログ入力
Arduinoでアナログ値を読むにはanalogRead(pin)関数を利用します、pinには読込むアナログ端子のピン番号を入れます、
今回は0番端子を利用です、0〜5番まで有りますね。
Arduinoは電圧0V〜5Vまでを数値の 0〜1023の範囲で読込むので今回は2.0V(410)を入力電圧の閾値にしています、
ソフトウエアでコンパレータの役目を行っています。
《その他》
実験風景です。
赤外線距離センサーよりは超音波センサーの方が距離は正確に測れます。
配線図1のセンサーモジュールは2012/06現在で1500円と結構安く、制御も簡単なのでお勧めしておきます。
配線図2は500円もあれば製作可能でしょう、防滴型のセンサーを使いたいとかぁ、1m以内の場合とかぁ、
言う場合はこちらでも良いでしょう。
また、送信出力電圧を上げられれば距離を伸ばす事が出来ます。
9V〜12Vの別電源を用意してトランジスターかFETを使って出力するかぁ、
後は5V電源ならMAX232のRS232C用レベル変換ICを利用するかぁ、でしょうか。
それと、こちらはPICでの使用例ですが、この方法を行えば160cm位なら距離を伸ばす事が出来るでしょう。
基板化する場合は、送信センサーからの直接波が回り込まない様な工夫が必要かもね。
また、基板化すると雑音も小さくなり距離が稼げるかもね。
まぁ、色々トライ&調整してみてみて。
それとぉ、超音波の反射はガラス・紙・ゴム・木・金属・コンクリート等は100%反射しますが、
布類・綿・グラスウールなどの物体は音を吸収します、なのでぇ物体検出は無理っぽいですよ。
リンクの見直し(*3) 2020/03/20
回路図の追加(*2) 2014/02/06
追記(*1) 2013/06/17
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.