マイコン(Arduino)を用いた"進化する"お風呂タイマー

今回は不必要な機能満載のお風呂タイマーの製作を報告いたします。これまで我が家ではお風呂のお湯張りと同時にキッチンタイマーをセットして、満水をチェックしておりました。しかし、先日、タイマーをセットし忘れて1時間近くお湯を流しっぱなしにするという失敗をしてしまいました。そこで、お湯を入れ始めたら自動的に時間をカウントし、警報音で知らせるシステムを製作することといたしました。


水位を直接検出するのは良い方法か?

市販のお湯張りセンサーや、電子工作で作成記事が紹介されているお風呂スイッチは水位を測定して満水を知らせるタイプが多いようです。しかしながら、浴室は高湿度環境であり、電子機器を設置して長期的な運用を行う上で好ましい状況とは言えません。また、お風呂のお湯を入れるたびに水位計を取り付けて、満水になったら取り外してお風呂に入る、というのも大変不便です。そこで、給湯機の動作を監視するシステムを採用いたしました。つまり、お湯の量を見るのではなく、湯沸かし器が連続動作している時間を計測することにしました。 これにより連続的な給湯を監視し、ブザーなどで知らせることが可能となります。このシステムは、お風呂の栓を忘れるといった失敗を防ぐことはできませんが、お風呂場に何も設置しないでお湯張りを監視することができるという大きな利点を持ちます。

調べてみますと、我が家では給湯の温度を一元的に管理するシステムが設置されており、この表示器から、お湯が出ている状況を感知することといたしました。周りの友人の話を聞く限り、このような給湯表示器は家庭用として一般的であるようです。具体的には室内の壁に設置された給湯の表示器から信号を取り出すこととしました。この表示器から何らかの電圧出力を取り出そうと考えておりましたが、残念ながらパネルを完全に外すことができませんでした。そこで、上から2番目の給湯確認のためのLED(赤)の点灯をフォトトランジスタで検出することといたしました。目に見える赤色ですから、可視域の普通のフォトトランジスタや明るさ検出素子として有名なCdSが使用できるはずです。


給湯表示器の外観。上から2番目のLED(赤)の点灯を検出する。

このLED点灯検出用の回路をプレッドボード上で作成しました。左上にある半透明の緑色をしている素子がフォトトランジスタ(NJL7502L)です。人間の視感度特性に近く、赤色の検出には問題は生じません。この回路では、フォトトランジスタに光が照射されている時に限り(検知する明るさのしきい値は回路に含まれる抵抗値で調整する必要があります)、右の赤色LEDに電流が流れるようになっています。この信号からマイコンのArduinoの電源をon/offすれば、お湯が出ている間だけArduinoを走らせ、時間を計測して、警告音を発することができます。

Arduino用に少し多めの電流を取りたいと考え、スイッチとなるフォトトランジスタの電流を増幅するトランジスタ(2sc1815)の後ろにフォトモスリレー(HSR312)を接続しています。トランジスタ無しでHSR312に直接フォトトランジスタの電流を流しこんでも問題なく動作すると思います。明るさの検出限界はR2で調整可能です。この部分を小さいRと可変抵抗の直列にしておくのも良いかもしれません。自作される場合の配線は、データーシートを参照してください。


プレッドボード上で構成したLED点灯検出部


フォトトランジスタへの光がoffの状態


明るさ検出部の回路

ドアチャイム用の通信機を用いて、給湯状態を無線転送

上述の光スイッチでArduinoのスケッチ(プログラム)を書いてブザーへの出力で万事OKと考えておりましたが、給湯表示機の近くに大きい機器を置くと邪魔になるとの家族の反対を受けました。また、Arduino用の電流を電池からだけ取るのは、長期間の運用という意味でも好ましくありません。

