換気扇の自動化
家のトイレは換気扇がついているけど冬は常にオンだと寒い。北海道ではトイレにも温水暖房がついているのは当たり前なので常に換気状態だと無駄に熱を外に出してしまう。人が入った時に換気、人がしばらくいない状態でも定期的に換気ができればいいなぁと思い、それを自動化してしまおうという記事です。とりあえず必要な物をリスト化してみました。
- マイコン : ESP8266でいきます
- リレー : 電磁リレーorソリッドステートリレー
- 人感センサー : 焦電型人感センサー
まぁこれだけ。とてもお手軽。ESP8266は余ってるからです。WIFIネタじゃないのでArduinoでもいいです。プルアップ・プルダウン抵抗とかレギュレーターとかは省きますので適宜用意してください。
ソリッドステートリレーを使う
まず、リレーの選定です。
モジュール化されたリレーにはご存じの通り主に2タイプの方法が主流かなと思います。
- 電磁リレー : JQC-3FF-S-Z搭載品など
- ソリッドステートリレー(SSR) : G3MB搭載品など
1は以前に遊んだ時の記事があります。
要は電磁石でスイッチをオンオフする方式です。物理接点がありカチカチ音が鳴ります。また接点に耐久性があります。対して2のSSRは、読んだまんまで半導体素子でオンオフするリレーで高速なスイッチングができるとか音がしないなどの利点がありますが、リレー自体が発熱があったりなど欠点もあります。下のサイトがわかりやすいです。
電気スイッチのオンオフ用途であれば、JQC-3FF-S-Z搭載の電磁リレーモジュールを用いてESP8266で動かしてもよかったんですが、もうモジュール化されて販売されていて、そっちの方がスマートだし綺麗だし・・・モチベーションが上がりません。その前に、この製品はIoTで使うこと前提なので技適警察に怒られます。
というわけで、あまり使われないSSR+ESP8266で組んでいこうと思いました。
SSRはAmazon国内発送だと700円~1000円でちょっとお高いので、時間があればAliExpress等を使って購入したほうが100円程度で買えるのでよさげです。配送期間は13~20日って大体なってますが「早くて13-20日」です。余裕で遅れますし届かないこともあります(笑)。来ない場合は、セラーにチャットで「ゴルァ!」して反応なければ「Dispute」すれば、大体の場合返金されます。2020年3,4,5月はコロナの影響で物流が混乱してて1-2か月放置なんてザラなんで優しい目で見守ってください。あ!あと、どこから届いてもそうですが届いたらまず
IPAなどでビチャビチャに消毒・清掃します!
時期が時期ですからね・・・。輸送にに一か月以上かかってますので商品内のウイルスは死んでるとは思いますが、色々なものと混ざって運ばれてるので外装ははがしてすぐビニル袋にいれてポイします。
僕はコロナ前に、興味本位のみでAliExpressから買ったやつがあるのでそれを使います。ちなみに「High Trigger Level」と「Low Trigger Level」の2タイプあります。そのまんまでして、CH1がHighの時にONか、Lowの時にONかの違いなのでスケッチ上でどうにでもなると思います。僕のは「High Trigger Level」なのでそれで説明していきます。
このモジュールのらしい回路図がありました。リレー動作電源は5v。10kΩの抵抗も入っていて、スイッチング回路が入っているのでCH1はESP8266の3.3vに直結でよさそうです。電源に3.3vだと動作しないか不安定になりそうです。
焦電型赤外線人感センサー
人感センサーにもいろいろあって、赤外線を使ったもの、超音波を使ったもの(ドップラーセンサーや測距センサー)、レーザーを使ったものがあります。この中で一番スタンダードであろう焦電型赤外線人感センサーを使っていこうと思います。ドップラーセンサーもあったけどドアの向こうの動体も検知してしまうし焦電型赤外線センサーが一番使いやすい。むかーしに秋月さんで購入して余っていたSB412を箱から見つけました!
代替品として、アマゾンなどでAM312で検索する出てくるSB412に似てるやつ。
AliExpressだと送料込みで100円/個ちょいぐらい。写真から察するにセンサーのTimeピンがない。ON持続時間が2(実際は2.3)秒固定というところをみると、センサー内部でGNDに直結されてるみたい。改造して持続時間延長は無理っぽいかなぁ。
用途にもよるだろうけど、サイズ優先ならAmazonのやつ(AM312)で時間調整が欲しいなら秋月さん(SB412)かな。まぁ送料の兼ね合いもあるけど。AliExpressだと送料込みで100円ちょいぐらいですね。
今回はON時間は最短固定(2.3秒)で使うのでどちらでもいいです。データシートから電圧は3~12Vで、HIGH出力は3Vです。R2の抵抗に0~100Kって書いてあるけどどういうことなんでしょ?ついてる?つけてね?ってこと?不安ならESP8266との接続に10KΩぐらいの抵抗を挟めていたほうがイイかな。
組み立て
上はスケッチを書き込んだ後で動作させる回路図です。RIは電流制限抵抗。R2~R5はプルアップ抵抗、R6はプルダウン抵抗です。RSTにはリセットスイッチもつけときました。抵抗は3.3kでも10kでも、その間でもいいです。
書き込むときは以前説明した治具でもいいですし、治具自体を上の回路に組み込んで、USBシリアル変換(FT232など)に接続するコネクタを基板につけてももいいと思います。
あれ?SB412ついてないねw。3ピンデュポンでSSRが接続されている上の3pinに接続します。SB412は人感センサーが反応しやすいように別の箱を3Dプリンタで作って納めています。
なんだか、スマートにしようと思ったら結局ゴチャゴチャ。熱集収縮チューブの中にプルアップ抵抗とプルダウン抵抗をしまって、前に作った治具と差し替えで動くようにしたけどなんかダサい・・・。LEDがついているけど、これはSSR動作確認用にGPIO13に抵抗を介して接続している机の上に転がってた抵抗を用いたので何Ωかはわからないけど適当でいいんだ!!SSRモジュール自体にもLEDはついているけど、これ見えにくいんすよ。
ならGPIO4につければいいじゃん
そう思います。このLEDはSSR確認用とか、人感センサー確認用とか、スケッチ動作確認とか・・・いろいろ使ってたので別ピンにしたのです。許してください。
スケッチ
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 75 76 77 78 79 |
#include <time.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> const unsigned long Interval_sec = 3 * 60; //SSRオン持続時間秒 3分 const unsigned long auto_int_sec = 30 * 60; //自動運転間隔(最後の動作から何秒後に自動で運転するか) 30分毎 const int ledPin = 13; // LED接続GPIO const int pin_sb412 = 5; // SB412接続GPIO const int pin_ssr = 4; // SSR接続GPIO int d_val; // SB412の値保持 int now_state = LOW; // Loop内で判断された状態 unsigned long on_time; //オンのリミット時間 int setted_state; //現在のセット状態を保存 void set_state(){ digitalWrite(pin_ssr, now_state); digitalWrite(ledPin, now_state); setted_state = now_state; } void setup() { ESP.wdtDisable(); Serial.begin(115200); Serial.println(""); pinMode(pin_sb412, INPUT); // SB412のピンを入力に設定 pinMode(ledPin, OUTPUT); // LEDのピンを出力に設定 pinMode(pin_ssr, OUTPUT); // SSRのピンを出力に設定 set_state(); // LOWに設定 on_time = millis(); delay(1000); // 一瞬ONになるを回避するため } void loop() { ESP.wdtFeed(); d_val = digitalRead(pin_sb412); unsigned long now_time = millis(); if( d_val != 0 ){ //人感センサー検知中なら on_time = now_time + Interval_sec * 1000; //リレーオン時間の延長 Serial.print(now_time); Serial.println(",人感センサー検知"); } if(now_time<=on_time){ //リレーオン時間内 now_state = HIGH; Serial.print(now_time); Serial.print(",残 "); Serial.print((on_time-now_time)/1000); Serial.println("秒"); }else{ //リレーオン時間外 if(now_time-on_time>=auto_int_sec*1000){ //リレーオフの状態が自動運転間隔時間以上経過したらリレーオン時間延長して自動運転する on_time = now_time + Interval_sec * 1000; now_state = HIGH; Serial.print(now_time); Serial.println(",自動運転開始"); }else{ now_state = LOW; } } //状態の変化があればset_state()で状態を変更する if(now_state!=setted_state) set_state(); ESP.wdtFeed(); delay(1000); } |
ローカル変数でいいものがグローバル変数になってみたり、set_state()内でsetted_stateの判断したほうが綺麗だとかコピペして思いましたが、サクッと書いてこんな感じになりました。ESP8266を使ってますがWifiにつないでないので技適がアレなやつでも使ってもいいんじゃないですかね。
技適がOKなESP8266を使えば、一定時間人感センサーが動作しなかったらメールで通知する独居老人・一人暮らし家族の見守り機能とかもつけれるんじゃないでしょうか。でも・・・
人のいないトイレで反応したら怖いよね….