mimikakimemo

自分用メモ。

ESP8266 で静電容量式土壌水分センサーを使う

水やりの目安にするため、土壌中の水分量を測定したい。ということで、土壌水分センサーを買ってみた。まずは動かすところから。

土壌水分センサーの種類

手軽に手に入る土壌水分センサーには、電気抵抗式のものと、静電容量式のものがある。

電気抵抗式のセンサーは、2 つの電極が露出している。価格が少し安めだが、使っていると電極が錆びやすいとのこと。

一方、静電容量式のセンサーは電極が露出しておらず、長期間安定して使えるらしい。そんなわけで今回はこちらを選んだ。Amazon だと 5 個セット(そんなに要らないが)で 800 円ほどなので、160 円/個。

Amazon で買ったセンサーの表面には、Capative Soil Moisture Sensor v1.2 と書かれている。調べてみると、DFRobot から販売されている Analog Capacitive Soil Moisture Sensor SEN0193 の、ジェネリック版らしい。

www.dfrobot.com

このセンサーの仕様や使い方については、DFRobot の Wiki に詳しく解説がある。

wiki.dfrobot.com

ESP8266 でアナログ入力を扱う

ESP8266(ESP-WROOM-02)には、アナログ入力に使えるピンが 1 つしかない。TOUT というピン名になっている。Arduino のスケッチ内では、ピン番号として定数 A0 を使う。値の取得には、普通の Arduino 同様、analogRead() 関数を使う1

int value = analogRead(A0);

ひとつ注意が必要なのは、0 V 〜 1 V の範囲でしか入力を受け付けない点。0 V 〜 3.3 V ではない。10 ビットの精度で、0 V のときは 0、1 V のときは 1023 という値が得られる。今回は土壌水分センサーを 3.3 V で動かしているので、手元にあった 10 kΩ の抵抗 3 本を使って、ざっくり 1/3 に分圧した。

f:id:mimikakimemo:20210523020641p:plain

土壌水分量の測定

f:id:mimikakimemo:20210523025240j:plain

analogRead() で読み取った値を、以下のようなコードでそのまま表示してみた。

#include <Arduino.h>

void setup()
{
  Serial.begin(74880);
}

void loop()
{
  const int value = analogRead(A0);
  Serial.println(value);
  delay(1000);
}

条件を変えて簡単に試した結果は以下の通り。

条件 測定値
空気中に出しているとき 394
植木鉢にさしたとき 298
植木鉢に水をやった後 265
水に浸したとき 228

普通の湿度とは逆で、水分が多いほど測定値は小さくなる。このままだとわかりにくいので、空気中における値  V_{\text{air}} を 0%、水中における値  V_{\text{water}} を 100% として、水分量を百分率で表すことにしたい。水分量と測定値の関係が線形だと雑に仮定すると2、測定値が  V のとき、水分量は

 \displaystyle
\frac{V_{\text{air}} - V}
       {V_{\text{air}} - V_{\text{water}}}
\times 100 \,[\%]

で計算できる。

この測定値・水分量は、土の種類や設置位置、センサーの個体差に大きく左右されるはず。しかし、今回の目的は「水やりの目安にするため、湿っているか乾いているかざっくり判定したい」という点なので、あまり細かいことは気にしなくて大丈夫。ただ、こちらの記事にあるとおり、電源電圧の低下には気をつける必要がありそう。

次は水分量を一定間隔で測定して、グラフ化したい。

参考


  1. 昔は analogRead() に対応していなかったようで、古い記事では「system_adc_read() を使う」という記述が見られる。

  2. こちらの記事の測定結果によれば、土壌が乾いてくると線形から外れる様子。