前回まで/次回以降の取り組みはこちらから。
どんどん続きを作っていきますよー。
今日は水やりの目安にするための、土の水分量を測ります。
Arduinoで土の水分量を測る
土の水分量、つまり土が乾燥しているか水を保っているかを測るにはどうしたらよいでしょうか。
人間が確認するときには…土を手で触ってみて、湿気ているか乾いているかを見るはずです。それをArduinoで測るには…。
結論は、「電気抵抗」を測ります。
土は電気抵抗が高く(電気を通しにくい)、水は電気抵抗が低い(電気を通しやすい)という性質を利用するわけです。
第1回で紹介したパーツキットにはちょうど良い、というか間違いなくこのために作られたセンサが付いていました。
フォークのように2つに分かれた側がそれぞれ電極になっているので、土に突き刺して電極同士の電気抵抗値を測定します。
内部回路を調べてみたらこんな感じになっていました。
土と水で電気抵抗が違うとはいえ、どちらも電線などと比べると電気が通りにくいので、非常に小さな電流しか流れませんし、水分量による電流の変化も小さなものです。
そこで、電極の間に流れたわずかな電流の変化を、トランジスタという部品を使って大きな電圧の変化にしてArduinoに渡してあげるという動作を行っています。
Arduinoに接続する
今回は使用する基板には動作に必要な部品がすべて実装されています。
「+」ピンは5V、「ー」ピンはGND、「S」ピンはA1(アナログピンならどこでもよい)にそれぞれ接続します。
温度・湿度・大気圧・照度のセンサとは別の場所に設置することが分かっているので、今の段階で専用の延長ケーブルを作って接続しました。
コネクタ付きケーブルを作るんだったら、汎用でいいので圧着工具を持っておくとはかどります。
作業も楽だし、ミスも格段に減りますヨ。
Arduinoで読み取ってみる
今回はライブラリは不要です。
analogReadで読み取ればそのままセンサの出力を読み取ることができます。
ちょうど使えるサンプルスケッチがありますので、それを利用してみましょう。
サンプルスケッチを開く
メニューバー[ファイル]→[スケッチ例]→[03.Analog]からサンプルスケッチ「AnalogInOutSerial.ino」を開いてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | /* Analog input, analog output, serial output Reads an analog input pin, maps the result to a range from 0 to 255 and uses the result to set the pulse width modulation (PWM) of an output pin. Also prints the results to the Serial Monitor. The circuit: - potentiometer connected to analog pin 0. Center pin of the potentiometer goes to the analog pin. side pins of the potentiometer go to +5V and ground - LED connected from digital pin 9 to ground created 29 Dec. 2008 modified 9 Apr 2012 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/Tutorial/AnalogInOutSerial */ // These constants won't change. They're used to give names to the pins used: const int analogInPin = A1; // Analog input pin that the potentiometer is attached to const int analogOutPin = 9; // Analog output pin that the LED is attached to int sensorValue = 0; // value read from the pot int outputValue = 0; // value output to the PWM (analog out) void setup() { // initialize serial communications at 9600 bps: Serial.begin(9600); } void loop() { // read the analog in value: sensorValue = analogRead(analogInPin); // map it to the range of the analog out: outputValue = map(sensorValue, 0, 1023, 0, 255); // change the analog out value: analogWrite(analogOutPin, outputValue); // print the results to the Serial Monitor: Serial.print("sensor = "); Serial.print(sensorValue); Serial.print("\t output = "); Serial.println(outputValue); // wait 2 milliseconds before the next loop for the analog-to-digital // converter to settle after the last reading: delay(2); } |
analogReadで読み取るピンを「0」から「1」に変えて、動かすことができます。
動かしてみる
ここまででArduinoに書き込んでみます。
(図が前々々回の使いまわし…)
書き込んだら、シリアルモニタを起動します
照度がPCにシリアル通信で返ってきています。
帰ってくる数字が大きいほど、電気が通りやすいことを表します。
センサが何にも触れていない状態だとanalogReadの読み取り値は0、
(いちおう、下に敷いてある水色のはゴムマットなので触れていても電気を通しません)
手で触れると70~80、
これは手が濡れているか乾燥しているか、濡れているとしてそれは水道水か汗か、センサの両面を触るか片面を触るか、そっと触れるだけかぎゅっと握るかなどで変わります。
この時は手は乾燥した状態でそっと乗せた(=片面だけ触れている)状態です。
金属製のお皿を載せると860くらい、
センサを水(水道水)に突っ込んでみたら650くらいでした。
水につけるのはセンサの電極だけにして、電子部品が水につかないように気を付けてください。
まとめると、
- 空気中:0
- 乾燥した手:70~80
- 金属のお皿:860
- 水:650
となりました。結構水って電気通すんですね。
水に漬かった電気器具が壊れるとか、濡れた手で電気器具を触ってはいけないとか、よくわかりますね。
あさがお観察用スケッチを作る
例によって最終仕様のスケッチを作っていきます。
前回までに作成したスケッチに追加して、一つのスケッチにまとめます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | // あさがおIoT観察日記 Arduino側プログラム // 2020.05.21 V0.0.1 DHT11による温度・湿度取得(DHT11サンプルスケッチより作成) // V0.0.2 BME280気圧取得(BME280サンプルスケッチより作成) // 2020.05.23 V0.0.3 TEMT6000による照度取得 // 2020.05.24 V0.0.4 KeyStudio製センサで土の水分量取得 #include <Adafruit_Sensor.h> #include <DHT.h> #include <DHT_U.h> #define DHTPIN 2 // Digital pin connected to the DHT sensor #define DHTTYPE DHT11 // DHT 11 DHT_Unified dht(DHTPIN, DHTTYPE); #include <Wire.h> #include <SPI.h> #include <Adafruit_BME280.h> #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME280 bme; // I2C uint32_t delayMS; int Alt = 120; void setup() { Serial.begin(9600); dht.begin(); delayMS = 1000; bme.begin(0x76); } void loop() { double temp; double temp_0; double humid; double pres; double pres_0; int bright; int water; delay(delayMS); sensors_event_t event; //温度取得 dht.temperature().getEvent(&event); if (!isnan(event.temperature)) { temp = event.temperature; } //湿度取得 dht.humidity().getEvent(&event); if (!isnan(event.relative_humidity)) { humid = event.relative_humidity; } //気圧取得 pres = bme.readPressure() / 100; pres_0 = pres/(pow((1-((0.0065*Alt)/(bme.readTemperature()+0.0065*Alt+273.15))),5.257)); //海面更生 //照度取得 bright = analogRead(0); //水分量取得 water = analogRead(1); //水やり判断 //シリアル送信 Serial.println(temp); Serial.println(humid); Serial.println(pres); Serial.println(pres_0); Serial.println(bright); Serial.println(water); } |
水分量センサの読み取り値を「water」というint型の変数に代入し、シリアル通信でPCに送るようにしてみました。
水分量は最終的には2つの使い道を考えています。
- シリアル通信でRaspberryPiに送って、IoTサービスにデータをアップロード
- RaspberryPiから時刻を受け取って、時刻と水分量との条件を決めて自動で水やりをする
何物にも限度ってものがあります。
水もじゃぶじゃぶ与えればいいというものではないようなので、時刻と土の乾燥度合いによって水やりを適度にコントロールする方法を考えていきます。
これで温度・湿度・気圧・照度・土の水分量が測定できるようになりました。
まだまだ続きます。
コメント