そこで、給湯表示器には、電池駆動の小さな無線発信機を設置し、給湯状態のon/offを1 bitで送信して、離れたところに受信機とAruduinoからなるシステムを設置することとしました。無線ですので、受信機側の接地場所は選びません。これにより、電池の持続時間を大幅に伸ばした装置を作成することが可能となりました。Arduinoの電源はACアダプタから取ることにします。このシステム構築のために用いた無線機はドアチャイムとして市販されている機器でHoltekのHT12E(エンコーダ、発信側)とHT12D(デコーダ、受信側)という通信用のICを用いたものとなります。この機器の外観を以下の写真に示します。通信販売で2000円程度でした。データシートによりますと発信器のスイッチがonの時には常に受信機のICのVDD端子がHIGH状態となりますのでこれをArduinoで検出すればお風呂の給湯機のLEDが点灯状態であることを無線で検出できることになります。


分解する前の無線ドアチャイムの外観


発信器部分:9V電源仕様です。


受信機部分4.5V仕様です。

追記(2012/1/22):無線接続にXBeeを用いた改良版では、フォトトランジスタの出力を3.3 VのDCDCアップコンバーターに入れてXBeeへの電源をon/offしています。

発信器側の電源改良

このような改造において電源に問題が生じました。発信器部分は9 Vの電源で回路が設計されております。しかし、この電池を入れてしまうと、余分なスペースがなく、明るさ検出量の回路を組み込むことができなくなります。調べたところ、HT12Eの仕様は2.4V以上となっておりました。そこで、9Vの角型電池(006P型)のスペースの半分に1.5Vの単三電池設置し、残りの半分に1.5Vを5Vに昇圧する回路と明るさ検出回路を組み込んで使用することとしました。発振時に流れている電流は5 V時に10 mA程度でしたので、昇圧とロスを考慮して1.5Vで40 mA程度、2000 mAhの電池で50時間の連続発振ができることがわかります。一日のうちで給湯機がonとなっている時間はトータルでも20分程度ですので、約150日間程度の 運転が期待できます。やや少ない気もしますが、電池の自己放電も考えると半年に一回交換するような使用環境は悪くないと考えられます。もう少し電池の持ちを良くするには、発信器のケースを大型化して単三電池2本の仕様にするのも良いかもしれません。

1.5Vから5Vへの昇圧

1.5 V電池を電源に5 Vに昇圧して使用するために、HT7750Aを用いた、秋月電子の昇圧型DCDCコンバーターを用いました。Step Upタイプですが、どんなに低い電圧でも動作するわけではなく、電源が1.5 V時には5V 25 mAまでしか取り出せないとなっています。この電流値でも上述の発信器の動作には十分です。また、このDCDCコンバーター回路は4番端子がCEとなっており、この端子に5 Vが入っている時にon、GNDが入っている時にoffとなるようなスイッチ機能がついています。これにより、給湯表示器のLEDがonの時のみに昇圧回路をonとすることができます。つまり、通常の電源off時には5Vへの昇圧回路の消費電力を節約することができます。待機電力は電池の自己放電程度であると考えられます。

最終的には以下のような回路を用いました。CE端子への入力に注目してください。470KΩと100uFは時定数が十秒単位となる遅延回路です。これは、短い時間だけお湯がonとなったりoffとなったりした場合の変化を意図的に見逃すためのものです。LEDがonの時にはフォトトランジスタはonとなり、数kΩの抵抗値となります。この時、470KΩの抵抗のために4端子にはほぼ5Vが入り、昇圧回路がonとなります。他方、フォトトランジスタに光が照射されない場合には流れる電流は1uA程度となり、この場合には、4端子はGNDに落とされ、昇圧回路はoffとなります。


昇圧回路の構成(実態図)


フォトトランジスタ部分の回路


センサー内部(試作中の写真であるため、回路にトランジスタを含む)


給湯表示器への発信器の設置状況(赤LEDにより、白いゴムで隠されたLEDの 動作状況も確認できる。)


受信部とソフトウェア(マイコンの設定)

受信部分からの出力は以下の基板のVT端子から取ります。発信器がonの時にこの端子に5Vが出力されます。


