赤外線測距モジュールで物体の距離を測ってみます(1/2)

〔2/2〕   〔Arduinoの動かせ方入門に戻る〕



 物体の距離を測るには色々有りますが、 先ず近距離(0cm-3cm位)の物体を測ると言いますか物体の存在を検知する為のセンサーが、 近接センサー(磁気センサー)やリードスイッチに光電センサー(フォトセンサー)です。
そして中距離(3cm-5m位)の物体を測るのに超音波距離センサーと今回この頁で扱う赤外線距離センサーです。 最後に長距離(5m-数百m)の物体を測るのにはレーザー距離センサーでしょうか。

近接センサー・フォトセンサーの話はこちらを参照して下さい。
Arduinoで超音波距離センサーの話はこちらを参照して下さい。
PIC16F1827で超音波距離センサーの話はこちらを参照して下さい。

測定原理図 測定原理としては、

光を照射して物体で反射してきた光を受光されるまでの時間を測定し、その時間差を距離に換算 する方式。
レーザー距離センサー
超音波距離センサー(これは音ですがね)


受光素子にPSDやC-MOS(デジカメのセンサー)を使い、光を受光素子面で受ければ距離におおじて 光を受ける位置が変化します、その位置を距離に換算する方式。
赤外線距離センサー


《配線図》

配線図 配線図です、電源線と電解コンデンサの表示が変ですけど気にしないで下さい。 ^^)
10uFのコンデンサはデータシートに入れた方が良さげって書いて有るので入れて置きました。
0.1uFのコンデンサは入れて置きましょう、センサー出力が気持ち安定します。

赤外線距離センサーはGP2Y0A21YKを使用します。
このセンサーは測距結果を電圧にして出力するので そのままアナログ入力に接続すればOKな嬉しいかぎりのセンサーです。
すべてのセンサーがこうあってくれれば楽なんですがねぇ。
(ただ、電圧と距離の関係が直線でないのが難点ですよねぇ)

実はこのセンサーかなり前に、車の後ろに着けて遊んではいたのですがぁ、
よ〜く見るとMyHPに記事が無いですね、今更って気もしますがぁ、
MyHPの充実って事で記事にしておきます。ww ^^;

GP2Y0A21YK:測距範囲10-80cm  400円
GP2Y0A02YK:測距範囲20-150cm 800円
GP2Y0A710K:測距範囲1m-5.5m  1200円 (2012年5月現在の秋月電子での通販価格です)

電圧と距離の関係グラフ
これが電圧と距離の関係グラフです、 データシートからの抜粋です、 ね、直線でないでしょう。
これを距離に変換する式が悩ましいのですぅ。

変換する方法は他のHPで色々書いて有る様なので そちらを検索して参照してもらうとして ここでは単純に行きますです、はい。
ただぁ、距離が4cm以下になると出力電圧が下がって来ます 注意が必要ですね。
それに50cm以上は電圧の変化が少ないので出力の精度がかなり落ちます、 オペアンプなどで2倍ぐらいに増幅した方が良いかもね。

《スケッチ1》

@まずは、上記図画面の様に配線しましょう。
Aarduinoボード(Arduino Duemilanove 328)はUSBケーブルで接続して、arduino IDEを起動させます。
BIDEに下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
 とりあえずアナログ0番の信号をIDEのシリアルモニター画面に表示して見るだけです。
---------------------------------------------------------------------
 void setup() {
     Serial.begin(9600) ;     // 9600bpsでシリアル通信のポートを開きます
 }
 void loop() {
     int ans ;

     ans = analogRead(0)  ;   // センサーから読込む
     Serial.println(ans) ;    // シリアルモニターに表示させる
     delay(500) ;             // 500ms時間待ち
 }
---------------------------------------------------------------------
CIDEツールバーの赤枠部分「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを
 行います。

upload


実行結果1  D正常終了後、ツールバーの右側のアイコン「SerialMonitor」
  ボタンをクリックしてシリアルモニター画面を起動させます。

 E赤外線距離センサーの前に物体をかざしてみましょう、
  左図の様に値が変化するはずです。

 でもぉ、値がばらついています、このままではダメですね。

《スケッチ2》

