電子工作43 – 超音波センサを使った超短距離送受信の試み

 

概要

   電子工作42で超音波センサに関わったついでに今回は3つの超音波パターンを短距離間送って受け取る実験をしてみた。 

 

実験の要点は:

(1)     3個の超音波パターンを送るプログラムの作成。

(2)     受け取る側でそれらを個々に区別認識するプログラムの作成。

(3)     実際に動作するかどうかの検討。

 

回路

 発信器

  下に3つの超音波パターン発生器の回路図を示す。 その目的のために3つのInput SWが導入してある。個々のInput SWから下述するよな違った超音波パターンが発生する。 

 

受信器

  この回路では送信側のInput SW1が押されるとLED1が点灯し、Input SW2が押されるとLED2が、さらにInput SW3が押されるとLED3が点灯する。個々のInput SWをもう一度押すと消灯する。押す毎にこの反転を繰り返す。

 

実験中―左のボードが発信側、右が受信側。 一番下に送信と受信用の超音波センサが向かい合っている。送信距離は電子工作42で述べたように短い。

      左のボード下部の3つのSWに反応して一部点灯している赤い3個のLEDが右側のボード上に見える。修理のため海外旅行してきた愛用のオシロも右手に見える。

 

 波形の解析

   上記3つの超音波パターン発生器の3つのInput SW1、Input SW2、 Input SW3を押すとそれぞれ下に示すようなパターンが受け側の12F629のGP0(Pin7)に入力される(このポイントでオシロで測定した)。

                  (波形1) Input SW1を押した時に発生するパターンで、4本の方形波がほぼ50%のデュティー比できれいに展開されている。1パターンの全幅は約300ms

                         で、各方形波の幅と2つの方形波間の間隔はともに40ms前後である。

 

                             

(波形2) Input SW2を押した時に発生するパターンで、2番目の方形波が欠けている。

                             

(波形3) Input SW3を押した時に発生するパターンで、3番目の方形波が欠けている。

 

(波形4) 3つの異なるInput SWを次々と押した時に発生するパターンで、上に示し3つの波形パターンの5分の1のスケールで表示してある。

               

プログラム

3つの超音波パターン発生器用プログラム

  送り手側のこのプログラムの概要は以下のようである。

1)     3つのInput SWのいずれから入力があったらLoop1, Loop2, Loop3などに進む、なければ待つ。

2)     例えは、Loop1へ飛んだ場合、H(40KHz)を5ms、Lを80ms発生させるサブルーチンを使ってHHHH波パターンを発生させる。

3)     Loop2とLoop3に飛んだ場合も同様にしてHLHH波とHHLH波パターンをそれぞれ発生させる。

 

'********* プログラム ************

'UltraSoundPWM40KHz3.bas   2010.6.9  3 SWs for 3 signal patterns

'PIC16F628A with 4MHz internal

'******** ピン接続 ************

'Pin 14 - Vdd (5V)

'Pin 5 - Vss (GND)

'Pin 4 - /MCLR (Reset) connected to Vdd via 4.7K

'Pin 6 - RB0 connected to Input SW1

'Pin 7 - RB1 connected to Input SW2

'Pin 8 - RB2 connected to Input SW2

'Pin 9  - RB3 connected to Tr driving a ultrasonic sensor (T40-16)

'******** プログラム本体 ********

CMCON=7              'No comparator

VRCON=0              'A/D voltage reference disabled

TRISB=%11110111      'RB3 - PWM output

TRISA.5=1            'Reset

PR2=24               'Set PWM for 40 KHz (25:38KHz) ここで40KHz波発生のための設定をする

CCPR1L=13            'Set PWM for 50% duty cycle

CCP1CON=%00001100    'PWM mode selection =12 in decimal

T2CON=%00000100      'Timer2 ON + 1:1 prescale

InputSW1 var PORTB.0  'Input SW1

InputSW2 var PORTB.1  'Input SW2

InputSW3 var PORTB.2  'Input SW3

 