受信機の信号出力

この出力をArduinoのanalog(0)に入れることにしました。Digital inの方がプログラムは簡単ですが、waveshiledでdigital入出力のほとんどを使っていることと、端子の配置が近いことからanalogReadを用いました。

最終的な配線の写真は以下の通りです。ACアダプタを用いているので過電流が流れることはないですが、安全のためにヒューズを入れています。右側に見えるのは5VのDCプラグとブザー、外部スピーカー用のイヤホン出力端子です。スピーカーは質感の良いものを探し、DENONの超小型コンポ単品を見つけました。こちらはヤフーオークションで1500円ほどで購入できました。


受信部の信号出力端子


スピーカーと受信器外観写真

Arduinoを使って、時間を計測するのはmillis();の指令で簡単にできます。これでブザーを鳴らすだけでは面白みがないと考え、任意の音声を再生するようにしました。ここで用いたのがArduinoのwaveshieldというSDカードからファイルを読み取ってwavの音声ファイルを再生するキットです。 詳細は Arduino wave shield をご参照ください。これは、振動センサと組み合わせて変な音が出る打楽器を作ったりできる面白いボードです。今回は、最初は電子ブザー音として、10回程度の給湯で乱数を用いてランダムに給湯警報機の"レベル"をアップさせ、警告の音声を変更させる仕様としました。

今回用いた音声はレベル順に
  1. 羊(メーメー)
  2. 猫(ニャーニャー)
  3. 鶏(コケコッコー)
  4. 多数の鶏(コケコケコケコケ)
  5. カラス(カーカー)
  6. 鳥(ピーチピーチク)
  7. 犬(ウー、ワンワン)
  8. 虫の音(リーンリーン)
  9. 蝉(ひぐらし)(かなかなかなか)
  10. エンジン音(ブルンルンルルルル)
  11. 人の声(リーチ!)
  12. 人の声(ツモ!)
  13. 人の声(終了です!)
です。

音声はゲーム用にフリーの音源を作製している方のサイトで配布されているものを使用しました。実際に動作させてみましたが、電子回路につながれたスピーカーから音声が出るのは非常に楽しいものでした。

作製したArduinoのスケッチ(プログラム)の一部を以下に示します。音声出力に関するスケッチは公開されており、上述のwaveshieldのサイトからダウンロードできます。プログラムはまだまだ洗練されていませんが動作は確認できています。部分的に抜き出して使用していただければ幸いです。


////buzzerWAV is sound Wav File
void BuzzerWAV(){  //場合分けにより音声を選択して流すサブルーチン。
    //levelがcase の後の数値により場合分けを行う。
  switch (level) {
  case 0:
    playcomplete("beep.WAV"); //音声を再生。
    delay(2000);  //2000msec待つ。
    break;
  case 1:
    playcomplete("1.WAV");
    delay(2000);
    break;
  case 2:
    playcomplete("2.WAV");
    delay(2000);
    break;
    //ここにその他の音声を出力させるための同様のコード。
  default:  //defaultはcaseに当てはまらない場合。
    BuzzerOne();
  }
}

void BuzzerAlarm(){    //BUZ1に接続されたブザーでブブブ、という短い警告を連続するサブルーチン。
  for (int i=0; i<=2; i++){
    digitalWrite(BUZ1, HIGH);
    delay(100);
    digitalWrite(BUZ1, LOW); 
    delay(100);
  }
}

void BuzzerOne(){   // 上と同じく、ブ、という短い警告音を発するサブルーチン。
  digitalWrite(BUZ1, HIGH);
  delay(100);
  digitalWrite(BUZ1, LOW); 
}

void LevelCheck(){//  現在のレベルを調べて、レベルを上げるか否かを決定するサブルーチン。
  randNumber=random(100);  //100までの乱数を発生。
  if(randNumber<10){  //0.1の確率でレベルアップ
    level=++level;  //level=level+1
    EEPROM.write(2,level);   // write down level //AruduinoのROMへレベルを書き込み。
    playcomplete("20.WAV");  //Level Up Soundの再生
    delay(2000);
    time2=millis();//時間の更新
    delay(100);
  }
  //Level UP if End
  ///////////////////////////////////////////////
}

