5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (10) 人感センサ1 PaPIRs
■コンパクトな人を検知する焦電型赤外線センサ
人は赤外線を発生しています。自動ドアなどで、人を感知するのが焦電型赤外線センサです。センサ自体を駆動する回路は複雑ですが、回路を含めてモジュール化された製品が入手できます。人を検知できる範囲は、センサ自身の性能とレンズによって大きく異なります。
●パナソニックPaPIRs 5m EKMC1601111
直径約11mm、全長14.4mmとコンパクトなセンサ・モジュールです。検知範囲は5mです。白色を秋月電子通商で入手しました。おもなスペックを示します。
- 動作電圧;3~6V
- 消費電流;170~300uA
- 出力電流;100uA
- 出力電圧;Vdd-0.5V
- 電源投入時回路が安定な出力をする待機時間;30秒
●接続
センサ・モジュールを裏から見た端子名です。出力は、LowがGNDレベル、HighがVddレベルです。正論理なので、人を感知したらHighになります。
センサ・モジュールの端子 | ラズパイのピン番号 |
---|---|
Vdd | 1番 3.3V |
OUT | 40番 GPIO21 |
GND | 39番 GND |
リード線をはんだ付けしました。データシートには3秒以内ではんだ付けを終わらすように書かれています。
LEDは抵抗内蔵タイプを使ったので、直列に抵抗は入れていません。
●プログラム例 ライブラリgpiozero
gpiozeroのライブラリにMotionSensorがあります。
2017年8月現在、RASPBIAN Stretch WITH DESKTOPのカーネルを確認します。8月16日にDebian version 9であるStretch に変更になりました。
uname -a
4.9.41
インストールされているPythonのバージョンを調べます。
python -V 2.7.13
インストールされているPython用ライブラリを調べます。
pip list gpiozero(1.4.0)
人を検知したら、LEDを光らせます。LEDは11番ピンのGPIO17につなぎます。焦電型赤外線センサの出力OUTをつないでいるGPIO21も、GPIOのどのピンを利用してもかまわないようです。
非同期でセンサの状態を検知しています。while文は、動作確認用です。センサの出力状態を確認したいとき、#を外してください。print文のインデントはtabを入れますが、表示の都合上スペースを8個入れてあります。このプログラムが動き始めるときには、OSが立ち上がるために30秒以上経過しているので、出力が安定する時間30秒を待ちません。
センサが人を検知したとき(=True=High)にLEDを消します。「人がいないとき、人が微動だにしないとき」にはLEDを点灯させます。この焦電型赤外線センサは、赤外線を発生している物体が動かないと、出力はLow(=False)です。
プログラムをshouden.pyという名前で保存し、sudo chmod 755 shouden.py と実行権を付け、python shouden.py で実行します。
#!/usr/bin/env python
from gpiozero import LED,MotionSensor
from signal import pause
led = LED(17)
button = MotionSensor(21)
button.when_motion = led.off
button.when_no_motion = led.on
#while 1:
# print (button)
pause()
記述を変えてみました。焦電型赤外線センサが人を検知したときにTrueを返すmotion_detectedを使います。人を検知するとLEDが光ります。gpiozeroのドキュメントはこちらです。
#!/usr/bin/env python
from gpiozero import LED,MotionSensor
led = LED(17)
button = MotionSensor(21)
while 1:
if button.motion_detected == True :
led.on()
led.off()
これであれば、gpiozeroのライブラリでなくとも実現できますね。
●プログラム例 ライブラリRPi.GPIO
RPi.GPIOのバージョンは0.6.3でした。
#!/usr/bin/env python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.OUT)
GPIO.setup(21,GPIO.IN)
try:
while 1:
if GPIO.input(21) == True :
GPIO.output(17,GPIO.HIGH)
GPIO.output(17,GPIO.LOW)
except KeyboardInterrupt:
GPIO.cleanup()