MOZIのアイコン画像
MOZI 2021年02月20日作成 (2021年12月07日更新) © MIT
製作品 製作品 閲覧数 6617
MOZI 2021年02月20日作成 (2021年12月07日更新) © MIT 製作品 製作品 閲覧数 6617

【ESP32】雨降り検知装置を作ってみた!

【ESP32】雨降り検知装置を作ってみた!

はじめに

皆さんこんにちは!MOZI電子工作です。
ところで、皆さんは家にいるとき突然雨が降ってきて、洗濯物を干しているのに濡れてしまった!ということはありませんか?そんな時に役立つのが、雨降り検知装置!
ということで今回は、ESP32を使った雨降り検知装置を作っていきます!

構想

雨を検出するのは水滴センサ(下のようなもの)を使います。この雨センサはうねうねしたパターンの書いてある基板に水を垂らすとデジタルアウトピンから出力されるものです。
Amazon.comより
それで、雨を検出する装置を作るのでこれでいいんですが、せっかくなので外気温を測定する機能も付けようと思いました。
外の気温と湿度を両方図ることができる温湿度センサを使います。
Amazon.comより
回路図は下の図です。
回路図
ブレッドボード図
ということでハードウェアはこんな感じですが、ソフトウェアはどうするかというと、まず雨の警告は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\">気温&emsp;<span class=\"numbers\" id=\"temp\">"); client.println((String)temp); client.println("</span>℃<br>湿度&emsp;<span class=\"numbers\"id=\"humid\">"); client.println((String)hemi); client.println("</span>%<br>雨&emsp;&emsp;<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を使用しました。
Fusion360で設計
こんな感じです。

一度プリント失敗しましたが、ノズルのつまりをとるとプリントできました。

プリント完了

ACアダプタの設計ミスをしていますが、気にしない気にしない...
防水はグルーガンで行いました。ガバガバだと思うので秋月の部品と同梱してある、あのシリカゲルも一応入れておきました。
無理やり穴をふさいだ

動かしてみる

いざ、動かしてみようと思います。
スマホのブラウザ
で特定のIPアドレスを開くと、、、?
表示成功
はい、動きましたね!
少しUIは崩れていますがしっかり表示できているようです。

まとめ

完成!
いかがだったでしょうか。
LINEでの通知はできませんでしたがかなり便利になったと思います。
ESP32にかなり可能性を感じました!
最後まで読んでいただきありがとうございました!
外に設置してみました
P.S.先日雨が降ったのですが安定して動いているので防水はちゃんとできているようです。

1
MOZIのアイコン画像
電子工作してます。 主にArduinoやRaspberry piや3Dプリンターなどでいろいろ作ってます。 いろいろ書いていく予定です。よろしくお願いします!
  • MOZI さんが 2021/02/20 に 編集 をしました。 (メッセージ: 初版)
  • MOZI さんが 2021/02/27 に 編集 をしました。 (メッセージ: 追記の追加)
  • MOZI さんが 2021/02/27 に 編集 をしました。
  • MOZI さんが 2021/02/27 に 編集 をしました。
  • MOZI さんが 2021/12/07 に 編集 をしました。 (メッセージ: 記事の種類・ライセンスを設定しました。)
ログインしてコメントを投稿する