InputSWLoop:

Pause 500  'Giving 500ms-space between 3-peak pulses when Input SW was kept pressed パターン間の間隔として500msを設定

CCP1CON=0 'PWM OFF

If InputSW1=0 then Loop1 ‘SWエントリルーチン

If InputSW2=0 then Loop2

If InputSW3=0 then Loop3

Goto InputSWLoop

 

Loop1:

Gosub H5L80OnOff 'Produce 4 peaks 4つの方形波を含むHHHH波パターンを発生させる

Gosub H5L80OnOff

Gosub H5L80OnOff

Gosub H5L80OnOff

Goto InputSWLoop

 

Loop2:

osub H5L80OnOff 'Produce 3 peaks  3つの方形波を含むHLHH波パターンを発生させる

Pause 5          'No peak section

Pause 80

Gosub H5L80OnOff

Gosub H5L80OnOff

Goto InputSWLoop

 

Loop3:

Gosub H5L80OnOff 'Produce 3 peaks  3つの方形波を含むHHLH波パターンを発生させる

Gosub H5L80OnOff

Pause 5          'No peak section

Pause 80

Gosub H5L80OnOff

Goto InputSWLoop

 

H5L80OnOff: 'Subroutine High5ms + Low80ms. Two values 5ms and 80ms were decided on a trial and error basis while checking a pulse pattern at Point (C). – GP0 (Pin7) HとLを作るサブルーチン

CCP1CON=12 'PWM ON for 5ms PWMを5ms ON この5msと80msの値は、受信側のポイント(C)での波形が適当な幅と出来るだけ50%のデュティー比になるように実験的に決めた

Pause 5

CCP1CON=0 'PWM OFF for 80ms PWMを80ms OFF

Pause 80

Return

 

'******** プログラムの終了 ********

'Note:

   'melabs U2 Programmer's configurations:

   'OSC - INTOSCIO; WDTE - Enable; Power-up Timer - Disable

   'MCLRpin – Reset ; BODEN - Enable; Low voltage Programming - Disable, Code – Not Protect, Data EEPROM- Not Protect

 

 

超音波信号を受けて3個のLEDをON/OFFする回路用プログラム

  受け側のこのプログラムの概要は以下のようである。

1)     30個のデータを集めるのでその保存場所を確保する。

2)     信号待ちしながら最初の方形波の端、つまりHが検知されたら信号パターンが送られて来たと解釈し、以下で10ms間隔で30個のデータを集め保存する。1つのパターンの全幅が300msなので300ms/10ms=30個とした。集めた各データの中身は1か0である。

3)     (波形1)を検知する原理は、先ず全幅が300ms区間の4つの方形波部分の“1”の全数を推定する。最大25、最小16と考えて、もし、実際に測定した数がこの2つの間に入ればこのパターンは(波形1)と断定しLED1を点灯させる。

4)     (波形2)を検知する原理は、このパターンでは2つ目の方形波が欠けているのD1からD16までの総和が最大5、最小3位と実験的に推定し、実際に測定した数がこの2つの間に入ればこのパターンは(波形2)と断定しLED2を点灯させる。

5)     (波形3)を検知する原理は、このパターンでは3つ目の方形波が欠けているのD17からD30までの総和が実験的に最大3、最小1位と推定し、実際に測定した数がこの2つの間に入ればこのパターンは(波形3)と断定しLED3を点灯させる。ここで最大3、最小1と予想以上に小さい値になったのは全幅300ms区間をD1−D30が正しくカバーしていないためかも知れない。

 

'********* プログラム ************

'SoundSensor3LED.bas  -  2010.6.10 Program to sense T4016 and turn on 3 LEDs

'12F629 with 4MHz internal

'******** ピン接続 ************

'Pin 1: Vdd (5V)

'Pin 8: Vss (GND)

'Pin 7: GPIO.0: input from TC4069

'Pin 4: GPIO.3: input - /MCLR (reset) via R=10K

