Raspberry Pi Zero Wで植物への自動水やりシステム作った

Raspberry Pi



我が家では妻が植物をいくつか育てていまして、

yatch
yatch

毎朝水やり大変そうだなあ。

ラズパイで楽にさせてあげられないかな?

と思うようになりました。

ググったら、ラズパイで自動水やりシステムを作れるっぽいので、自分もやってみました。

部材調達

Amazonで探したら見つかりました。

商品タイトルが
WayinTop 自動水やり装置 DIYキット 静電容量式土壌水分センサー + 小型ポンプ DC3V 5V + 1M ホース + リレーモジュール 1チャンネル
と、何やらすべて揃ってそうじゃないですか。
約1200円と、DIYするには手を出しやすい価格です。

2023/04/30更新
↑のリンクは売り切れが続いています。
↓で同じものを購入できます。
・ポンプ土壌湿度計リレーモジュール

2023/06/10更新
もとの「WayinTop...」も在庫が復活しています。



コメントを見た感じ、ラズパイでも使えそうです。
買ってみました。



注文して2日で届きました。

内容物は以下の通り。

・土壌センサー
 土壌センサー用3pinケーブル
・リレーモジュール
・ポンプ
・ホース
土壌センサー+3pinケーブル
リレーモジュール
ポンプ(なぜか2本ある)
ホース



Amazonのレビューにもありましたが、なぜかポンプは2つ入っていました。
ホースは1つなので、もう1つホースをつなげれば2つの鉢に水を入れられそうです。
 水を入れるタイミングは同じになりますが。



それぞれをつなげるジャンパーピンも要りそうだったので、併せて購入。
 ブレッドボード・ジャンパーワイヤー(メス-メス)(20cm)40本



まあ特に何の変哲もないケーブルたちです。

使用する母艦はRaspberry Pi Zero Wです。
非力ですが、この用途であれば十分でしょう。
ピンヘッダー付のモノでよかったです。



先ほどの水やりセットをラズパイで使うときはA/Dコンバーターが必要とのことで買いました。
 KKHMF 2個 ADS1115 16Bit ADC 4チャンネル I2C IIC 互換 A/Dコンバータ
センサーから取得したアナログ値をデジタル値に変換し、ラズパイで読み取るために使うそう。



届いて気づいたのですが、ピンと基板が繋がっていないので、はんだ付けが必要そうです。



ということで、ダイソーで買ってきました。
 はんだごて:500円
 はんだ:100円
こんなものまでダイソーで売っているなんて、いい時代になりましたなあ。




また、ポンプを動かす電源も必要とのことで、こちらもダイソーで乾電池を調達。



本当はこんな感じの乾電池ケースの方がいいのでしょうけど、この水やりシステムが軌道に乗ってきたら入れ替えを考えましょう。

準備

まずはA/Dコンバーターにピンをはんだ付けします。
はんだ付けなんて中学で技術の授業以来です。
 組込エンジニアなのに…



結果。
あまりキレイではないですが、センサーをつないでみたら値が取れていたので、良しとします。



配線図は、先ほどの水やりセットを買ったところに

ラズパイで使いたいので配線図ください

とお願いしたら、すぐにPDFを送ってくれました。

動作確認

根性まな板よろしく、とりあえずつないでみました。



配線はこんな感じです。
購入先からのPDFに従って接続しました。
土壌センサーと接続する線はA/Dコンバーターとラズパイ、両方つなげるため分岐が必要です。
 ↓の図で言うと、赤と緑の線
私は線の外皮を剥いて、適当にねじって作成。



配線図PDFにはサンプルプログラムも書いてあったので、とりあえず動かしてみましょう。

リレーにつないでいるGPIO4を出力に設定

以下を繰り返す
 土壌センサーの値を取得
 土が乾いているか?
  乾いている
   → GPIO4をHIGHにする
   → リレー経由でポンプが動く
   → 水が出る
  乾いていない
   → GPIO4をLOWにする
   → リレー経由でポンプが止まる
   → 水が止まる
 0.5秒待つ
#!/usr/bin/python3

import RPi.GPIO as GPIO
import time
import Adafruit_ADS1x15
import math

adc = Adafruit_ADS1x15.ADS1115()
GAIN = 1
SENSOR_THRESHOLD = 15000

PIN = 4

values = [0] * 100

def setup():
	GPIO.setmode(GPIO.BCM)
	GPIO.setup(PIN, GPIO.OUT)
	GPIO.output(PIN, GPIO.LOW)

def loop():
	while True:
		maxValue = 0
		# read some times to avoid pulse value
		for i in range(100):
			values[i] = adc.read_adc(0, gain = GAIN)
			if values[i] > maxValue:
				maxValue = values[i]
		print("maxValue == " + str(maxValue))
		# if dry
		if (maxValue) > SENSOR_THRESHOLD:
			GPIO.output(PIN, GPIO.HIGH)
			print("Pump is ON")
		# if not dry
		else:
			GPIO.output(PIN, GPIO.LOW)
			print("Pump is OFF")
		time.sleep(0.5)

def destroy():
	GPIO.setup(PIN, GPIO.IN)
	GPIO.cleanup()

if __name__ == '__main__':
	setup()
	try:
		loop()
	except KeyboardInterrupt:
		destroy()



作ったコードはgithubに置いてあります。
コンテナ化したのでDockerfileがありますが、ホストOSで動かす場合water.pyのみで十分です。

GitHub - kurofuku/sense-and-water
Contribute to kurofuku/sense-and-water development by creating an account on GitHub.



まずは必要なパッケージを入れます。

