※2019年公開の試作品の記事を修正したものです
やること
Raspberry Piと開閉センサーを組み合わせて「冷蔵庫を開けていた時間をサーバーに送る」IoTデバイスを作製した備忘録です。ラズパイのOSインストール、USBケーブルによるSSH接続、無線LAN設定、メインプログラム、プログラムの自動実行設定が含まれます。家の冷蔵庫をIoT化してデータを集めてみましょう。
なおラズパイのWi-Fiは2.4GHzのみ対応で、5GHzは非対応なのでご注意ください。データをサーバに送信するためのAPIは別途用意する必要があります。(ここでは無効にしてあります)
参考にさせていただいたサイト
ラズパイで100均のドア開閉センサー検知
Raspberry PiのGPIO概要
材料
- Raspberry Pi Zero WH(無線LANがあるから)
- microSDカード
- USBケーブル
- ACアダプタ
- ドアセンサースイッチ(リードスイッチ)
- ラズパイケース
- ヒートシンク(お好みで)
秋月電子のリードスイッチ(250円)を買いましたが、参考サイトによれば100円ショップの商品を分解しても手に入るようです。
手順1
OSインストール
Raspberry Pi ImagerでmicroSDカードにOSを焼きます。デスクトップを使用しないのであれば「Raspberry Pi OS Lite (Legacy)」が軽くて良いかと。このときにオプションで無線LAN設定をしておくと後の同設定が不要になります。
有線SSH設定のON
microSDカードを再度PCに接続して次の3つを行います。
①boot直下にsshフォルダを作成。
②「mdline.txt」のrootwaitの後に半角スペース開きで以下を追記。
modules-load=dwc2,g_ether
③「config.txt」の最下行に以下を追記。
dtoverlay=dwc2
Windows用Ethernetドライバのインストール
PCがWindowsであれば、有線SSH接続に必要なドライバをインストールします。以下から「Acer Incorporated. – Other hardware – USB Ethernet/RNDIS Gadget」をダウンロードし、「RNDIS.inf」を右クリックからインストールします。
有線SSH接続
ラズパイをUSBケーブルでPCに接続し起動を待ちます。ラズパイを認識しているか、pingで確認します。
ping raspberrypi.local
sshでラズパイに入ります。※デフォルトパスワード「raspberry」
ssh pi@raspberrypi.local
このとき、「過去の接続設定が残っています」的なWarningが表示されて失敗したら、以下でそれを削除してから再度sshします。
ssh-keygen -R raspberrypi.local
手順2
無線LAN設定(必要に応じて)
OS焼き込み時にやっていなければここで無線LAN設定を行います。2.4GHz帯のSSIDとパスワードを記入します。
nano /etc/wpa_supplicant/wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
ap_scan=1
update_config=1
network={
scan_ssid=1
ssid="sample-ssid-2GHz"
psk="sample-password"
}
このとき、ファイルの書き込み権限がなければ以下で権限を変更してから行います。今後も同様です。
sudo chmod 777 /etc/wpa_supplicant/wpa_supplicant.conf
Wi-Fi接続のため再起動し、またsshで入っておきます。
sudo reboot now
Wi-Fi接続確認
ラズパイ内からpingしてWi-Fiに繋がっていることを確認します。
ping google.com
手順3
メインプログラム
メインプログラムを作成します。開閉センサーはGPIO 21とGNDに差す想定です。
0.1秒間隔でリードスイッチの状態を取得し、
- 継続して閉じている
- 継続して開いている
- 閉じていたけど開いた → タイム測定開始
- 開いていたけど閉じた → タイム測定終了、サーバに送信、タイム表示
の4条件で分岐します。サーバに送る部分は各自で変わるので空欄にしてあります。
nano main.py
import os
import requests
import RPi.GPIO as GPIO
from time import sleep, time
#GPIO 21pinを入力モードとし、pull up設定とする
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#初期化
new_state = GPIO.input(21)
old_state = new_state
start_time = time()
while True:
try:
#現在の状態を取得(0:Close, 1:Open)
new_state = GPIO.input(21)
if old_state == 0 and new_state == 0:
print('Close')
if old_state == 1 and new_state == 1:
print('Open')
if old_state == 0 and new_state == 1:
start_time = time()
print('Close -> Open')
if old_state == 1 and new_state == 0:
end_time = time()
open_time = end_time - start_time
#サーバに送信
try:
pass #ここでrequests.post()等でサーバに送る
except:
pass
print('Open -> Close {}s'.format(open_time))
old_state = new_state
sleep(0.1)
except:
print('Err')
break
GPIO.cleanup()
print('End')
リードスイッチの接続
GPIOピンの一番端、GPIO 21とGNDに繋ぎます。リードスイッチには極性がないので向きはどちらでも大丈夫です。
メインプログラムの動作確認
Pythonプログラムを実行します。センサーを開けて閉じると「開けた時間」が表示されます(サーバにも飛んでいきます)。飽きたらCtrl+Cで中止します。
python3 main.py
Close
Close
Close
Close -> Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open -> Close 2.0s
Close
Close
Close
Close
手順4
自動実行設定
「rc.local」というファイルの「exit 0」の前に「python3 /home/pi/main.py &」を追記します。
nano /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
python3 /home/pi/main.py &
exit 0
冷蔵庫に設置
PCとの接続を解除し、ACアダプタから給電する形で冷蔵庫にテープ留めました。磁石は約1cm以内で閉じた判定になるので十分に近づけます。サーバに記録が飛んでくれば成功です。
おわりに
「時刻」の記録はラズパイ側、サーバ側どちらで行っても良いと思います。電気代は20~100円/月くらいだと思います。