Raspberry Piで土壌湿度センサー(YL-69)からA/Dコンバータ(MCP3002)を使ってデータを取ろう

こんにちは、ゆきです!
これまでDHT-11を使って土中の湿度を測る仕組みを構築しようとトライしてきましたが、やっぱり土中の湿度を測るには、容器に湿度を蓄えて測定する仕組みでは中々水分量を正確に把握できない。DHT-11自体の精度も1%刻みだしね…。
そこで今回は土壌湿度センサーを使ってデータを取る仕組みを構築したいと思います。
目次
土壌湿度センサー(YL-69)とはどういうもの?

YL-69は土の中の抵抗値を測定するセンサーです。水分が含まれた環境下では抵抗が上がり、乾いてくると抵抗値が下がります。
安価ですがその分精度はあまりよくないので、利用環境に合わせてどのくらいの抵抗値になったら水分が不足気味か、閾値を見極めなければなりません。
この辺りの精度の差は、DHT-11と組み合わせて上手く見れるかテストしたいと思います。
土壌湿度センサー(YL-69)を使用する上での注意点
Raspberry Piは土壌湿度センサーのようなアナログデータをそのまま取り込むことが出来ない
Raspberry Piで取り込めるのはデジタルデータのみです。デジタルデータとはHigh or Lowのような、1と0の2択しかないデータを指します。
一方、土壌湿度センサー(YL-69)はアナログ値を返します。YL-69のセンサー部に生じた電流の量を測定し、土壌の湿度を推定します。電圧や電流は、1と0では表せませんよね。
Raspberry Piはアナログデータを読み取ることができません。
この問題を解決するためには、A/Dコンバータを使用します。A/Dコンバータはアナログデータを1と0の2進数に変換し、Raspberry Piに通信で送信するデバイスです。Raspberry Piで送られてきたデータを紐解く事で、現在のアナログ値が判ります。
Raspberry PiとA/Dコンバータの間の通信は、SPI通信を使います。
土壌湿度センサー(YL-69)に入力電圧をかけた状態を続けるとすぐ錆びる
土壌湿度センサー(YL-69)は、その抵抗値を測るため、入力電圧3.3V~5Vを印加する必要があります。しかし、この電圧を測定時だけではなく、常時かけた状態のままにしておくとすぐにセンサー部が錆びます。これは電圧をかけていることにより、金属の表面がイオン化しやすい状態になっているためです。
僕は化学の事はそこまで詳しくないので、詳細については「電気防食」や「金属 イオン化」等のキーワードで表示される検索ページを参考にすると良いかと思います。
(参考)金属はどうして腐食する?
このため、土壌湿度センサーを使用して湿度を取得する場合、計測時のみ電圧を印加する仕組みとしましょう。
A/DコンバータとのSPI通信の準備
A/Dコンバータ(MCP3002)とのSPI通信には、事前に準備が必要です。Raspberry PiにSPI通信のドライバをインストールしていきましょう。まず最初に、コンソールで以下のように入力します。
sudo apt-get install python-spidev
インストールが完了すると、完了と出ますが、僕の場合、最初から入ってたみたいです( ˘ω˘ )

Raspberry Piでは、SPIデバイスがデフォルトで無効になっています。これはGPIOピンと兼用しているためだと思いますが、SPI通信のためにはこれを有効にする必要があります。
Raspberry Piのコンソールを開いて、以下のように入力します。
sudo raspi-config
入力後以下のような画面が起動するので、「5.Interfacing Options」を選択します。

次に「P4 SPI」を選択します。

「Would you like the SPI interface to be enabled?(SPIインターフェースを有効にしますか?)」と出るので、「はい」を選択。

これでRaspberry PiのSPIインターフェースが有効になります。コンソールに戻って次のように入力してみましょう。
ls -l /dev/spi*
以下のように出ればOKです。

これで前準備は終了なので、早速実装していきましょう!
土壌湿度センサーとA/DコンバータをRaspberry Piと接続しよう
回路の組み方

今回用いる回路は以下のような感じ。ちょっと複雑! 土壌湿度センサー(YL-69)とADコンバータ(MCP3002)のデータシートは次の通り。
実際に組んだ回路は以下です。

