#ポトスにお水をあげなくちゃ
私の部屋には、毎日つかれた心をいやしてくれる「ポトス」がいます。
今年の5月に100均で購入し、可愛がっていたら、
ぐんぐん育ってくれて…
2、3日に1度、水やりをやっているのですが、
年に数回、地元へ帰省することがあり、
毎回7〜9日間ほど家をあけることがあります。
家を空けている期間は誰も水やりができないので、
このままでは、大切なポトスが苦しんでしまいます。
.
そんなわけで今回は、大切な観葉植物を毎日元気にするために、
RaspberryPiの工作を通して学んだ知識を活かして
水やりの自動化に挑戦していきました。
#完成イメージ
指定した時間に水やりをして、観葉植物の状態を撮影、
LINEに実行通知と画像を送信するプログラムを動かします。
#材料
- Raspberry Pi 3 B+
- 小型水中ポンプ DC5V
- WEBカメラ
- チューブ(小型水中ポンプの吐き出し口の径に合うもの)
- 水を貯めるもの
#環境
- PC:MacBook Pro2017(macOS Big Sur_Ver11.6.1)
- エディタ:Atom(Ver1.58.0)
- VNC Viewer(Ver6.20.529)
- -raspbian
- No LSB modules are available.
- Distributor ID: Raspbian
- Description: Raspbian GNU/Linux 10 (buster)
- Release: 10
- Codename: buster
- Python:3.7.3
Atomを用いてリモートでRaspberryPiへアクセスする方法を過去に紹介しています。
作業性が良いので、ぜひ参考にしていただけたらと思います。
↓ ↓ ↓
RaspberryPi内のPythonファイルをAtomのリモート機能で編集したら最高だった
#手順
ラズパイのOSインストール、環境設定等に関する説明は割愛します。
なので、環境構築ができている前提で進めていきます。
##ポンプ制御
ポンプはUSB電源に接続すると、モータが駆動する仕様になっています。
RaspberryPiのUSBポートは常時通電しているので、
繋げたままだと無限給水してしまいます。
USBポートの電源をON、OFF制御できるようにしましょう。
.
まずは、USBを制御するためのhub-ctrlを導入します。
ターミナルに下記を入力
$ sudo apt-get install libusb-dev
$ wget http://www.gniibe.org/oitoite/ac-power-control-by-USB-hub/hub-ctrl.c
$ gcc -O2 hub-ctrl.c -o hub-ctrl-armhf-static -lusb -static
$ sudo cp hub-ctrl-armhf-static /usr/local/bin/hub-ctrl
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import datetime
import os
# USB-ON
def USB_ON():
print("USB-ON")
os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 1")
return
# USB-OFF
def USB_OFF():
print("USB-OFF")
os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 0")
return
# 実行関数
def job():
now_time = datetime.datetime.now()
print("現在時刻 : ", now_time)
# ON
USB_ON()
time.sleep(5)
# OFF
USB_OFF()
指定したUSBポートに対するON_OFF制御はできないみたいなので、
ON_OFFの切り替えは、全ポート行われます。
ちなみに、os.system("sudo hub-ctrl -b...の末尾の数字が、
1でON、0でOFFに切り替わります。
##Line通知+定期実行
過去に投稿した記事を参考に、Lineへの通知処理を実行します。
Lineのアクセストークンが必要になるので、
その取得方法等は下記のリンクをご参照ください。
↓ ↓ ↓
RaspberryPiを使って、インターホンを押すとLINEに通知が行く仕組みを1からつくってみた
また、下記の例だと20秒に一度の定期実行を行います。
定期実行はscheduleモジュールを使って実行できます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import datetime
import os
import requests
# USB-ON
def USB_ON():
print("USB-ON")
os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 1")
return
# USB-OFF
def USB_OFF():
print("USB-OFF")
os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 0")
return
# Line通知
def Line_notify(message,sP_ID,s_ID):
payload = {
'message':message,
'stickerPackageId': sP_ID,
'stickerId': s_ID}
headers = {'Authorization': 'Bearer ' + '発行したアクセストークンをここに書きます' }
res = requests.post('https://notify-api.line.me/api/notify', data=payload, headers=headers)
print(res)
# 実行関数
def job():
now_time = datetime.datetime.now()
print("現在時刻 : ", now_time)
message = '\n\n水やりしたから、ヨシ!'
sP_ID = 11538
s_ID = 51626496
# ON
USB_ON()
time.sleep(2)
img = ShotPicture()
Line_notify(message,sP_ID,s_ID)
# OFF
USB_OFF()
os.remove(img)
# Test
schedule.every(20).seconds.do(job)
try:
while True:
schedule.run_pending()
time.sleep(1)
except:
USB_OFF()
message = '\n\nなんかエラーが発生したっぽいけど、ヨシ!'
sP_ID = 11538
s_ID = 51626515
Line_notify(message,sP_ID,s_ID)
実行すると、下記のようにLineへ通知が来ます。
##撮影・画像送信
WEBカメラでポトスを撮影して、Lineに送信します。
WEBカメラで撮影する前に、OpenCVの環境を構築を実施。
この環境構築なのですが、上手くできていないとプログラムを実行した際に、
下記のようにエラーが出力されてしまいます。
私は、このエラー解決にもっとも時間がかかったので、
備忘のため、記事を残します。
最終的には、下記の記事を参考に、
記事の最下部まで試してやっと環境構築ができました。
↓ ↓ ↓
【Raspberry Pi】Raspberry Pi Zero WにOpenCVの環境を構築する
撮影・画像送信を追加した水やりプログラムはこちら
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import datetime
import os
import schedule
import requests
import cv2
from PIL import Image
# USB-ON
def USB_ON():
print("USB-ON")
os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 1")
return
# USB-OFF
def USB_OFF():
print("USB-OFF")
os.system("sudo hub-ctrl -b 1 -d 2 -P 2 -p 0")
return
# Line通知
def Line_notify(message,sP_ID,s_ID,img):
payload = {
'message':message,
'stickerPackageId': sP_ID,
'stickerId': s_ID}
files = {'imageFile':open(img, 'rb')}
headers = {'Authorization': 'Bearer ' + '発行したアクセストークン' }
res = requests.post('https://notify-api.line.me/api/notify', data=payload, headers=headers, files=files)
print(res)
# カメラ撮影関数
def ShotPicture():
Image_dir = "/home/pi/Desktop/"
now = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
file_name = now + '.jpg'
cc = cv2.VideoCapture(0)
ret, img = cc.read()
cv2.imwrite(file_name, img)
img = Image_dir + file_name
cc.release()
return(img)
# 実行関数
def job():
now_time = datetime.datetime.now()
print("現在時刻 : ", now_time)
message = '\n\n水やりしたから、ヨシ!'
sP_ID = 11538
s_ID = 51626496
# ON
USB_ON()
time.sleep(3)
img = ShotPicture()
Line_notify(message,sP_ID,s_ID,img)
# OFF
USB_OFF()
os.remove(img)
# Test
schedule.every(20).seconds.do(job)
# Production
# schedule.every().day.at("07:00").do(job)
try:
while True:
schedule.run_pending()
time.sleep(1)
except:
USB_OFF()
message = '\n\nなんかエラーが発生したっぽいけど、ヨシ!'
sP_ID = None
s_ID = None
img = '/home/pi/Desktop/main.png'
Line_notify(message,sP_ID,s_ID,img)
ShotPicture()で定義している部分で撮影の処理を行います。
このソースを実行させた結果がこちら。
テスト動作で水やりをさせていませんが、ヨシですね!.
except節で定義している、デスクトップ上の画像を選択して送信させています。
また、水やり中にエラーが発生し、無限給水をしてしまわないように、
USB給電をOFFにする処理を実行させるようにします。
これでヨシですね。(たぶん)
##自動実行
過去にスケジューリングをするならsystemdがいいと聞いたので、
自動実行をするために、shellスクリプトとserviceファイル作成、
権限付与などの処理を行います。
こちらも、過去に投稿した記事がありますので
詳しくはこちらからどうぞ
↓ ↓ ↓
Raspberry Piでプログラムの自動起動をsystemdでやってみた
.
これで、自動水やりプログラムは完成です!
##たのしい工作
といっても、WEBカメラ、水中ポンプ、USBライトをRaspberryPiに差し込むだけ。
でおわる予定だったのですが、
USBライトはタッチセンサーのスイッチを押さないと点灯しない
仕様なので、ちょっとだけひと手間加わえます。
通電時に電源をONにしたいけど、どうしよう…
.
よし、考えるのはあとだ!! 分解!!
電子部品に関することは詳しくわからないのですが、
おそらく、タッチセンサーの信号をオペアンプで増幅させて、
抵抗の大きさが異なる回路に切り替えているのかなと思います
(間違っていたらごめんなさい…)
なんとなく、ICの部分を短絡させればいけるかなと思い、検証してみます。
.
すると画像の部分を短絡させることによって、
電源ONのときにLEDが点灯することに成功!
その辺に落ちてた配線をはんだ付けするだけで終了です。
もし、配線がない場合は、
緑色の配線(乾電池からの電源供給)を拝借しましょう。
小さい基盤ようのはんだごてを持っていないので、
配線を焦がしてしまったことは見逃してください。
##完成品
あとは、組み立て、いい感じに配線したら完成です。
#参考記事
#終わりに
まめコーヒーアドベントカレンダーの記事を書くネタを考える時期が、
たまたま帰省前だったので、こんな記事になってしましました。
この文章を書いている時に、コーヒーネタでもよかったなーと…
ポンプがあるなら、なんちゃってドリップマシンでもつくれたかもしれないですね。
来年のアドベントカレンダーのネタに取っておこうと思います。
(忘れているかもしれないけど)
.
最後まで見ていただきありがとうございました!!