void loop(){////プログラム本体
  //level=0; //レベルを0に設定(プログラム書き込み時1回のみ実行)
  // EEPROM.write(2,level); //ROMへ書き込み。(プログラム書き込み時1回のみ実行)
  
  /////WaitingCode///給湯されていない時のループ。
  do {
    delay(1000); //1秒待つ。(1秒ごとに測定)
    RFin=analogRead(0); // RF signal check
  }  while(RFin<400); //RFin=analogRead(0)端子が5*400/1024 V以上となるのを待つ。
  ///////////////////
  
  time1=millis(); //ループを脱した時(発信器がonを出力した時)の時間を検出
  //この時間をtime1とする。

  // start main program
  while(RFin>400){   //
    time2=millis(); //時間の計測開始。
    delay(1000);
    while((time2-time1) < WaitFuroMsec){   //time1から数えた時間がwaitFuroMsecに達するまで繰り返す。
          //////RF singnal check////
          RFin=analogRead(0); // RF signal check
          if(RFin<400) {break;} //電圧が下がっていれば計測を終了してdo loopに戻る。
      delay(1000);
     time2=millis();  //時間の更新。
      //////////警告音を発する時間の7割に達した時にレベルチェックをする/////
      if((time2-time1)>(WaitFuroMsec*0.7) &  & (time2-time1) < (999+WaitFuroMsec*0.7) ){
        level=EEPROM.read(2);//レベルを読む
        if ( level>12 ){level=0;}//最高レベルの時には0に戻す。
        delay(1000);
        LevelCheck();  //レベルチェック。
      }
          time2=millis();//現在時間の読み直し
      if((time2-time1)>(WaitFuroMsec*0.7)){BuzzerWAV();}//満杯になる時間の7割以上で音声を出力。
      /////////
    }  // While End
    /////////////////////////
    while((time2-time1) > =WaitFuroMsec){    // 満杯になった後(WaitFuroMsecに達した後)は一秒ごとに常に警告音を発する。
      BuzzerAlarm(); 
      delay(1000);
      //////RF singnal check////
      RFin=analogRead(0); // RF signal check //発信器からのシグナルが無くなったときに警告音ルーチンから脱する。
        if(RFin<400) {break;} 
         time2=millis();  //時間の更新。
    } // While End
    //////////////////////////
     RFin=analogRead(0); // RF signal check
      if(RFin<400) {break;} //発信器からのシグナルが無くなったときにDo loopに戻る。
  }
}  ///void loop end

以上が、今回作成したお風呂タイマーです。 動作機構と機能をまとめますと、

  1. 給湯表示器のLEDを検知する
  2. ドアチャイム(HT12E)により給湯状態onを無線発信する
  3. HT12Dにより給湯状態onを受信する
  4. ArduinoにてHT12Dの受信状態を検知する
  5. 約13分の給湯時間の7割まで待つ
  6. ROMに記録されたレベルをチェックする
  7. レベルに応じた音声をSDカードから読み取りスピーカーに出力
  8. 13分以上でブザーの警告音を発する

となります。音を出す点と無線の送受信がやや複雑な点で時間がかかりました。 装置は正常に動作しており、”メーメー”などといった楽しい 声を出しています。我が家では「電気子羊」(発信器)と 「電気親羊」(受信機)と呼んでおります。


宣伝↓

戸田システムウェア

ここで公開するアイデア/装置は安全性を保障しておりません。 用途に応じた設計を行い、十分な安全検査を行ってからご利用ください。 プログラムの二次配布はご遠慮ください。 本サイトの情報の営利目的での利用はご遠慮ください。 本サイトの内容の無断転載を禁じます。© 2009,2012 TYK