こんどのスケッチはセンサーから読み込んだ値を平均化して距離に変換しています。
このセンサー値はバラつきが有るので今何センチとかの精度は無理です、
なのでぇ、AnaToCm()関数が20と返したら、20cm以内(10cm〜20cmに物体有り)とします。
---------------------------------------------------------------------
// 電源起動時とリセットの時だけのみ処理される(初期化と設定処理)
void setup() {
     Serial.begin(9600) ;                    // 9600bpsでシリアル通信のポートを開きます
}
// 繰り返し実行される処理(メインの処理)
void loop() {
     int val ;

     val = IDSread(0)  ;                     // センサーから読み込む
     Serial.print(val) ;                     // アナログ値を表示する
     Serial.print("  ") ;
     Serial.println(AnaToCm(val)) ;          // 距離を表示する
     delay(500) ;                            // 500ms後に繰り返す
}
// センサーからの読み込み処理(100回読込み平均をとる)
int IDSread(int PinNo) {
     long ans ;
     int i ;

     ans = 0 ;
     for (i=0 ; i < 100 ; i++) {
          ans  = ans + analogRead(PinNo) ;   // 指定のアナログピン(0番端子)から読取ります
     }
     return ans/100 ;                        // 100回の平均値を返します
}
// センサーから読込んだ値を距離(cm)に変換する処理
// 距離が短くなるとセンサー値は大きくなるが、4cm以内になると逆に小さくなっていく注意
int AnaToCm(int analogValue) {

     if (analogValue <  85 ) return(0)  ;     // 60cm以上離れている
     if (analogValue >= 470) return(10) ;     // 10cm以内
     if (analogValue >= 260) return(20) ;     // 20cm以内(10-20cm)
     if (analogValue >= 165) return(30) ;     // 30cm以内(20-30cm)
     if (analogValue >= 126) return(40) ;     // 40cm以内(30-40cm)
     if (analogValue >= 105) return(50) ;     // 50cm以内(40-50cm)
     if (analogValue >= 85 ) return(60) ;     // 60cm以内(50-60cm)
     return(-1) ;                             // この行実行は有得ないと思うが....
}
---------------------------------------------------------------------
実行結果2  実行した結果です、数値左がセンサー値を100回読んでその平均値で
 数値右が距離に変換した値(20-30cmの範囲に物体有りと判断)です。

 それにしてもぉ、
 センサー値5カウントぐらいのバラつきがまだ有りますねぇ〜
 (40cm以上になるとまだバラついてきます、やっぱり増幅?)
 (何とかならない物でしょうか?)
 (移動平均を取って見ようかなぁ、でもぉめんどいしぃ.....)

 AnaToCm()関数内の85,470,105とかの数値は、物体とセンサーの間を
 メジャーで実際に測りそこのアナログ値(センサー値)を読み取って閾値
 にしました、調整したい人はこの値を変更して下さい。

《その他》

実際に他のHPに書いて有る計算式を数種類試したのですがぁ、なんとなく今一つでぇ
自分の欲しい距離ポイントをメジャーで測り実測データを利用したやり方がお勧めです。

距離を測るよりはぁ、数十センチで物体の存在を検知するセンサーとして利用した方が良さげぇ〜。
物体のない時のセンサー値を読んどいてぇ、物体が来た時のセンサー値と比較すればもおバッチリ
見たいなぁ感じぃ。

取付け例1

この写真は自動車の後ろに取り付けた失敗の例です。
センサーをアクリル板で囲って取り付けました、アクリル板の下側は穴を空けては入るのですがぁ、
その程度では水滴は取れません、蒸れ蒸れです、そのうち錆び発生しています。
下側はアクリルで囲まない方が良いかも、でも埃泥がぁ....

車の後ろに物体が無い場合、センサーはアクリル板で反射して反応します、 なのでぇ、センサーとアクリル板の距離が1.5cm有ります、って事は電源が入ると常に 500mV程出力状態です、これは車の後ろ60cm辺りに障害物が有るのと同じ状態になります。
実際に後ろに障害物が有ればそこで赤外線は反射されます、アクリル板の反射よりは障害物からの反射が強いのでしょう。
だからぁ、車のスケッチでは4cm以内と60cm以上はアナログ値は無視していました。
アクリル板とセンサーは隙間なくした方が良いと思うがぁ、水滴がぁ......
リモコンとか見るとぉ、黒い板付いているようですねぇ......

新しい測距モジュール(GP2Y0E03)が販売されましたねぇ、
  動作させて見ましたその記事は(2/2)の次ページにて。 *1)
  (精度が欲しい人はこのGP2Y0E03を利用しましょう、±1cm以内位で読み取れます)



追記(*1) 2014/08/03


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2014 Shigehiro Kimura All Rights Reserved.