はじめに
皆さんこんにちは!MOZI電子工作です。
ところで、皆さんは家にいるとき突然雨が降ってきて、洗濯物を干しているのに濡れてしまった!ということはありませんか?そんな時に役立つのが、雨降り検知装置!
ということで今回は、ESP32を使った雨降り検知装置を作っていきます!
構想
雨を検出するのは水滴センサ(下のようなもの)を使います。この雨センサはうねうねしたパターンの書いてある基板に水を垂らすとデジタルアウトピンから出力されるものです。
それで、雨を検出する装置を作るのでこれでいいんですが、せっかくなので外気温を測定する機能も付けようと思いました。
外の気温と湿度を両方図ることができる温湿度センサを使います。
回路図は下の図です。
ということでハードウェアはこんな感じですが、ソフトウェアはどうするかというと、まず雨の警告はIFTTTを使ってLINEに送信させようと思います。そして、外の温度湿度ですが、これはESP32の機能としてwebサーバーを作る見たいな機能を使用してスマホのブラウザから確認できるようにしようと思います。イメージとしては以下の図の感じ。(最終的にはできないのですが...)
基本的に操作はスマホから全てできるようにします。
プログラム
ブラウザからのみ確認
//プログラムの参考(というかほぼコピペ)させていただきましたサイト →https://wak-tech.com/archives/719
//温湿度センサーのライブラリをインポート
#include <DHTesp.h>
// Wi-Fiライブラリをインポート
#include <I2CLiquidCrystal.h>
//I2Cのライブラリをインポート
#include <Wire.h>
// Wi-Fi接続情報を入力
const char* ssid = "SSID";
const char* password = "PASSWORD";
// ウェブサーバーをポート80で開始
WiFiServer server(80);
// HTTPリクエストを保存しておく変数
String header;
#define DHTPIN 32
DHTesp dht;
//温湿度センサー
#define PIN_RAIN 33
void setup() {
Serial.begin(115200);
//Wi-Fiのセットアップ
// ssidとpasswordを用いてWi-Fiに接続
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// IPアドレスを出力し、webserverをスタート
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
pinMode(DHTPIN,INPUT);
pinMode(PIN_RAIN,INPUT);
dht.setup(DHTPIN,DHTesp::DHT11);
timer = timerBegin(0, 80, true); //timer=1us
timerAttachInterrupt(timer, &LED_Blink, true);
timerAlarmWrite(timer, 600000000, true); // 500ms
timerAlarmEnable(timer);
}
void loop() {
// put your main code here, to run repeatedly:
WiFiClient client = server.available(); //クライアント(スマホやPCなど)がつながっているかどうかをclientに出力
if (client) { // クライアントが来たとき
Serial.println("New Client.");
String currentLine = ""; // クライアントからくるデータを格納する変数
while (client.connected()) { // クライアントがつながっている間、以下をループ
if (client.available()) { // クライアントからデータが来ているとき
char c = client.read(); // データを読み込み
Serial.write(c); // 届いたデータをシリアルモニタに出力
header += c;
if (c == '\n') { // 届いたデータが改行コードだった時
// もし現在の行が空白ならば、この改行コードのみ受け取る
// つまりHTTPリクエストの終わりなので、レスポンスを返す
if (currentLine.length() == 0) {
// HTTPヘッダは(HTTP/1.1 200 OK)のようなステータスコードから始まる
// 次にコンテントタイプを送信。今回はhtml形式なので以下のようにする
//湿度、気温センサの更新
TempAndHumidity newValues = dht.getTempAndHumidity();
if (dht.getStatus() != 0) {
Serial.println("DHT11 error status: " + String(dht.getStatusString()));
client.println();
client.println("<!DOCTYPEhtml><html><head><title>現在の温湿度・天気</title><meta charset=\"UTF-8\">");
client.println("</head><body><h1>温湿度センサーのエラー</h1><p>DHT11 error status: " + String(dht.getStatusString()) + "</p></body></html>");
client.println();
break;
}
float temp = newValues.temperature;
float hemi = newValues.humidity;
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPEhtml><html><head><title>現在の温湿度・天気</title><meta charset=\"UTF-8\">");
client.println("<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\">");
client.println("<link href=\"https://fonts.googleapis.com/css2?family=Pathway+Gothic+One&display=swap\" rel=\"stylesheet\">");
client.println("<link href=\"https://fonts.googleapis.com/css?family=Sawarabi+Gothic\" rel=\"stylesheet\"><style type=\"text/css\"> ");
client.println("body{font-family:'PathwayGothicOne','SawarabiGothic'sans-serif;}#block{margin:0px10px; font-size:50px; } .numbers{font-size:300px; } #temp{color:#E62360; } #humid{color:#E6D839; } #rain{color:#0BB6E6; font-size:120px; }</style>");
client.println("</head> <body><div id=\"block\">気温 <span class=\"numbers\" id=\"temp\">");
client.println((String)temp);
client.println("</span>℃<br>湿度 <span class=\"numbers\"id=\"humid\">");
client.println((String)hemi);
client.println("</span>%<br>雨  <span id=\"rain\">");
//雨センサ
if (digitalRead(PIN_RAIN) == LOW) {
client.println("降っている");
} else {
client.println("降っていない");
}
client.println("</span></div></body></html>");
// HTTPレスポンスの最後は改行で終了
client.println();
// whileループの終了
break;
} else { // 改行コードを取得したら、currentLineをリセット
currentLine = "";
}
} else if (c != '\r') { // 改行以外の何かしらのコードが来ているとき
currentLine += c; // currentLineに追加
}
}
}
// ヘッダーをリセット
header = "";
// 接続をリセット
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
こんな感じのプログラムができました。
このプログラムは大まかにいうとESP-32自体でWebサーバーを作り、それにアクセスが来たらHTMLを送る、という寸法です。ただ、これは家の中でしか確認ができません。ただ、雨が今降ってきたっていうのを外出中に確認できても何もできないので今回は良しとします。
そしてIFTTTからのLINEの通知ですが、かなり難易度が高く断念しました...
もし出来るようになったら、作り直したいと思います。
設計
本体の設計をしていきます。
まず、回路ですが以下の通り。
回路図
これをユニバーサル基板に移しました。
ケースも作らないといけませんが野外に設置する予定なのである程度防水をしないといけません。防水を厳密にするのは技術的にも予算的にも難しいので、防水をするためのケースを3Dプリンターで作ることにしました。長期間の稼働を考えて、電源はACアダプタを使用することにします。
設計
3Dプリンタのデータの設計はfusion360を使用しました。
こんな感じです。
一度プリント失敗しましたが、ノズルのつまりをとるとプリントできました。
ACアダプタの設計ミスをしていますが、気にしない気にしない...
防水はグルーガンで行いました。ガバガバだと思うので秋月の部品と同梱してある、あのシリカゲルも一応入れておきました。
動かしてみる
いざ、動かしてみようと思います。
スマホのブラウザ
で特定のIPアドレスを開くと、、、?
はい、動きましたね!
少しUIは崩れていますがしっかり表示できているようです。
まとめ
いかがだったでしょうか。
LINEでの通知はできませんでしたがかなり便利になったと思います。
ESP32にかなり可能性を感じました!
最後まで読んでいただきありがとうございました!
P.S.先日雨が降ったのですが安定して動いているので防水はちゃんとできているようです。
投稿者の人気記事
-
MOZI
さんが
2021/02/20
に
編集
をしました。
(メッセージ: 初版)
-
MOZI
さんが
2021/02/27
に
編集
をしました。
(メッセージ: 追記の追加)
-
MOZI
さんが
2021/02/27
に
編集
をしました。
-
MOZI
さんが
2021/02/27
に
編集
をしました。
-
MOZI
さんが
2021/12/07
に
編集
をしました。
(メッセージ: 記事の種類・ライセンスを設定しました。)
ログインしてコメントを投稿する