あいさつ
磁力を利用するタイプの開閉スイッチを使って、様々な扉の閉め忘れに対応できる警報システムを作ってみました。
作品名に「汎用型」と記したのは、使用している開閉スイッチが小型かつ磁力の有無で感知しているので、扉間の距離や扉の形状に関わらずケージや窓などの扉にも幅広く対応可能だと思ったからです。
制作目的
私は、RaspberryPiで解決したい課題を考えるに当たって、目を離した隙に赤ちゃんやペットがどこかに行ってしまうトラブルを防止しようと思いました。
そうした脱走が知らない間に起きてしまうのは、扉の閉め忘れや鍵の故障が発生した状態で目を離して扉を開けられてしまうことが原因だと考え、扉そのものを監視することで不意の開閉にいち早く気付けるようにしたいと思い、このシステムを製作しました。
使用部品
・Raspberry Pi 4
・市販の磁気開閉スイッチ
・3色のLED(赤・黄・緑)
・ブザー
・GPIOピン
システムの概要
本システムは、磁力センサが感知する磁力の有無で動作する開閉スイッチからの信号をラズベリーパイで読み取り、そのままプログラム内の条件式に当てはめて用意した動作を行うというシンプルな物です。
扉が「閉じている状態」と「開いている状態」の動作をそれぞれ用意して、開閉スイッチの信号の変化に素早く反応して状態の切り替えが出来るシステムを目指しました。
扉が閉じている状態の動作
開閉センサーから「扉が閉じている」という信号を受け取ると、扉が締められたことを示す音楽がブザーから奏でられると共に緑色のLEDだけが点灯して、視覚・聴覚の両方で扉の状態を通知します。その後、スイッチの信号が変化するまで静かにLEDが点灯し続けます。
これが、本システムの平常時の状態となります。
扉が開いている状態の動作
開閉スイッチからの信号が、「扉が開いている」状態になると、赤いLEDだけが点灯し「扉が閉じている」状態とは別の音を発して、扉が開いたことを通知する状態になります。警報は、信号を受け取った10秒後・20秒後にも流れ、3回に渡って「扉が開いている」ことを通知します。
閉め忘れ状態
それでも扉が閉じられない場合は、「閉め忘れ状態」として「扉が閉じている」状態に移行するまで、オリジナルの警報音をループさせて使用者が気付くまでオリジナルの警報音を発し続けます。
停止状態の動作
プログラムに割り込んで終了させる機能です。
開閉時に、動作するものではありません。
実際の動作
扉が開いている状態
開閉センサ同士が近い状態だと緑色のLEDだけが点灯して、収録できませんでしたがブザーから3拍子の音が出力されます。
扉が開いている状態
開閉センサ同士が遠い状態だと赤色のLEDだけが点灯して、ブザーから2拍子の音が出力されますが、こちらも収録できませんでした。
約30経過すると流れる「閉め忘れ状態」時のオリジナルの警報音も収録出来ませんでしたが、アドベンチャーゲームのようなBGMを設定していました。
停止状態
Ctrl+cを押して停止機能が動作すると黄色いLEDだけが数秒点灯する状態となり、黄色いLEDの消灯後にプログラムが停止します。
今回の作品は、LEDの光とブザーの音で扉の開閉を使用者に通知するという物でしたがelchikaの投稿機能を確認していない状態で開発を進めたので、ブザーの音を収録出来ませんでした。
プログラムコード
設定部のプログラム
import RPi.GPIO as GPIO
from time import sleep
import sys
# 出力ピン番号をBCMで指定する
pwmpin = 23 # ブザー
LED1 = 17 # 赤のLED
LED2 = 27 # 黄のLED
LED3 = 22 # 緑のLED
# 出力する音階の周波数指定
A3 = 220
B3 = 246
C3 = 261
D3 = 293
E3 = 329
F3 = 349
G3 = 392
A4 = 440
B4 = 493
C4 = 523
Q = 0.001
soundpitch = (60.0 / 80.0) - 0.1
bercount = 4
offtime = 0.1 / bercount
soundoff = 0.1 # 音の切れ目の時間指定
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(pwmpin,GPIO.OUT)
GPIO.setup(LED1,GPIO.OUT)
GPIO.setup(LED2,GPIO.OUT)
GPIO.setup(LED3,GPIO.OUT)
pin23 = GPIO.PWM(pwmpin,10)
GPIO.setup(18,GPIO.IN,pull_up_down=GPIO.PUD_UP) #GPIO18番ピンに設定
sw_status = 1 #SWITCH OPTION
def LEDcheck(LED1,LED2,LED3):
print("LED TEST")
GPIO.output(LED1,True)
GPIO.output(LED2,True)
GPIO.output(LED3,True)
sleep(1)
GPIO.output(LED1,False)
GPIO.output(LED2,False)
GPIO.output(LED3,False)
条件式のプログラム
# START
print("Start KONTEST.py")
print("(Ctrl-C to EXIT)")
print()
try: #プログラムスタート
# LEDのテスト
LEDcheck(LED1,LED2,LED3)
# ブザーのテスト
print("Buzzer TEST")
GPIO.output(pwmpin,GPIO.HIGH)
count = 0 #カウント用変数を宣言
close_door = 0 #閉じられた直後を判定する関数を宣言
while True: #処理を繰り返すための無限ループ
sw_status = GPIO.input(18) #SWITCH STATUS #GPIO18ピンを設定
if sw_status == 1: #閉じている状態
print("CLOSE")
#print(sw_status)
count = 0 #閉じられたらカウントを初期化
close_door += 1
pin23.start(0) #duty比
GPIO.output(LED1,False) #緑色のLEDだけが点灯し続ける
GPIO.output(LED2,False)
GPIO.output(LED3,True)
if (close_door == 100): #閉じたことをブザーで通知 #2拍子の音を出力
pin23.start(50)
pin23.ChangeFrequency(E3)
sleep(0.3)
pin23.ChangeFrequency(F3)
sleep(0.3)
pin23.ChangeFrequency(G3)
sleep(0.3)
pin23.start(0)
else: #締め忘れ状態
print("OPEN")
#print(sw_status)
close_door = 0 #開けられたらカウントを初期化
count += 1
GPIO.output(LED1,True) #赤いLEDだけが点灯し続ける
GPIO.output(LED2,False)
GPIO.output(LED3,False)
if (count == 100) or (count == 5250) or (count == 10250): #開いた直後・約10秒後・約20秒後にアラーム #3拍子の音を出力
pin23.start(50)
pin23.ChangeFrequency(D3)
sleep(0.2)
pin23.ChangeFrequency(E3)
sleep(0.3)
pin23.start(0)
if count >= 15500: #締め忘れ状態 #扉が開いてから約30秒経過で警報
pin23.start(50) #duty比
# 第1小節 #オリジナル警報音の出力
pin23.ChangeFrequency(G3)
sleep(0.5)
pin23.ChangeFrequency(C3)
sleep(0.3)
pin23.ChangeFrequency(E3)
sleep(0.4)
pin23.ChangeFrequency(B4)
sleep(0.3)
# 第2小節
pin23.ChangeFrequency(B4)
sleep(0.2)
pin23.ChangeFrequency(G3)
sleep(0.2)
pin23.ChangeFrequency(C3)
sleep(0.2)
pin23.ChangeFrequency(F3)
sleep(0.2)
pin23.ChangeFrequency(B4)
sleep(0.4)
pin23.ChangeFrequency(E3)
sleep(soundpitch)
GPIO.output(pwmpin,GPIO.LOW)
# LEDのテスト
sleep(0.3)
#LEDcheck(LED1,LED2,LED3) #全点灯はなし
#分岐に戻る
except KeyboardInterrupt: #Ctrl+cで停止処理
print("\nEND")
pin23.start(0) #duty比
GPIO.output(LED1,False)
GPIO.output(LED2,True)
GPIO.output(LED3,False)
sleep(1.5) #黄色いLEDが1.5秒間点灯
GPIO.cleanup() # クリーンアップして終了
まとめ
コンピューターの行う動作が分かっていても、その動作を成り立たせているプログラムを見ると、どうしても難解に感じてしまいます。
それでも、今回のコンテストに向けて作品を改善していく中で、各プログラムの表している動作が見えてくるようになり、どのように変更すれば目的の動作が行えるか理解しながら作成することが出来ました。
シンプルな仕組みでブザー音の作成などを遊び心を持って取り組めたのでいい体験が出来たと思います。
-
kaburi
さんが
2024/09/30
に
編集
をしました。
(メッセージ: 初版)
-
kaburi
さんが
2024/10/24
に
編集
をしました。
-
kaburi
さんが
2024/10/24
に
編集
をしました。
-
kaburi
さんが
2024/10/28
に
編集
をしました。
-
kaburi
さんが
2024/10/29
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/30
に
編集
をしました。
-
kaburi
さんが
2024/10/31
に
編集
をしました。
ログインしてコメントを投稿する