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

YL-69とMCP3002を使用した土壌湿度センサーデータの取得

こんにちは、ゆきです!

これまでDHT-11を使って土中の湿度を測る仕組みを構築しようとトライしてきましたが、やっぱり土中の湿度を測るには、容器に湿度を蓄えて測定する仕組みでは中々水分量を正確に把握できない。DHT-11自体の精度も1%刻みだしね…。

湿度の測れなかった地中温度・湿度センサーを改造してみた。

そこで今回は土壌湿度センサーを使ってデータを取る仕組みを構築したいと思います。

土壌湿度センサー(YL-69)とはどういうもの?

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

インストールが完了すると、完了と出ますが、僕の場合、最初から入ってたみたいです( ˘ω˘ )

SPIのドライバをインストールしよう。

Raspberry Piでは、SPIデバイスがデフォルトで無効になっています。これはGPIOピンと兼用しているためだと思いますが、SPI通信のためにはこれを有効にする必要があります。
Raspberry Piのコンソールを開いて、以下のように入力します。

sudo raspi-config

入力後以下のような画面が起動するので、「5.Interfacing Options」を選択します。

raspi-configでSPI通信を有効にする1

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

raspi-configでSPI通信を有効にする2

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

raspi-configでSPI通信を有効にする3

これでRaspberry PiのSPIインターフェースが有効になります。コンソールに戻って次のように入力してみましょう。

ls -l /dev/spi*

以下のように出ればOKです。

SPIデバイスの有効化

これで前準備は終了なので、早速実装していきましょう!

土壌湿度センサーとA/DコンバータをRaspberry Piと接続しよう

回路の組み方

MCP3002の回路図

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

実際に組んだ回路は以下です。

実際に組んだ回路

YL-69の配線について

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])&amp;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でも試してみたいと思います。相当シンプルにできると思うので、こちらも近いうちに紹介できればと思っています。

以上!