フィジカルコンピューティング with Raspberry PI Pico
9 防犯アラーム

赤外線センサー(人感センサー、PIRセンサー)を使って、防犯アラームを作成します。赤外線センサーで人の動きを監視し、動きがあればブザーを鳴らします。また動きがないとき(平時)は、PicoのオンボードLEDをゆっくりとしたリズムで点滅させます。

赤外線センサー

赤外線センサーにはパッシブとアクティブの2つのタイプがあります。パッシブは遠赤外線をキャッチするセンサーで、人間や動物などが出している赤外線をキャッチし電気信号に変えることができます。たとえば、トイレに入ったら自動的に照明が点いたり、水道の蛇口に手を伸ばしたら水が出てくるところでは、このタイプのセンサーが使われている場合が多いです。このプログラムではパッシブタイプを使用します。

センサーを手に取ってみると、おそらく金属の突起(ピン)が3本出ていると思います。。どのピンをPicoのどのピンに接続するかはキットの説明書やセンサーの説明書に書かれていると思われますが、もし書かれていない場合や単品を購入して不明な場合には、自分で調べる必要があります。

たとえばSR-602という赤外線センサーの場合には、基板上にプリントされていて、下図に示すように、ピンは左から(-)、(+)、(OUT)の順で並んでいると分かります。またHC-SR501の場合には、基盤には書かれていませんが、製品名をインターネットで検索すると、下図に示す資料写真が見つかるので、(-)、 (OUT)、(+)だと分かります。

また動作に何ボルトを必要とするかも調べておく必要があります。Picoで扱えるのは5Vまでです。たとえばSR-602は3.3Vで、HC-SR501は5Vで動作します。

赤外線センサーの値の読み取り

作成する防犯アラームは、始終赤外線センサーで周囲を監視し、センサーが動きを感知したらブザーを鳴らす、という仕組みにします。このためには、赤外線センサーの値の読み取り方法を知っておく必要があります。

配線

赤外線センサーを配線するときには、オス-メス タイプのジャンパー線を使用します。

5Vで動作する赤外線センサーの場合には、ジャンパー線のメスをセンサーの(+)ピンに接続し、オスをPicoの右上隅のVBUSピンに接続します。3.3Vで動作するセンサーでは、Picoの右上隅から5番めにある3V3(OUT)ピンに接続します。センサーの(-)に接続したジャンパー線はPicoのGNDピンのどれかに接続し、センサーの(out)はPicoのGP15に接続します。

Raspberry Pi Pico 赤外線センサー
VBUS か 3V3(out) +
GND
GP15 OUT

PicoのVBUSピンには、micro USBからの5Vが給電されます。Pico自体(チップ)にはその後、3.3Vに変換されて給電されます。

プログラムコード
from machine import Pin
import utime

sensor = Pin(15,Pin.IN,Pin.PULL_DOWN)

while True:
    utime.sleep(0.1)
    print(sensor.value())

ここでは、センサーの値を読み取る前に、ジッターと呼ばれる時間的なノイズを滑らかにするために、utime.sleep(0.1)で一瞬の間を取っています。プログラムを実行し、Thonnyの[シェル]を見ると、0が出力され、センサーに手をかざすと1になるのが確認できます。

防犯アラームの作成

前述したように、このプログラムでは、赤外線センサーが反応したらブザーを鳴らすようにします。ブザーにもパッシブとアクティブの2つのタイプがあり、ここでは電気を通すだけで鳴るアクティブブザーを使うことにします。

ブザーの配線

アクティブブザーの作りは単純で、+の赤線とマイナスの黒線だけが出ています。線の先に突起がついていない場合には、ジャンパー線を切ってブザーの線と接続し、ブレッドボードに挿せるようにします。

ブザーの線とジャンパー線を接続するときには、熱収縮チューブと呼ばれるゴムチューブが役に立ちます。適当な長さに切って線に通し、接続部に合わせて、その部分にヘアードライヤーなどで熱を与えると縮むので、接合部の保護やショートの防止になります。

配線

ブザーは(+)をPicoのGP14ピンに、(-)をPicoのGNDピンのどれかに接続します。

Raspberry Pi Pico 赤外線センサー
VBUS か 3V3(out) +
GND
GP15 OUT
Raspberry Pi Pico アクティブブザー
GP14 VCC(+)
GND GND(-)
プログラムコード

このプログラムでは、赤外線センサーを使って人の動きを始終監視し、何もない平時にはPicoのオンボードLEDを点滅させ、人の動きを感知した緊急時にブザーを鳴らすようにします。人間の動きはいつ感知されるか分からないので、While Trueの無限ループで、センサーの値をずっと監視します。

from machine import Pin
import utime

# 赤外線センサー
sensor = Pin(15, Pin.IN, Pin.PULL_DOWN)
# オンボードLED
onboard_led = Pin(25, Pin.OUT)
# ブザー
buzzer = Pin(14, Pin.OUT)

# オフでスタート
onboard_led.off()
buzzer.off()

