はじめに
Raspberry Pi Advent Calendar 2020の20日目です.
趣味で作ったペットの排泄検知システムについて書いていきます.
私は,フトアゴヒゲトカゲというオーストラリア原産のトカゲを飼っています.(飼育日記)
うんちをすることはそれほど多くなく,月に2〜3回程度です.
ただ,外出中などにうんちをされると,片付けるまでに時間がかかってしまうので,うんちをしたらわかるようなシステムを作ってみようと思いました.
実装した機能
目標は,うんちをしたらセンサで検知して,スマホに通知が来ることです.また,センサの出力値はあとで眺めたいので,何処かに保存しておきたいなと思いました,
そのために,ラズパイ上に以下の機能を実装しました.
- においセンサ
- LINEBotによるスマホ通知機能
- GoogleAppsScriptを作成し,センサー出力値をGoogleスプレッドシートに送信
においセンサ
回路基盤
まずは,ラズパイににおいセンサ用の回路基盤を実装しました.実装する回路基盤は,こちらの記事を参考にしました.
使用したものもほとんど同じで,増えたのはラズパイ用ユニバーサル基盤とLEDくらいです.
全部,秋月電子通称で買い揃えました.
- 臭気センサ TGS2450 1個
- ADコンバータ MCP3002-I/P 1個
- トランジスタ 8050SL-D-T92-K (20V700mA) 2個
- 抵抗 270Ω 1kΩ 2kΩ 各1個
- Raspberry Pi Zero用ユニバーサル基盤 1枚
- ピンソケット 1個
- 適当なLED 2個
- LEDがいい感じに光る抵抗を何個か
回路基盤のイメージをfritzingで書きました.参考にした記事では,ブレッドボード上に実装していますので,そちらも合わせてご確認ください.
(左上の四端子の部品がにおいセンサ,右上の三端子の部品2個がトランジスタ,下の二端子部品2個がLEDです.
ピンソケットを使って,直接ラズパイにはんだ付けで固定せず,においセンサ基盤だけモジュール化しました.
LEDは家にあったものを適当につけたので,適宜良さげなものをつけてください.そのための抵抗も大きめの抵抗から抵抗値を少しずつ下げて試して行って,いい感じに光るものをつけました.)
プログラム
プログラムは,pythonで実装しました.ソースコードをこちらに置いておきます.
import spidev
# src/unkoDetector/util/spiModule.py
def setup():
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz=1000000
spi.bits_per_word=8
return spi
# src/unkoDetector/unkoDetectorByLineNotify.py
from measure import measure
from util import spiModule, LINENotifyBot
import RPi.GPIO as GPIO
import time
import os
from tqdm import tqdm
import requests
def main():
# Execute the following command in advance on the shell.
# export "LINE_NOTIFY_KEY"=<YOUR_ACCESS_TOKEN>
access_token = os.environ["LINE_NOTIFY_KEY"]
bot = LINENotifyBot(access_token=access_token)
bot.send(message = "においの検出を開始しました")
# Setting up a Google spreadsheet to enter sensor data
# export "GAS_URL"=<YOUR_GAS_URL>
gas_url = os.environ["GAS_URL"]
# Setting of GPIO pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
ch0 = 0x00
spi = spiModule.setup()
judge = False
trial = 100
outlier = 20
threshold_list = [0]*trial
scaling = 0.25
# Warming up to remove outliers.
print("ウォームアップを開始します")
for i in tqdm(range(outlier)):
GPIO.output(22,True)
time.sleep(0.005)
GPIO.output(22,False)
GPIO.output(17,True)
time.sleep(0.008)
GPIO.output(17,False)
time.sleep(0.237)
print("ウォームアップが終了しました")
# Trials for Threshold Determination.
print("基準値の測定を開始します")
for i in tqdm(range(trial)):
GPIO.output(22,True)
time.sleep(0.005)
ch0_val = measure(spi, ch0)
GPIO.output(22,False)
GPIO.output(17,True)
time.sleep(0.008)
GPIO.output(17,False)
time.sleep(0.237)
val = 1023 - ch0_val
threshold_list[i] = val
threshold = sum(threshold_list) / len(threshold_list)
#bot.send(message = "基準値を" + str(threshold) + "に決定しました.")
print("基準値を" + str(threshold) + "に決定しました")
try:
while 1:
GPIO.output(22,True)
time.sleep(0.005)
ch0_val = measure(spi, ch0)
val = 1023 - ch0_val
GPIO.output(22,False)
GPIO.output(17,True)
time.sleep(0.008)
GPIO.output(17,False)
time.sleep(0.237)
print(val)
requests.get(gas_url + "?data=" + str(val))
if val > threshold*(1.0+scaling) and judge == False:
judge = True
bot.send(
message = "出たよ!!",
image = "/home/pi/Laboratory/unkoDetector/src/unkoDetector/photo/mafuyu.jpeg"
)
elif val < threshold*(1.0+scaling) and judge == True:
judge = False
bot.send(
message = "片付けてくれてありがとう!!",
image = "/home/pi/Laboratory/unkoDetector/src/unkoDetector/photo/latte.jpeg"
)
except KeyboardInterrupt:
GPIO.output(22,False)
GPIO.output(17,False)
spi.close()
if __name__ == "__main__":
main()
基本的な流れは,
- においセンサを使うためにGPIOピンのセットアップ
- においセンサの起動
- 基準値となる現在のにおいレベルを測定
- においの測定を繰り返し,全てのセンサ出力値を記録
- 基準値を大幅に超えたら通知
LINEBot
LINEBotの通知機能は,こちらの記事で紹介されている,LINENotifyBotのclassをそのまま拝借しました.
GoogleAppsScript
GoogleAppsScriptによるGoogleスプレッドシートへの記録は,こちらの記事を参考に実装しました.
実際に動かしてみる
今回は,執筆中にフトアゴがうんちをしてくれなかったので,家にあった臭そうなものでテストしました.
実運用ではラズパイZeroを使いますが,テストにはラズパイ4を使いました.
Qiita Raspberry Pi Advent Calendar 2020のためにペットの排泄検知システムを作った動画です.
— Masahito Kumagai (@MasahitoKumagai) December 20, 2020
あとで記事が出たら,ぶら下げます.https://t.co/d7adqvxUZr pic.twitter.com/MFkgc4sNt5
おわりに
今回は,ラズパイを使ってフトアゴ用のにおいセンサを作ってみました.
うちの子もクリスマスプレゼントをもらってうれしそうにしています!!