'Pin 2: output - to LED (G) via R (indicator)

'Pin 6: GPIO.1: output - to LED1 (R) via R=470

'Pin 5: GPIO.2: output - to LED2 (R) via R=470

'Pin 3: GPIO.4: output - to LED3 (R) via R=470

'******** プログラム本体 ********

CMCON=7 'Comparator off

TRISIO=%001001 'all outputs except GPIO.0 & 3

D1 var byte  'storage for D1 (1 or 0) covering max. 4 peaks

D2 var byte

D3 var byte

D4 var byte

D5 var byte

D6 var byte

D7 var byte

D8 var byte

D9 var byte

D10 var byte

D11 var byte

D12 var byte

D13 var byte

D14 var byte

D15 var byte

D16 var byte

D17 var byte

D18 var byte

D19 var byte

D20 var byte

D21 var byte

D22 var byte

D23 var byte

D24 var byte

D25 var byte

D26 var byte

D27 var byte

D28 var byte

D29 var byte

D30 var byte

A1 var byte 'storage

A2 var byte

TotalA  var byte

B var byte

C var byte

HorLdata var GPIO.0 'Input from invertor TC4069

LED var GPIO.5 'Indicator when a pulse is accepted

LED1 var GPIO.1 'For driving LED1

LED2 var GPIO.2 'For driving LED2         

LED3 var GPIO.4 'For driving LED3

 

HorLdata=0

LED=0

LED1=0

LED2=0

LED3=0

 

Start:

If HorLdata=1 then ReadData 'Waiting the arrival of the first H peak  最初の方形波を待つ、検知したらReadData以下に進む

Goto Start

ReadData: ‘ここから10ms毎に30個のデータD1-D30を集める(各データは1か0、 4個の方形波を含む部分の幅約300msなので300ms/10ms=30個)

Pause 10

D1=HorLdata

Pause 10

D2=HorLdata

Pause 10

D3=HorLdata

Pause 10

D4=HorLdata

Pause 10

D5=HorLdata

Pause 10

D6=HorLdata

Pause 10

D7=HorLdata

Pause 10

D8=HorLdata

Pause 10

D9=HorLdata

Pause 10

D10=HorLdata

Pause 10

D11=HorLdata

Pause 10

D12=HorLdata

Pause 10

D13=HorLdata

Pause 10

D14=HorLdata

Pause 10

D15=HorLdata

Pause 10

D16=HorLdata

Pause 10

D17=HorLdata

Pause 10

D18=HorLdata

Pause 10

D19=HorLdata

Pause 10

D20=HorLdata

Pause 10

D21=HorLdata

Pause 10

D22=HorLdata

Pause 10

D23=HorLdata

Pause 10

D24=HorLdata

Pause 10

D25=HorLdata

Pause 10

D26=HorLdata

Pause 10

D27=HorLdata

Pause 10

D28=HorLdata

Pause 10

D29=HorLdata

Pause 10

D30=HorLdata

Pause 10

A1=D1+D2+D3+D4+D5+D6+D7+D8+D9+D10+D11+D12+D13+D14+D15

A2=D16+D17+D18+D19+D20+D21+D22+D23+D24+D25+D26+D27+D28+D29+D30

TotalA=A1+A2 ‘30個のデータD1-D30の和を求める

If 16=<(TotalA) and (TotalA)<25 then JumpA  'if OK, go to JumpA  Parentheses essential! 総和が16と25との間に入っているかどうかチェックし、入っていれば波形1と断定 

B=D1+D2+D3+D4+D5+D6+D7+D8+D9+D10+D11+D12+D13+D14+D15+D16

If 3=<(B) and (B)<5 then JumpB ‘D1−D16の総和が3と5の間に入っているかどうかチェックし、入っていれば波形2と断定

C=D17+D18+D19+D20+D21+D22+D23+D24+D25+D26+D27+D28+D29+D30

