5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (10) 人感センサ1 PaPIRs

コンパクトな人を検知する焦電型赤外線センサ

 人は赤外線を発生しています。自動ドアなどで、人を感知するのが焦電型赤外線センサです。センサ自体を駆動する回路は複雑ですが、回路を含めてモジュール化された製品が入手できます。人を検知できる範囲は、センサ自身の性能とレンズによって大きく異なります。

パナソニックPaPIRs 5m EKMC160111

 直径約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()