sudo apt install python3-pip
sudo pip3 install Adafruit-ADS1x15



やってみたら、/dev/i2c-1がないと怒られました。

python3 water.py 
Traceback (most recent call last):
  File "water.py", line 6, in <module>
    adc = Adafruit_ADS1x15.ADS1115()
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_ADS1x15/ADS1x15.py", line 319, in __init__
    super(ADS1115, self).__init__(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_ADS1x15/ADS1x15.py", line 82, in __init__
    self._device = i2c.get_i2c_device(address, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_GPIO/I2C.py", line 64, in get_i2c_device
    return Device(address, busnum, i2c_interface, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_GPIO/I2C.py", line 97, in __init__
    self._bus = Adafruit_PureIO.smbus.SMBus(busnum)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 125, in __init__
    self.open(bus)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 151, in open
    self._device = open("/dev/i2c-{0}".format(bus), "r+b", buffering=0)
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'



i2c通信が有効になっていないみたいです。
以下を実行して有効化します。
ラズパイ再起動後に有効になります。

vim /boot/config.txt

# 以下を末尾に追記
dtparam=i2c1=on
dtparam=spi=on

vim /etc/modules

# 以下を末尾に追記
i2c_bcm2835
i2c-dev



一応動作確認しました。
良さそうです。

sudo apt install i2c-tools
i2cdetect -y 1
0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --



再チャレンジです。

今度はポンプがずっと動き続けてしまいました。
GPIO4をLOWにしても止まりません。



結論としては、このリレーがLow Level Triggerであることが原因でした。



リレーを使うのは今回が初めてなのですが、事前勉強で確認したいくつかのサイトでは
 入力が一定電圧以上だと回路が成立して電源が入る
という解説のみだったため、自分のリレーもそうだろうと早とちりしていました。

このサイトによれば、
通常5Vで動作させるこのリレーは3.6V-3.8VあたりがON/OFF切替のしきい値のようでした。


一方で、ラズパイのGPIOはHIGHで3.3Vです。
これではHIGHにしてもON/OFFが切り替わりません。

リレーはLow Level Triggerなので、電圧が低いときにONになり、ポンプが動く。

ということで、この接続だとGPIO4をHIGHにしようがLOWにしようが意味がありません。



何とかならないものか、ということで調べたところ、
このリレーを3.3Vで動作させると、前記ON/OFFが切り替わる電圧が2.0Vから2.4Vあたりになる、
とのことです。
であれば、GPIOをLOW/HIGH切り替えれば、ON/OFFを切り替えることができそうです。

先ほどのページと↓を参考にさせていただきました。

ラズパイ GPIOでリレーが起動しないので、解決策を知りたい
### ラズパイ GPIOでリレーが起動しない 個人でIoTプロダクトデザイン開発を行なっている、 Raspberry Piの初心者です。今回質問を行うのも初となります。 現在、非常に基



やってみたら、見事動作しました。
 1秒ごとにON/OFF切り替えをやっています。



これに伴い、配線図は以下の通り変えました。
 リレーのVCCを5Vから3.3Vに変更。

設置

妻からのリクエストとして

外に置いてあるバラに取り付けたい

ということでしたので、さっそく取り付けました。
HARIBOの箱が2つ余っていたので、それぞれ
 ラズパイ、水やりキットなど
 水、ポンプ
というように入れました。



動かしているときはこんな感じです。
少し見づらいですが、鉢の右側に配置しているホースから水が出ているのが見えると思います。

今後の課題

ここまででとりあえず動くようにはなったのですが、いくつか課題が見えてきました。

給水する条件と一回の給水量は調整がいりそう
外に置くとなると、防水・防風対策が必要
ラズパイの電源確保をどうするか
 現在はモバイルバッテリーで動作



給水条件と量は、
 乾いていると判断するセンサーのA/D値
 給水時のポンプを動かし続ける時間
が鍵になりそうです。

また、給水後すぐだとまだ土が十分湿っていない可能性もあるような気がしたので、給水したら10秒程度待ちを入れるのがいいかもしれません。



また先ほどの写真をご覧になってわかる通り、
野ざらしだと雨が降った瞬間にいろいろなパーツがお釈迦になります。
また強い風が吹いたときに吹っ飛んでも困ります。

一番簡単な解決方法は屋内で日当たりのいい場所に置き換えることです。
こちらも妻と相談しながら決めたいと思います。

まずはサランラップで気持ち防水してみました。
小雨程度なら凌げると思いますが、あくまでも一時的なので、のんびりしてはいられません。



電源確保も悩ましいです。
これまた屋内に置けばコンセントに繋げられるので解決ですが、屋外に置くときはどうするか。

ひとつはモバイルバッテリーが考えられます。
最近は40000mAhといった大容量のものもあるようで、1週間程度は持ちそうです。

また、太陽光発電パネルを備えたものもあるようで、充電量が消費量を上回れば半永久的に動かし続けることができます。

ですが、いくつか該当バッテリーを調べた感じ、

満充電までに300時間(=約12日)かかる
雨や曇の日は充電効率が下がる

といった懸念が思いついたため、モバイルバッテリーを使う案は難しそうです。

あるいは、屋外のコンセントを使う手もあります。
 ↓みたいなやつ。
ここに、屋外利用に適した丈夫な電源ケーブルを調達し、ラズパイに繋げればイケそうです。

終わりに

いかがでしたか。

水やりだけだと少し物足りないので、
 水が無くなりそうならメールか何かで通知
 毎日撮影してnextcloudにアップロード
  もしくはLINEに投稿
といったネタもやっていきたいと思います!

Comments

タイトルとURLをコピーしました