■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、PCとの接続事例)
■特殊メイク、特殊材料の販売 ※特殊メイクのコーナーはこちらに移りました。
Top(お知らせ) 製品紹介 使い方とサンプルプログラム 通信販売 リンク ロボット掲示板 会社案内
 Easy Robotics for all enthusiastic people!!!  ---HOBBY ROBOT PARTS SHOP ASAKUSAGIKEN---   Since 2003...

PICと超音波距離センサ(PING)

はじめに

 浅草ギ研で販売しているもう一つのパルス幅出力タイプのセンサ
センサで、超音波距離センサ(PING)があります。これもパルス幅を測定するだけなので、前回行ったラジコン受信機2軸加速度センサと同じ方法で値を読み取ることができます。ここではこの超音波センサ、PINGとPICとの接続を説明します。

なお、回路の詳細やデバックモニタの使い方など、前のPIC関連のページもあわせてお読み下さい。


超音波距離センサ PING)))

PINGについてはこちらでも説明しています。
PINGの商品説明のページ

ここでは簡単にピン配列と動作原理を説明します。(上のページの説明と同じものです。)

<接続図>

<動作イメージ>



 

 
超音波発射から物体に反射してくるまでの時間を測定することにより距離が測定できる。
<動作タイミング>



1)SIGピンにつないだマイコンののIOピン(以後IOピン)を出力に設定し、5μS間Highのパルス(トリガ入力といいます。)を加えます。
2)IOピンはトリガ入力後は入力に設定し、結果出力を待ちます。
3)PING側ではトリガ入力が入ると超音波発振準備をし、超音波を発射します。超音波を発振した後にSIGピンがHighになり、物体に跳ね返った超音波が戻ってきた時点でSIGピンがLOWになります。この結果出力時間を測定することにより物体までの距離が測定できます。
※PINGは超音波発信中に自分の発振した超音波を拾ってしまう可能性がありますので、超音波発射後はしばらく受信動作を停止します。この時間と発振準備にかかる時間がホールドオフ時間になります。ホールドオフ時間は350uSで固定です。



回路図



PINGの信号線SIGにGP0を接続し、GP0からトリガパルス出力および、PINGからのパルス出力を読み取ります。特に難しいところはありませんね。
電源回路などについては「PICを使ってみる」を参照願います。
結果の出力(デバックモニタ)については「PICとPCとの接続」を参照願います。

接続ですが、前回と同様に、PIC基板に出ているヘッダピンを2550コネクタが付いたケーブルで接続します。



実際に接続した様子はこのような感じです。




プログラム

プログラムですが、12F675使用時のポイントは次の通り、

1) 12F675でデジタルIO入力を使うにはADCを切る必要がある。

2)内部クロック使用の場合はカウントが1/4になる。

以上は前の方のページを参照願います。
以下、PINGを使う場合のポイントです。

3)PINGが正常に立ち上がるまで待つ必用がある。


今回、ココが一番ハマりました。普通にロボット用としてセンサーのプログラムを書く場合は、他のセンサーなどの設定でロボットが起動してから実際に距離を測定するまでに結構時間が空きますので問題ありませんが、PINGだけをテストするプログラムを書く場合には、距離測定までにあまりにも早いとPINGが起動しないうちにパルスを読み取るところまで走ってしまい、正常に動かない(トリガを加えても結果パルスが生成されない=無限ループに陥る)ことがわかりました。
これは一見、PINGが壊れているように見えるので要注意です。今回は読み取り前に適当にディレイを入れて、PINGが正常に立ち上がるまで待ちます。


4)クロックの分周値


PINGの仕様を見ると、最小距離=115uS、最大距離=18.5mS、とかなりパルス幅のレンジが広いので、距離を長く測定しようとすると解像度が悪くなるという結果になります。
いつもの、タイマ0で分周した場合のカウント値の表を作ると、

 
115uS
18.5mS
0分周
115
18500
8分周
14.4
2312.5
32分周
3.6
578.1
64分周
1.8
289
128分周
0.9
144.5
※内部4MHzクロック使用だが、12F675の場合は内部クロック使用時は1/4になる。1MHz->1uSで1カウント。

ということになり、128分周がよさげですが、幅が結構広いので解像度は低くなります。
今回は128分周でテストしてみましたが、近距離を高解像度で測定したい場合は分周を下げると良いでしょう。この場合、255の値を超える(つまり遠い距離を測ろうとすると)と値が0〜にもどりますので注意してください。

以下が、上記を踏まえて作ったプログラムです。




テキストデータはこちら PIC-PING.txt

タイマ0の設定までは前回とほぼ同じです。
タイマ0の設定は128分周なので、今回は RTCC_128 になります。

次の delay_ms(1000); で、PINGが正常に動き始めるまで待っています。今回、この行が無い状態で動かそうとしていて、トリガパルスは加えているのにPINGの結果パルスが出力されなくて悩みました。PINGはトリガを受け取って超音波を発射するときにLEDが点灯しますので正常動作しているかどうかを確認できます。1000mS待ってますがもっと短くてもおそらく問題ないですが、このウェイトを入れないとあとのプログラムで while(!(input(PIN_A0))); とかやってますのでパルスが立ち上がらなくてこのwileを無限ループしてしまいます。本当はこのような書き方ではなく、何回かループしたらタイムアウトとかにした方が、なにかの拍子でPINGが壊れてもプログラムは止まらない、というようにした方が良いでしょう。今回、面倒なのとわかりやすさからそのままにしてます。

その他は前回までと同じなのでそちらを参照願います。  


ちなみに、タイマ0が8ビットカウンタなのが問題?と考えるかもしれませんが、16ビットタイマのタイマ1は8分周までしかできないので、どちらにしても18mSぐらいまでは測定できません。但し、近距離を高解像度で測定したい場合はタイマ1を使用してもよいでしょう。この場合は次のようにしてみてください。

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128);

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);

set_timer0(0);

set_timer1(0);

printf("Dist=%u\r\n\r\n",get_timer0());

printf("Dist=%Lu\r\n\r\n",get_timer1());

タイマ1は16ビット幅なのでprintf( ) 関数で出力するときは u% ではなく %Lu になりますので注意。Lはlong型を明示しています。分周の設定値もタイマ0のような感じで T1_DIV_8 ではなく BY が入りますので注意。

この辺りは 「C言語によるPICプログラミング入門 後閑哲也著」 に詳しく書いてあります。CCS-CでPICのプログラムを組む場合は絶対に置いておきたい一冊です。


結果


上のプログラムをコンパイルし、PICライタで書き込んだらPICボードに差し込んで電源を入れます。いつものようにPCで結果をモニタすると下記のように表示されます。

尚、PC上でハイパーターミナルによるデバックについては「PICとPCとの接続」を参照願います。

センサーに手をかざしてだんだん遠ざけた様子。




電卓をカベにして距離を測定してみました。センサーにくっつけた状態が次の通り、




ちょっと離してみたところ、




もうちょっと離してみたところ、




浅草ギ研の作業場の天井は結構高くて、3mぐらいあります。天井にセンサを向けたところ、




遠くのカベに向けたところ(5M先ぐらい?)ではこの通り、



ということで距離も測れるようになりました。



2005年8月18日
 
(C)Copylight 2003. 有限会社浅草ギ研 | 通信販売の法規(訪問販売法第8条)に基づく通信販売業者の表示