YL-69の配線について
YL-69は購入時についてくる半固定抵抗付の回路と接続する必要がありますが、これはプラスマイナスはどちらでも大丈夫です。

VCCには3.3~5Vの範囲内で電圧を供給します。今回はGPIOから3.3Vの電圧を印可。AOはDAコンバータのチャンネルと接続します。
DOは半固定抵抗で指定した値を超えると1が立つ信号とのことですが、Raspberry Pi側で判断するため今回は接続していません。
Raspberry Pi側でPythonのプログラムを組もう
今回もPythonで組んでいきます。
# -*- coding: utf-8 -*- import RPi.GPIO as GPIO from time import sleep import spidev #GPIOのピン番号 pin = 22 # initialize GPIO GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.cleanup() #GPIOの指定したピン番号を出力端子に設定 GPIO.setup(pin, GPIO.OUT) #出力用関数 def output_fromGPIO(pin, output): GPIO.output(pin, output) sleep(0.1) #MCP3002動作用関数 def readadc_spidev(adcnum): if ((adcnum > 1) or (adcnum < 0)): return -1 #0x68は1chを使う場合です。2chは0x78を使います。 ret = spi.xfer2([0x68,0x00]) #データは8ビットずつに分かれているので、最初の8ビットを上位データとして8ビットシフトし、下位データと結合する #MCP3002は10ビット目までがデータなので、10ビット目までを残して他のデータを消す adcout = ((ret[0]<<8) + ret[1])&0x3ff return adcout #SPI通信開始 spi=spidev.SpiDev() spi.open(0, 0) # bus0, CE0 #データ取得前にYL-69に電圧を印可 output_fromGPIO(pin,True) try: while True: #先ほど定義したMCP3002の関数を呼び出す getValue = readadc_spidev(0) #値がちゃんと取れたらデータを出力。取れるまでトライ if getValue != -1: print(getValue) break; sleep(1) except KeyboardInterrupt: pass #YL-69の印加電圧をとめる output_fromGPIO(pin,False) #SPI通信終了 spi.close()
早速動かしてみよう
プログラムまで出来たところで、早速動かしてみます。以下の画像のように水に浸してみました。

①乾燥時
>>> 1023
②全部浸した場合
>>> 464
③先端だけ浸した場合
>>> 699
まぁこんなもん・・・なのかな?
おわりに
今回購入したYL-69の場合、全部浸した場合で460~500程度だったため、700くらいを閾値にしておけば水が不足している通知を出せそうですね。しかし実際の土で試してみないことには判らないので、外用のカバーを作成し実際に運用してみたいと思います。
結果が出次第報告します。
また、Raspberry Piで構築してみましたが、同じことをNefry BTでも試してみたいと思います。相当シンプルにできると思うので、こちらも近いうちに紹介できればと思っています。
以上!
ディスカッション
コメント一覧
はじめまして。
土壌湿度で水やりを自動化したくて、やってまいりました。
これとは別にスクレイピングしてsqliteにデータを入れたいと調べようとしてたんですが、こちらで一石二鳥で知ることができました。
プログラムのことなんかでいろんな方のページ読みますが、これだけ理解し良い書き方は見たことないです、ほんと。日本は知りませんが、アメリカのクオリティペーパーは14歳が読んで理解できる基準で書いてるらしいですが、こちらの編集の仕方は学校の教科書のお手本にしてほしいです。
2日分くらい時間を得した感じします。ありがとうございます。
>たら様
お褒めの言葉ありがとうございます!大変励みになります。
自分自身初心者というのもあり、なるべく知識のない人でも出来るようになればとの思いで執筆しています。
その想いが実ったと感無量です。
大変うれしいお言葉重ねてありがとうございます!
これを応用して自動水やりを工作しようと思っていますが、
公開されているpythonを実行すると、0しか応答しません。
8行目 pin 22とありますが、接続はしてないようですが。
>シモ様
コメント遅くなってしまい申し訳ございません。
GPIO22はPin No15です。以下の記事をご参照ください。
https://yuki-no-yabo.com/measure-temp-usingdht11/
このプロジェクト素晴らしいです。
このブログも読みやすくデザインも良いです。