If 1=<(C) and (C)<3 then JumpC ‘D17−D30の総和が1と3の間に入っているかどうかチェックし、入っていれば波形3と断定。範囲が意外と小さくでた。

Goto Start

 

JumpA:

High LED 'Turn on LED  Indicator when a pulse is accepted

Toggle LED1 ‘LED1を1回ごとに点灯/消灯の繰り返し

Pause 200 'Wait 200ms

Low LED 'Turn off LED

Goto Start

 

JumpB:

High LED 'Turn on LED

Toggle LED2

Pause 200 'Wait 200ms

Low LED 'Turn off LED

Goto Start

 

JumpC:

High LED 'Turn on LED

Toggle LED3

Pause 200 'Wait 200ms

Low LED 'Turn off LED

Goto Start

 

'******** プログラムの終了 ********

'Note:

   'melabs U2 Programmer's configurations:

   'FOSC - INTOSC; WDTE - Enable; Power-up Timer - Disable

   'MCLRpin – Reset ; BODEN - Enable; CD - Disable; CDP - Disable.

 

結論など

1)     3つの超音波のパターンを送信し、受信側で個々のものを区別認識することが出来た。

2)     送信側のプログラムはサブルーチンの使用によってすっきりした。

3)     受信側のプログラムでは、30個のデータを集めてそれらを操作する新しいロジックを採用した。

4)     送受信距離は相変わらず短く、電子工作42に示したものと変わらない。電圧を9V−>12V−>15Vと上げると距離は伸びる。

5)     差しあたって何か役立つものに応用できるか思いつかない。

6)     方形波の数を増せば送れる信号の数が増える。

7)     波形パターンを読込む新しいロジックが試せたのが最大の収穫だった。

 

 

改良した超音波信号を受けて3個のLEDをON/OFFする回路用プログラム(2010.6.15)

  上記の'SoundSensor3LED.bas長いのでArray(配列)を使って短く見栄えを良くし、また、メモリが足りなくなったので12F629の代わりに12F683を使った。両者の間のピン配置は同じなので、12F683にこの新しいプログラムを入れて差し替えればよい。 Arrayの使い方に関しいろいろWeb上を探しまわったがに良く分からず、試行錯誤で何とか仕上げた。結局、30個のデータの保存領域確保とそれらの10ms毎の読込み、さらに30個のデータの加算などでArray を使うことによりコンパクトにすることが出来た。送受信の動作も前と変わらない。

 

Array (配列)の話: うまく利用するとプログラムがコンパクトに出来る。

                              変数名 var 型

型名

ビット長

最大値(10進)

BIT

0−1

BYTE

0−255

WORD

16

0−65535

LONG*

32

−2147483647 ―

2147483647

*LONG型は18Fシリーズのみで使用可

 

例: Array var BYTE [4] の意味は以下の領域がメモリ内に確保されるということ。 [x]のような括弧を使う。

    Array[0] + + + + + + + +

    Array[1] + + + + + + + +

    Array[2] + + + + + + + +

    Array[3] + + + + + + + +

7                      0 (8bit)

 

例: D var BIT[30] (今回のプログラム中で使われている)は同様にして BIT型でビット長が1なので以下のようになる。+には“1”か“0”が入る。

    D[0] +

    D[1] +

        |

   D[29] +

 

プログラム中では以下の様に使う。

I var Byte

D var Bit[30]

I=0

For i=0 to 29   'Reading 30 data once every 10 ms - D[0], D[1] ,.... D[29]  ここから10ms毎に30個のデータD[0]-D[29]を集める

D[i]=HorLdata  ‘ここがポイント!

Pause 10

Next I

 

'********* プログラム ************

'SoundSensor3LED683A.bas  - 2010.6.16  modified from SoundSensor3LED.bas  Previous program was shortened using arrays  Program works at last!

'12F683 used with internal clock 4MHz

'******** ピン接続 ************

'Pin 1: Vdd (5V)

'Pin 8: Vss (GND)

'Pin 7: GPIO.0: input from TC4069

