ESP8266と土壌センサを使って水分量を測定する方法を解説

 


画像の拡大

この記事では、Arduino互換機のESP8266(ESP-WROOM-02)を使って、土壌センサーで土の水分量を測定してみたいと思います。ESP8266には、ADコンバータが1つだけ内蔵されているのでそれを使って、土壌センサーのアナログ電圧を読み取っていきます。また、WiFiでログデータをAmbientへ送信してグラフ化するまで行ってみたいと思います。他のArduinoでもほぼ同じ内容で動作すると思いますので、ぜひ参考になさってみてください。

土壌センサの選択

まずはじめに、土壌センサの選択のお話から。土壌センサには2つの種類があります。

  1. 抵抗型
  2. 静電容量型

❶の抵抗型は、2つの金属棒で土の抵抗を測って土壌の水分量を測定する方法です。水分量が増えれば電流が流れやすくなり電気抵抗が少なくなるといった具合です。とてもシンプルでカンタンな方法なので、釘を使って自作も可能です。ただし、金属棒が土にさらされるわけですから、腐食しやすいです。使っているうちに抵抗値も変化してしまうでしょう。

一方で、❷の静電容量型は、センサーに接触している水分量が変わると、センサー内部の静電容量が変化するのを利用して土壌水分量を測定します。静電容量型は、電極板をコーティングできるので腐食の恐れがほぼないと言って良いでしょう。この記事でも❷の静電容量型を使用しました。Amazonでよく見かけるこちらの製品は「Capacitive Soil Moisture Sensor」というものです。バージョンが書いてありますがどういった違いがあるのかは分かってません(^_^;)どちらともアナログ値を出力するものなので、使い勝手は同じだと思います。

▼ こちらはなんと、土壌センサとリレーやポンプがセットになった「自動水やり装置」です。楽しそうで実験してみたくなりますね。

リレーの使い方はラズパイとリレーモジュールをご参考になさってみてください。

ラズパイだけでなく、Arduinoでもカンタンにリレーを取り扱うことができます。

▼ PHを測定できるセンサも見つけてしまいました!本格的な農業ができそうです。

土壌センサの使い方

それでは「Capacitive Soil Moisture Sensor」の使い方をみていきましょう。ネットを探しても公式のマニュアルを見つられないのですが、調べた限りの情報をまとめます。

項目内容
電源電圧3.3〜5.5V
出力電圧範囲0〜3V
消費電流5mA

センサのアナログ出力電圧は、センサによって少しばらつきがあるようです。複数台使う場合は、補正かけるなどの工夫が必要かもしれません。

土壌センサの使用範囲は図のとおりです。センサにラインが引いてありますが、これは警告線です。このラインより1cm〜2cm下の範囲までを、土壌に埋めるようにしましょう。

土壌センサの使用範囲
土壌センサの使用範囲

このセンサの回路が分かりましたのでご紹介しておきます。回路は至ってシンプルな組み合わせでできていました。

土壌センサの回路図
土壌センサの回路図

まず、タイマICの555を使って矩形波を発生させています。矩形波は1次のRCローパスフィルタに通されます。すると、矩形波はローパスフィルタによって高周波成分が削られていき三角波へ近づきます。そして、交流信号(電圧)を直流信号(電圧)に変えるため、AC-DCコンバータを通します。

ここで、ローパスフィルタのコンデンサCを土壌センサのプローブにすると、静電容量の変化に応じてカットオフ周波数が変化します。つまりフィルタのかかり具合が変わり、出力のアナログ電圧が変化するわけです。

AC-DCコンバータは、Peak Detectorとも呼ばるもので、いわゆる半波整流回路になってます。実は、アナログ出力とは、1uのコンデンサに溜まった電荷を測っているにすぎないのです。1MΩの抵抗は、1uのコンデンサに溜まった電荷を逃がす役割をします。センサの反応が悪いと感じた場合には、この抵抗を100kΩ程度に変えると改善すると思います。

AOUTとGND間に100kΩ
AOUTとGND間に100kΩ

ここらへんの話はECM音センサの作り方でも書きましたので参考になさってみてください。

土壌センサーとArduino(ESP8266)の配線

それでは土壌センサとESP8266を配線していきましょう。

センサーの電源はESP8266の主電源と同じ3V3に接続します。また、ESP8266の TOUT ピンへ入力できる電圧は+1Vまでです。そのため土壌センサのアナログ出力AOUT を、分圧抵抗で1/3の電圧に電圧降下させました。これによってセンサの値を0V〜約1Vの範囲で読み取ることができます。

分圧抵抗の入れ方
分圧抵抗の入れ方

ESP8266と土壌センサー
ESP8266と土壌センサー

水分量の計算方法