# 非常時ブザーを鳴らす
def alarm_buzzer():
    onboard_led.off()
    buzzer.off()
    # 50回、高速で点滅
    for i in range(50):
        buzzer.toggle()
        onboard_led.toggle()
        utime.sleep(0.1)
    utime.sleep(0.5)

# 平時のオンボードLED点滅
def onboard_blink():
    buzzer.off()
    onboard_led.toggle()
    utime.sleep(0.5)

while True:
    utime.sleep(0.1)
    if sensor.value()==1:
        print("非常事態発生!!")
        alarm_buzzer()

    print("平時")
    onboard_blink()

MicroPythonでも、Pythonと同じ要領で関数が定義できます。ここでは、非常時用のalarm_buzzer()関数と平時用のonboard_blink()関数を定義して、while Trueの無限ループで赤外線センサーの値を監視し、値が1のときにalarm_buzzer()を、そうでないときにonboard_blink()を呼び出しています。

LEDやブザーのtoggle()は、オンとオフを交互に切り替えるメソッドです。オンならオフに、オフならオンに切り替えることで、点滅や断続音が作り出せます。具体的に言うと、whileループのある呼び出しのときLEDを点灯させたonboard_led.toggle()は、次の呼び出しのときLEDを消します。これが繰り返されるので、点滅になります。

プログラムを実行すると、平時のオンボードLEDが点滅します。防犯装置の平時の点滅は「この辺りは監視されているぞ」ということを侵入者に示す効果があります。センサーに手をかざすとブザーが鳴り、しばらくすると止みます。もう一度手をかざすとブザーが鳴り、しばらくすると止みます。結果だけを見ると、動作に問題がないように思えますが、このプログラムは実はもう少し良くなります。

while Trueでは、繰り返しのたびに次の行でセンサーの値を調べていますが、これはPicoの負担で、もし誰かが代わってくれたらPicoは楽になります。

if sensor.value()==1:

その代わりの方法に割り込みがあります。

割り込み

割り込みを使用すると、while Trueで平時の動作を実行中、赤外線センサーが動きを感知したタイミングで割り込み、つまり“横入り”をして、while Trueのメインループを一時的に停めて、緊急時の動作を実行することが可能になります。

割り込みの設定は少しややこしく、割り込みを設定するには、赤外線センサーのirq()メソッドで、トリガーとハンドラと呼ばれるものを設定します。トリガーとは“引き起こすもの”という意味で、ここでは割り込みを引き起こすものを言います。ハンドラは“処理するもの”という意味で、ここではトリガーによって割り込みが引き起こされたときに呼び出される関数名を指します。

sensor.irq(trigger=Pin.IRQ_RISING, handler=alarm_buzzer)

トリガー(trigger)に指定しているPin.IRQ_RISINGは、ピンの値がロー(0)からハイ(1)に変化するときの「立ち上がり」の部分を言います。

専門用語が多く混乱されるでしょうが、ざっくり言うと、sensor.irq(trigger=Pin.IRQ_RISING, handler=alarm_buzzer)によって、センサーの値の監視が開始され、値がトリガーのIRQ_RISINGの状態に達したとき、つまりローからハイに上がり始めたとき、ハンドラのalarm_buzzer()関数が自動的に呼び出される、という仕組みです。

ハンドラのalarm_buzzer()関数では、パラメータ変数にpinを定義する必要があります。この変数はirq()メソッドで割り込みを設定したピンを指しています。

# ハンドラ関数
def alarm_buzzer(pin):

IRQはInterrupt ReQuestの略で、割り込み要求という意味です。

プログラムコード

割り込みを使ったプログラムは次のように記述できます。

from machine import Pin
import utime

sensor = Pin(15, Pin.IN, Pin.PULL_DOWN)
onboard_led = Pin(25, Pin.OUT)
buzzer = Pin(14, Pin.OUT)

# ハンドラ関数
def alarm_buzzer(pin):
    if pin.value() == 1:
        print("非常事態発生!!")
        onboard_led.off()
        buzzer.off()
        # 50回、高速で点滅
        for i in range(50):
            print("IRQ")
            buzzer.toggle()
            onboard_led.toggle()
            utime.sleep(0.1)
    utime.sleep(0.5)

# 平時のオンボードLED点滅
def onboard_blink():
    buzzer.off()
    onboard_led.toggle()
    utime.sleep(0.5)

# PIRセンサーの割り込み設定。
# 侵入者を感知したら、ハンドラ関数を呼び出す
sensor.irq(trigger=machine.Pin.IRQ_RISING, handler=alarm_buzzer)

# メインループでは、平時の動作を実行するだけ
while True:
    print("Main")
    onboard_blink()
    utime.sleep(0.1)

割り込みを使用することで、whileループではセンサーの値を調べる必要がなくなり、Picoの負担が軽減されます。なお、sensor.irq()の行は、while True より先に記述する必要があります。プログラムはwhile Trueで無限ループに入るので、while Trueより後に書くと、プログラムの実行中、sensor.irq()は実行されない行になるからです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


2023年7月
 12
3456789
10111213141516
17181920212223
24252627282930
31