電子工作35 - 集電型人体検知赤外線センサNaPiOnを使った電池式LEDセンサライトの製作
概要
もともとこの実験を始めようと思ったきっかけはパソコンの前からオペレータが一定時間離れたらモニタの電源を自動的に切ることが出来ないかということだった。つまり人体の動きを検知し、一定時間後にソレノイドなどを使ってモニタの電源ポタンを押して切るようなことを想定した。手初に人体検出赤外線センサとはどんなものか調べ、そして、そのセンサを使って電池式LEDセンサライトの製作を試みた。
センサ
いろいろ検討した結果、パナソニック電工の集電型人体検出赤外線モーションセンサ
NaPiOn AMN31111(標準検出タイプ)というものを使うことにした。なかなか入手困難でやっと秋葉原のマルカ電機工業の東京ラジオデパート1F店
にて購入できた。
このセンサの特徴は;
1)アンプが内蔵されているモジュールタイプである。
2)出力がH、Lである。つまり、Vdd(電源電圧)と0VでPICでは扱いやすい。
3)電源は3.0
- 6.0 V、消費電流は170mAと電池駆動も可能。
4)最大検出距離は5mで、検出の水平と垂直角度は広く80ー100度である。
5)人体の動きに反応し、人体の移動スピード範囲は0.8 – 1.2 m/secである。
まずこのセンサの動作を見るために次のような回路を組んだ。最初に電源を入れ安定し機能するまで7秒から1分程の時間がかかる。センサの前で手や体を動かすと出力H(Vdd)を示すLEDが点灯する。原則、人体の動きに反応し、動きを止めると人体の一部がセンサのすぐ前にあっても出力はL(0V)になりLEDは消灯する。これで大体の特性が理解出来た。
オシロで見たセンサからの出力
電源電圧(Vdd)が3.94Vの時(電池利用を想定した電圧)、センサが人体の動きを検知すると、ほぼVddと同じレベルの出力を出す。HとLがはっきりしていてPICで扱い易いことが分かる。
回路
このセンサを使って電池で動作するセンサライトを製作してみることにした。備えなければならない条件は;
1)人が近付くと自動的にLEDランプが点灯する。そこに居続け動いている間、途中瞬間的な消灯を伴うが点灯し続ける。
2)人が居なくなると自動的に消灯し、その後の消費電流はわずかであること。
その回路図を下に示す。12F629 (PIC)を使った。人体の動きを検知した時のセンサの出力はまず12F629のGP1(ピン6)に入る。さらにトランジスタを介してセンサの出力を示す赤色LEDにつながれている。センサからHレベルのパルスが出るとそのつど点灯する。外してもよい。またセンサ出力は33Kの抵抗を通してGNDにつなげてある。これが無いとシステムがうまく動作しない。12F629に読み込まれた信号は内部のプログラムで処理され、GP4(ピン3)より直接ランプとしての高輝度LED2個を点灯させる。一応リセットボタンも付けてある。電池は単4を3本使い(4.5V)足元を照らすのに十分な明るさが得られる様にした。
この回路で全く動作していない時(待機時/Sleep時)の消費電流は170mAで、そのほぼすべてがセンサの駆動に使われる(PICの消費電流は1mA程)。人体の動きを感知してLEDランプが点灯するとき抵抗100オームを通じて8-10mAの電流が流れる。照度を上げるには、LEDを破壊しない程度にこの抵抗値を小さくすればよい。ただし、1本のGPIOポートから取り出せる最大電流は25mAであるので要注意。また、2本のGPIOポートを使ったりLEDの数を増やすことによっても照度は上げられる。
試作ボード上の下側に黒く丸いセンサや点灯中の赤いLEDが見える。12F629の上部には白く点灯している2個のLEDが見える。電源は単4電池3本である。
プログラム
人体が近くにない時、すなわち待機時システムはできるだけ電流を消費しないように、電池でも長期間駆動できるようにプログラムを作成する必要がある。そのため割込み機能を使った。常時動作しているセンサは人体の動きを検知するとパルスを発生する。それを取り込んで割込みを発生させ、PICを目覚めさせプログラムでLEDランプを一定時間点灯させる。次のパルス発生がなく割込みがない場合、つまり、人体の動きがない場合PICは@Sleepモードに入り、センサの駆動電流だけが必要な低消費電流モードの待機状態に入る。以下が作成したプログラムである。電子工作30のプログラムAlmS629.bas をもとにしている。
'********************** プログラミング備忘録 ******************************
'Lamp629A.bas 2000.6.22 センサライト動作プログラム PICBasic Pro compiler used
'This demo program functions as follows: when Sensor is activated,
'an interrupt occurs, executing the LEDs light-up routine (GPIO.4)
'and then enters into the sleep mode where current consumption is about 170 mA,
'most of which is consumed by Sensor (about 1 mA by PIC)
'Main themes here are how to use the interrupt and the low-power consuming
'sleep mode (@sleep), where battery operation becomes possible. Succeeded!!
'******** Pin connection ******************
'Pin 1: Vdd (4.5V) - battery operated
'Pin 8: Vss (GND)
'Pin 6: GPIO.1: input - connected to Motion Sensor and LED (red)
'Pin 3: GPIO.4: output - connected to two illuminating LEDs via R=100 ohm
'Pin 4: GPIO.3: input - connected to Vdd via R=10K and Reset SW
'********** ここからがプログラム本体 ***************
LED VAR GPIO.4 'LEDs on GPIO.4
CMCON=7 'Disable Comparators, GP0 & GP1 -> digital
TRISIO=%001010 'GPIO.1 (Interrupt) & GPIO.3 (Reset) - inputs
WPU=%000000 'No weak pull-up of any GPIO port
OPTION_REG.7=1 'No weak pull-up
IOC.1=1 'Detect input at GP1 - Essential !! このピンで入力データの変化検出許可
INTCON.7=1 'Enable the use of interrupt 割込み使用する
INTCON.3=1 'Enable the port input-level change interrupt GPIOポート入力レベル変化割込みを使う
LightupLoop:
LED=0
INTCON.0=0 'Clear GPIF GPIOポート入力レベル変化した時1になるので0に戻してやる
@Sleep 'Have good sleep! - This is a key command アッセンブラコマンド Sleep を使う(超小電流消費モード)
INTCON.0=0 'Clear GPIF GPIOポート入力レベル変化した時1になるので0に戻してやる
'*** LEDs lightup routine ****
High LED ‘LEDs を約20 秒間点灯する
Pause 22200 ‘This gives approx. 20 sec.
Low LED ‘LEDs を消灯する
Goto LightupLoop
'********** ここまでがプログラム ***************
'Note:
'AKI Programmer's configurations:
'FOSC - INTOSC(GP4:I/O); WDTE - Disable; PWRTE - Enable
'MCLR - MCLRpin ; BODEN - Diable; CP - Disable; CDP - Disable.
'2009.6.21
結論·余談
1) 最大で5メートル位離れたところから手を振ったり、体を動かすと瞬時にLEDランプが点灯する。反応は速い。
2) 待機時の消費電流は170mAなので、単4アルカリ電池3本で半年以上もつ計算になる(待機時のみとして単4電池900 mAH/0.17 mA=5294 hours
–> 220 days) 。
また、LEDランプ点灯時でも10mA以下の電流しか流れない。
3) このセンサは¥1030と比較的高価であったが使い方が簡単で良く出来たセンサと思う。いろんな目的に使えそう。
4) 他にも1個100円のモジュール化されてないAKE−1(RE-210)というセンサも試してみたがジジイには難し過ぎた。
上記を改良した回路とプログラム(2009.6.26)
回路の改良点は;
1) LEDランプの点灯時間をスイッチで短・長時間の2段階(20、または40秒間)に切り換えられるようにした。 それでも待機時消費電流は170mAと変わらない。
2) 明るさを増すためにLEDの数を2本から3本に増やした。R=47で約15mAの電流が流れる。
3) Reset SWは除いた。ただし、GP3 (Pin4)をR=10Kを介してVddに接続しておく必要あり。
プログラム
GP5(Pin2)より点灯時間の短・長時間選択を切り換えSWから読込むので、その部分が新たに加わった。例えば、 IFLupTimeSW=0 Then ShortTimeなどである。新たに加わった部分は<####>で示した。
'****************** プログラミング備忘録 *******************
'Lamp629B.bas 2000.6.25
'******** Pin connection ******************
'Pin 1: Vdd (3.0V) - battery operated
'Pin 8: Vss (GND)
'Pin 6: GPIO.1: input - connected to Motion Sensor and LED (red)
'Pin 3: GPIO.4: output - connected to 3 illuminating LEDs via R=X ohm
'Pin 2: GPIO 5: input - connected to SW which leads to Vdd or GND via R=100K <####>
'Pin 4: GPIO.3: input - connected to Vdd via R=10K
'********** ここからがプログラム本体 ***************
LED VAR GPIO.4 'LEDs on GPIO.4
LupTimeSW var GPIO.5 'Read H(Vdd Long time) or L(0V Short time) <####>
CMCON=7 'Disable Comparators, GP0 & GP1 -> digital
TRISIO=%101010 'GPIO.1 (Interrupt) & LupTimeSW read – inputs <####>
WPU=%000000 'No weak pull-up of any GPIO port
OPTION_REG.7=1 'No weak pull-up
IOC.1=1 'Detect input at GP1 - Essentiall !!
INTCON.7=1 'Enable the use of interrupt
INTCON.3=1 'Enable the port input-level change interrupt
LightupLoop:
LED=0
INTCON.0=0 'Clear GPIF
@Sleep 'Have good sleep! - This is a key command
INTCON.0=0 'Clear GPIF
'***** LEDs lightup routine *****
If LupTimeSW=0 Then ShortTime ‘短い点灯時間か? <####>
If LupTimeSW=1 Then LongTime ‘長い点灯時間か? <####>
ShortTime: <####>
High LED
Pause 22200 '約20 sec
Low LED
Goto LightupLoop
LongTime <####>
High LED
Pause 44400 '約40 sec
Low LED
Goto LightupLoop
'********** ここまでがプログラム ***************
'Note:
'AKI Programmer's configurations:
'FOSC - INTOSC(GP4:I/O); WDTE - Disable; PWRTE - Enable
'MCLR - MCLRpin ; BODEN - Diable; CP - Disable; CDP - Disable.
'2009.6.21
人体検知を遅延させる機能を追加した (2009.6.29)
上記の回路とプログラム(2009.6.26)を以下のように若干変更した。
人体の動きを検知しすぐLEDランプが点灯するこれまでの機能に加え、ある一定時間センサの前で動かないとLEDランプが点灯しないようにする機能を追加した。これはセンサの前を瞬時に過ぎ去るような人体の動きには反応しないようにするためである。
回路(追加した検知遅延選択回路)の改良点は;
1) 新たにSWを設け、切り替えでVdd またはGNDに100K経由で接続できるようにした。他端は12F629のGP0(Pin7)につないだ。
2) X-sec waitを選択すると、人体の動きを一定時間検知し設定の値に合致するとLEDランプが点灯する。 Instantlyは従来モードで人体の動きを検知するとすぐ点灯する。
3) この回路の追加で待機時の消費電流が170mAから220mAへと若干増加した。
プログラム
GP0(Pin7)より読込んだH,L信号でLならInstantlyで従来通り人体の動きを検知してすぐLEDランプ点灯する。一方、HであるX−sec
waitでは、GP1より0.5秒間毎に10回取り込んだセンサ信号が7回以上(7回も含め)“H”であったらLEDランプを点灯させるというように設定した。人体の動きに対する感度はこの部分で調整できる。
'****************** プログラミング備忘録
*******************
'Lamp629C.bas 2000.6.28
'******** Pin connection ******************
'Pin 1: Vdd (3.0V) - battery operated
'Pin 8: Vss (GND)
'Pin 6: GPIO.1: input - connected to Motion
Sensor and LED (red)
'Pin 3: GPIO.4: output - connected to 3
illuminating LEDs via R=X ohm
'Pin 2: GPIO 5: input - connected to SW
which leads to Vdd or GND via R=100K
Lightup Time
'Pin 4: GPIO.3: input - connected to Vdd
via R=10K
'Pin 7: GPIO.0: input - connected to SW
which leads to Vdd or GND via R=100K
Wait Time
'********** ここからがプログラム本体 ***************
LED VAR GPIO.4
'LEDs on GPIO.4
LupTimeSW var GPIO.5 'Read
H(Vdd Long time) or L(0V Short time)
WaitTimeSW var GPIO.0 'Read H(Vdd X-sec wait) or L(0V
Instantly)
SensIn var GPIO.1 'Input from Sensor センサからの読込み
AddH var Byte ‘AddH Hレベルのカウンタ
CMCON=7
'Disable Comparators, GP0 & GP1 -> digital
TRISIO=%101011 'GPIO.1 (Interrupt), LupTimeSW &
WaitTimeSW read - inputs
WPU=%000000 'No weak pull-up
of any GPIO port
OPTION_REG.7=1 'No weak pull-up
IOC.1=1 'Detect
input at GP1 - Essentiall !!
INTCON.7=1 'Enable the use of interrupt
INTCON.3=1 'Enable the port input-level change
interrupt
LightupLoop:
LED=0
INTCON.0=0 'Clear GPIF
@Sleep 'Have good sleep! - This is a key command
INTCON.0=0 'Clear GPIF
'*** Demo routine *** ‘Insert your routine below
If WaitTimeSW=0 Then Lightup ‘WaitTimeSWがGNDならLightupへ飛べ
If WaitTimeSW=1 Then Xsecwait ‘WaitTimeSWがVddならXsecwait
へ飛べ
Xsecwait:
AddH=0 'AddH
= No. of 'H' pulse detected in reading SensIn センサから読込んだHの数、まず0とする
If SensIn=1 Then 'Read SensIn 1個目の H or Lをチェックする。もし読込んだセンサ値がHなら AddH=AddH+1でH=1を加算する
AddH=AddH+1
Endif
Pause 500 '0.5 sec 0.5秒待つ
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If SensIn=1 Then ‘10個目の H or Lをチェックする
AddH=AddH+1
Endif
Pause 500 '0.5 sec
If AddH >= 7 Then '7 times out of 10
times もし、合計AddH値が7より大きいか、等しければLightupへ飛んでLEDランプを点灯させる。そうでなければLightupLoopへ戻る
Goto Lightup
Endif
Goto LightupLoop
Lightup:
If LupTimeSW=0 Then ShortTime
If LupTimeSW=1 Then LongTime
ShortTime:
High LED
Pause 11100 '約10 sec
Low LED
Goto LightupLoop
LongTime:
High LED
Pause 44400 '約40 sec
Low LED
Goto LightupLoop
'********** ここまでがプログラム ***************
'Note:
'AKI Programmer's configurations:
'FOSC - INTOSC(GP4:I/O); WDTE - Disable; PWRTE -
Enable
'MCLR - MCLRpin ; BODEN - Diable; CP - Disable; CDP -
Disable.
'2009.6.21
余談
1) いつものようにプログラムは最初動作しなかった。2日かかってSensIn var GPIO.1 のGPIO.1をGPIO.0としていたことに気づいた。ロジックは最初からOK!
2) このセンサを使い、今回製作した回路やプログラムで実用的なセンサライトやその応用機器が作れそうだ。 完