土壌センサーを使って水分量を測定するには準備が必要です。それは、空気中と水中においてのアナログ出力を知る必要があります。空気中で値を水分量0%とし、水中での値を水分量100%とします。土壌センサにはラインが引いてありますので、それより少し手前までを水につけて測定します。

土壌センサーを水につけてアナログ電圧を読み取る
土壌センサーを水につけてアナログ電圧を読み取る

つぎに、空気中の値を AirValueとし、水中の値をWaterValue とします。水分量 Moisture(%)は次の式で表すことができます。

$$ Moisture = 100 - 100 \times \frac{(Aout - WaterValue)}{(AirValue - WaterValue)}$$

ここでAoutは、センサのアナログ出力値であります。

土壌水分量の測定プログラム

それでは実際にArduinoでプログラミングを行っていきましょう。プログラムの内容は、土壌水分量をしてそのデータをAmbientへWiFiで送信するものとなっています。なお、Ambientの使い方はここでは詳しく解説しませんので、M5StickC PLUSからAmbientへデータ送信をご参考になさってみてください。

#include "Ambient.h"
//ESP8266では、アナログ入力を使うため以下の記述が必要
extern "C" {
#include "user_interface.h"
}

const int AirValue = 224; // 空気中の実測値を設定する
const int WaterValue = 123; // 水に浸した実測値を設定する
const char * ssid = "WiFi SSID";
const char * password = "WiFi パスワード";
const int channelId = チャネルID;
const char * writeKey = "ライトキー";

WiFiClient client;
Ambient ambient;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password); //  Wi-Fiの初期化

  while (WiFi.status() != WL_CONNECTED) {  //  Wi-Fiアクセスポイントへの接続待ち
      delay(500);
  }

  ambient.begin(channelId, writeKey, &client);  //  チャネルIDとライトキーを指定してAmbientの初期化
}

void loop() {
  int v = system_adc_read();
//  Serial.println(v);
  float moisture = 100 - 100 * (v - WaterValue) / (AirValue - WaterValue);
  Serial.println(moisture);  
  
  ambient.set(1, moisture);
  ambient.send();
  
  delay(60 * 1000);
}

WiFiやAmbientの必要がなければ、setup関数内がほとんど消えるのでもっとカンタンになりますね。ところでESP8266では、TOUTピンからアナログ電圧を取得するために、以下の宣言が必要なので注意してください。他のArduinoの場合は、この部分は削除してください。

extern "C" {
#include "user_interface.h"
}

測定結果!?

最後に、実際に土壌センサーを使って、ベランダで育てている野菜プランターの土壌を測定してみました。

土壌センサーを使ってベランダの野菜プランターの土壌水分量を測定
土壌センサーを使ってベランダの野菜プランターの土壌水分量を測定

朝に水やりをしてから、土壌の水分量の測定を開始しました。こちらがAmbientで表示させたグラフです。

時間と土壌水分量の推移グラフ
時間と土壌水分量の推移グラフ

なぜか水分量が上昇していきます。不思議に思いながらも、そのままログを取り続けてみました。数式を何度も確認しながら「間違ってないよなー」と思うのですが、不思議です。その後、電池切れになり電池を交換した時に重大なことに気づきました!

こちらが電池交換したあたりのログです。

定電圧でなかったために水分量が正しく測れていない
定電圧でなかったために水分量が正しく測れていない

おわかり頂けますでしょうか?

電源の電圧降下が影響して、土壌センサーのアナログ出力に影響してしまったんです。実は先ほどの写真に写ってます通り、ESP8266の主電源をアルカリ乾電池2本で供給していました。当然、運転しているうちに電圧降下が起こります。土壌センサーは出力電圧が低くなると水分量が多いと判断されるわけですからね。電池の消耗で電圧が下がると右肩上がりのグラフになってしまったのです。

もちろんこの問題は、3.3VのレギュレーターなどのDC-DCコンバータを使って安定化電源にすれば解決します。

とりあえず今回は、土壌センサーの使い方を覚えただけで良しとしましょう。皆さんもセンサを使ってアナログ値を読み取る場合には、くれぐれもご注意ください。

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
人気のArduino互換機
Arduinoで人気の周辺パーツ
Arduinoのオススメ参考書

▼ Arduino初心者向きの内容となっています。ほかのArduino書籍と比べて図や説明がとてもていねいで、読みやすかったです。Arduinoで一通りのセンサーが扱えるようになります。

▼ 外国人が書いた本を翻訳したものです。この手の書籍は、目からうろこな発見をすることが多いです。

▼ Arduinoの入門書を既に読んでいる方で、次のステップを目指したい人向きの本です。C言語のプログラミングの内容が中心です。ESP32だけでなく、ふつうのArduinoにも役立つ内容でした。

関連記事