各種センサの結果をインターネットに接続して共有する
第1回:植物育成デバイス制作の準備
第2回:センサを使って室内の状態チェック
こんにちは、ヨシケンです!
小型のArduino互換機のM5Stackシリーズを使って、室内の植物を見守り、水やりなどを自動化するデバイスを作る今回の連載。今回はM5Stackにさらにセンサを追加して、植物周りの明るさも測れるようにします。また、植物の環境を楽しく分かりやすいようにM5Stackの画面に表示したり、インターネットに接続して植物の状況を遠隔からでも分かるようにします。植物を面白いキャラにしたりして、楽しく植物育成できるようになるかもしれませんよ。
M5Stackシリーズを使って観葉植物育成機作り
今回の記事で必要な物一覧
M5Stack Core
ESP32を搭載し、ディスプレイ、センサなども入ったArduino互換機
ローム照度・近接センサ (RPR-0521RS)
赤外線を発しその反射光を測定して、光の強度や近接度を計測します。
DHT11温湿度センサ
温度と湿度が両方測れるデジタル温湿度センサモジュール
水分センサ
土中の水分量を計測
今回の記事の流れ
1. 照度・近接センサの設定
M5Stackにさらにセンサを追加して、植物の日当たりを確認したいと思います。植物周りの明るさを測るために照度センサというものがあり、今回はロームセンサ評価キットの照度・近接一体型センサモジュール(RPR-0521RS)を使ってみます。
このセンサは、赤外線LEDを発し、その反射光を検知することによりその明るさを測定します。このセンサを使うためにも同様に、ローム・センサのページからzipファイルをダウンロードし、Arduino IDEメニューからRPR-0521RS用のライブラリをインストールします。
サイト中にあるzipファイルをダウンロードし、Arduino IDEのライブラリをインクルード メニューからインストールします。
ソフトウェアがインストールできたら、M5Stackと照度・近接センサをつないでみます。照度・近接センサはI2Cという通信方式を使うので、以下、表に従ってI2C通信が可能なSDA=G21とSCL=G22と接続してください。
センサ側端子 (右から) | M5Stack側(下部) |
VDO | 3.3V (オレンジ) |
GND | GND (青) |
SDA | GPIO21 (黄) |
SCL | GPIO22 (緑) |
INT | NA |
センサとM5Stackをつないだら、Arduino IDEのスケッチ例のところから、先ほどインストールしたサンプルスケッチを選びます。ArduinoIDEでサンプルのPRP-0521RSを選びます。今後これをカスタマイズして使っていくので、M5Stack_Sensors.inoなどとして別名保存しておいてください。そこに以下のようなプログラムを追加します。
以下のようなスケッチが開いたら、その一番上に
1 | #include <M5Stack.h> |
の記述を追加します。その後、左上の書き込みボタン押して、このサンプルスケッチをM5Stackに流し込んでみましょう。
13、19行目の Wire.begin(21,22) は、M5StackでI2Cを使うための宣言になります。
[M5Stack_Light.ino]
01 02 03 04 05 06 07 08 09 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 | #include <M5Stack.h> #include <Wire.h> #include <RPR-0521RS.h> RPR0521RS rpr0521rs; void setup() { byte rc; Serial.begin(9600); while (!Serial); Wire.begin(21,22); rc = rpr0521rs.init(); } void loop() { Wire.begin(21,22); byte rc; unsigned short ps_val; float als_val; byte near_far; rc = rpr0521rs.get_psalsval(&ps_val, &als_val); if (rc == 0) { Serial.print(F( "RPR-0521RS (Proximity) = " )); Serial.print(ps_val); Serial.print(F( " [count]" )); near_far = rpr0521rs.check_near_far(ps_val); if (near_far == RPR0521RS_NEAR_VAL) { Serial.println(F( " Near" )); } else { Serial.println(F( " Far" )); } if (als_val != RPR0521RS_ERROR) { Serial.print(F( "RPR-0521RS (Ambient Light) = " )); Serial.print(als_val); Serial.println(F( " [lx]" )); Serial.println(); } } delay(500); } |
このプログラムをM5Stackで使う際、ひとつ変更が必要です。PRP-0521RS.cppというファイルを開いて、#include <pgmspace.h>として”avr/”を取り除きます。(通常、インストールしたライブラリは、Arduino > Libraries > RPR-0521RS 内にあります)
こうすることにより、M5Stackでpgmspace.hを正常に読み取ることができるようになります。
PRP-0521RS.cppの場所、変更前。赤枠部分から”avr/”を取り除く。
この変更が済んだら、M5Stack_Sensors.inoを実行します。自動的に計測を始め、室内の明るさをルクスで示してくれたと思います。
室内の明るさを計測
2. M5Stackを使ってLINEに通知
植物周りの明るさ、温湿度、土中の水分量が測れたので、その結果を外部からでも分かるようにしましょう。M5StackはWi-Fiが内蔵されていて、インターネットにも簡単につなぐ事ができるので、計測結果をLINEに通知するようにしてみます。
まず、M5StackとLINEを連携していきましょう。LINEにはLINE Notifyという外部から通知を送る仕組みがあり、無料で使えるのでそれとM5Stackを接続できるようにします。最初にこちらのリンクからLINE Notifyに登録をおこないます。
https://notify-bot.line.me/ja/
右上のメニューからLINEアカウントでログインします。
アクセストークンの発行画面があるので、「トークンを発行する」をクリックします。
通知の送り先、またはグループを選びます。指定したグループにLINE Notifyを招待しておきます。
選んでトークンを発行します。このトークンはこの時一度しか表示されないので、確実にコピーしておいてください。
これで、LINEで投稿する設定ができました。それではこれをM5Stackのスケッチで使ってみましょう。
まずWi-Fiとの接続と、LINEに投稿するスケッチは以下のようになっています。
01 02 03 04 05 06 07 08 09 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 | M5Stack_Line.ino #include <M5Stack.h> #include <ssl_client.h> #include <WiFiClientSecure.h> #include <HTTPClient.h> WiFiClient client; const char * ssid = "YOUR SSID" ; const char * password = "YOUR PASSWORD" ; void send(String message) { const char * host = "notify-api.line.me" ; const char * token = "YOUR TOKEN" ; WiFiClientSecure client; Serial.println( "Try" ); client.setInsecure(); if (!client.connect(host, 443)) { Serial.println( "Connection failed" ); return ; } Serial.println( "Connected" ); String query = String( "message=" ) + message; String request = String( "" ) + "POST /api/notify HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Authorization: Bearer " + token + "\r\n" + "Content-Length: " + String(query.length()) + "\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n\r\n" + query + "\r\n" ; client.print(request); while (client.connected()) { String line = client.readStringUntil( '\n' ); Serial.println(line); if (line == "\r" ) { break ; } } String line = client.readStringUntil( '\n' ); Serial.println(line); } void setup() { M5.begin(); WiFi.begin(ssid, password); } void loop() { M5.update(); if (M5.BtnA.pressedFor(100)){ M5.Lcd.print( 'L' ); send( "左ボタン" ); } else if (M5.BtnB.pressedFor(100)) { M5.Lcd.print( 'C' ); send( "中ボタン" ); } else if (M5.BtnC.pressedFor(100)) { M5.Lcd.print( 'R' ); send( "右ボタン" ); } } |
このスケッチでは、M5StackからWi-Fiに接続するために、<WiFiClientSecure.h>のライブラリを読み込みます。スケッチ中の”YOUR SSID”と”YOUR PASSWORD”にはご自宅のWi-FiのID、パスワードを入れます。また”YOUR TOKEN”には先ほどコピーしたLINE Notifyのトークンをペーストします。このプログラムはM5Stack前面にあるボタンを押すと、特定のメッセージをLINEに送るようになっています。
これでまずLINEに結果が投稿できるかテストしてみましょう。M5StackがWi-Fiに接続できたら、左、真ん中、右側のボタンを押してみて下さい。
このように先ほど接続設定したLINEグループに投稿が送られたら、M5StackとLINEの連携ができたことになります。
3. 植物の状況、計測結果を定期的にLINEに送付
M5Stackに接続した温室度センサ、水分センサ、照度センサの結果について、ボタンを押したら送信してくれるようにしましょう。また、ある値を超えたらLINEに送って、状況を把握できるようにします。
前面左側のボタンを押したら、温度と湿度を送信します。真ん中のボタンは水分量、右側は明るさをLINEに通知します。ある値を超えた時のメッセージとして、例えば室温が30℃以上になっていたら「暑いよー!」と警告しています。水分量が少ない時(数値が300以下)には、「喉が渇いたよ!お水ください!」としたら面白いかもしれません。
そんなプログラムを先ほどのスケッチに追加して作ります。
[M5Stack_sensors_line.ino]
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #include <M5Stack.h> #include <DHT.h> #include <Wire.h> #include <RPR-0521RS.h> RPR0521RS rpr0521rs; #include <ssl_client.h> #include <WiFiClientSecure.h> #include <HTTPClient.h> WiFiClient client; const char * ssid = "YOUR SSID" ; const char * password = "YOUR PASSWORD" ; void send(String message) { const char * host = "notify-api.line.me" ; const char * token = "YOUR TOKEN" ; WiFiClientSecure client; Serial.println( "Try" ); client.setInsecure(); if (!client.connect(host, 443)) { Serial.println( "Connection failed" ); return ; } Serial.println( "Connected" ); String query = String( "message=" ) + message; String request = String( "" ) + "POST /api/notify HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Authorization: Bearer " + token + "\r\n" + "Content-Length: " + String(query.length()) + "\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n\r\n" + query + "\r\n" ; client.print(request); while (client.connected()) { String line = client.readStringUntil( '\n' ); Serial.println(line); if (line == "\r" ) { break ; } } String line = client.readStringUntil( '\n' ); Serial.println(line); } // 使用するピン const int PIN_DHT = 5; DHT dht(PIN_DHT,DHT11); void setup() { M5.begin(); WiFi.begin(ssid, password); dht.begin(); byte rc; rc = rpr0521rs.init(); } uint16_t analogRead_value = 0; void loop() { M5.update(); delay(3000); // 湿度を取得 float humidity = dht.readHumidity(); // 温度を取得 float temperature = dht.readTemperature(); analogRead_value = analogRead(36); Wire.begin(21,22); byte rc; unsigned short ps_val; float als_val; rc = rpr0521rs.get_psalsval(&ps_val, &als_val); if (als_val != RPR0521RS_ERROR) { Serial.print(F( "RPR-0521RS (Ambient Light) = " )); Serial.print(als_val); Serial.println(F( " [lx]" )); Serial.println(); } M5.Lcd.clear(BLACK); if ( (temperature > 30) or (analogRead_value < 300) ) { M5.Lcd.fillScreen(TFT_RED); send( "暑いよ〜、温度" +String(temperature,1)+ "Cが高すぎるか、水分不足です!" ); } else if ( (temperature < 10) ) { M5.Lcd.fillScreen(TFT_BLUE); send( "寒すぎ!温度" +String(temperature,1)+ "Cが低いです!" ); } M5.Lcd.setTextColor(WHITE); M5.Lcd.drawString( "M5STACK SENSORS" ,0,0,4); M5.Lcd.setTextColor(YELLOW); M5.Lcd.drawString( "Humidity:" ,0,30,4); M5.Lcd.drawFloat(humidity, 0, 0, 50, 4); M5.Lcd.drawString( "%" ,50,50,4); M5.Lcd.setTextColor(GREEN); M5.Lcd.drawString( "Temperature:" ,0,80,4); M5.Lcd.drawFloat(temperature, 0, 0, 100, 4); M5.Lcd.drawString( "C" ,50,100,4); M5.Lcd.setTextColor(BLUE); M5.Lcd.drawString( "Moisture:" ,0,130,4); M5.Lcd.drawFloat(analogRead_value, 0, 0, 150, 4); M5.Lcd.setTextColor(WHITE); M5.Lcd.drawString( "Light:" ,0,180,4); M5.Lcd.drawFloat(als_val, 0, 0, 200, 4); if (M5.BtnA.pressedFor(100)){ send( "温度は" +String(temperature,1)+ "C、湿度は" +String(humidity,1)+ "%です!" ); } else if (M5.BtnB.pressedFor(100)){ send( "水分は" +String(analogRead_value)+ "です!" ); } else if (M5.BtnC.pressedFor(100)){ send( "明るさは”+String(als_val,1)+”Lxです!" ); } } |
このスケッチを流し込み、植物周りにセットして、使ってみましょう。まず左、真ん中、右側のボタンを押します。そうすると以下のように計測結果をLINEに通知してくれます。
また室温が30℃以上になった時などは、このようなメッセージで警告してくれます。
4. まとめ
今回はM5Stackに、ロームの照度センサを接続して、明るさを計測しました。これで、明るさ、温度、湿度、土中の水分量が計測できたので、これをLINEに送信して、外からでも植物の状況を見えるようにしました。他にもWi-Fiでインターネットに接続できることを活かして、遠隔から操作したり、Twitterなどにも投稿できますね。
次回はいよいよ自動で水をあげる機構を作って、植物の状況により自動で水やりしたり、外部からコントロールできるようにしたいと思います。お楽しみに!
今回の連載の流れ
第1回:植物育成デバイス制作の準備
第2回:センサを使って室内の状態チェック
第3回:各種センサの結果をインターネットに接続して共有する(今回)
第4回:電動スプレーを操作して自動水やり機の完成!