'Pin 4: GPIO.3: input - /MCLR (reset) via R=10K

'Pin 2: output - to LED (G) via R (indicator)

'Pin 6: GPIO.1: output - to LED1 (R) via R=4.7K

'Pin 5: GPIO.2: output - to LED2 (R) via R

'Pin 3: GPIO.4: output - to LED3 (R) via R

'******** プログラム本体 ********

CMCON0=7 'Comparator off   ‘この2行も必須のようだ

ANSEL=0 'All ports digital

TRISIO=%001001 'all outputs except GPIO.0 & 3

 

A1 var byte

A2 var byte

TotalA  var byte

B var byte

C var byte

HorLdata var GPIO.0 'Input from invertor TC4069

LED var GPIO.5 'Indicator when a pulse is accepted

LED1 var GPIO.1 'For driving LED1

LED2 var GPIO.2 'For driving LED2         

LED3 var GPIO.4 'For driving LED3

i var byte  'Counter for 30 data collection

 

i=0            'Secure 30 data storages - D[0] var Byte, D[1] var Byte, ... D[29] var Byte, Arrayを使って30個のデータの保存領域確保

For i=0 to 29   ‘ここがポイント!

D var bit[30]  'No need to be "BYTE" because the bit length of D is 1, that is, "1" or "0"   Dの中身は“1”か“0”なのでBit型の配列でOK!

next i

 

HorLdata=0

LED=0

LED1=0

LED2=0

LED3=0

 

Start:

If HorLdata=1 then ReadData 'Waiting the arrival of the first H peak  最初の方形波を待つ、検知したらReadData以下に進む

goto Start

ReadData:

i=0

For i=0 to 29   'Reading 30 data once every 10 ms - D[0], D[1] ,.... D[29]  ここから10ms毎に30個のデータD[0]-D[29]を集める

D[i]=HorLdata  ‘ここがポイント!

Pause 10

Next i

 

Pause 20

 

A1=0

For i=0 to 15  'A1=D[0]+.....+D[15] ここでD[0]+.....+D[15]の和を求める

A1=A1+D[i]

Next i

 

A2=0

For i=16 to 29  'A2=D[16]+ ....+D[29] ここでD[16]+.....+D[29]の和を求める

A2=A2+D[i]

Next i

TotalA=A1+A2

If 16=<(TotalA) and (TotalA)<25 then JumpA  'if OK, go to Jump1  Parentheses essential!

 

B=0

For i=0 to 15 'B=D[0]+.....+D[15] ここでD[0]+.....+D[15]の和を求める

B=B+D[i]

Next i

If 3=<(B) and (B)<6 then JumpB  ‘ここの範囲を決める数値も少し変えた

 

C=0

For i=16 to 29  'C=D[16]+ ....+D[29] ここでD[16]+.....+D[29]の和を求める

C=C+D[i]

Next i

If 3=<(C) and (C)<6 then JumpC  ‘ここの範囲を決める数値も少し変えた

Goto Start

 

JumpA:

High LED 'Turn on LED  Indicator when a pulse is accepted

Toggle LED1

Pause 200 'Wait 200ms

Low LED 'Turn off LED

GOTO Start

 

JumpB:

High LED 'Turn on LED

Toggle LED2

Pause 200 'Wait 200ms

Low LED 'Turn off LED

GOTO Start

 

JumpC:

High LED 'Turn on LED

Toggle LED3

Pause 200 'Wait 200ms

Low LED 'Turn off LED

GOTO Start

 

'******** プログラムの終了 ********

'Note:

   'melabs U2 Programmer's configurations 12F683:

   'FOSC – INTOSCIO; WDTE - Enable; Power-up Timer - Disable

   'MCLRpin – Reset ; BODEN - Enable; Internal External Switvh Over – Enable, Fail-Safe Clock Monitor – Enable, CD - Disable;Dtata EPPROM - Disable.

 

Menu Pageへ戻る

Topへ戻る