toraのアイコン画像
tora 2021年02月23日作成
製作品 製作品 閲覧数 4344
tora 2021年02月23日作成 製作品 製作品 閲覧数 4344

エアコンを自動で制御する装置

エアコンを自動で制御する装置

1.きっかけ
私の住んでいる地域は夏と冬の寒暖差が激しいです。夏は切タイマーをして寝るのですが、それでも朝は室温が30℃近くになることもあり熱中症の危険があります。
そこでArduinoを使ってエアコンを自動でつける装置を小型化と作りやすさを重視して製作しました。

2.機能
部屋の中の温度が設定した温度(例えば27℃)を超えたとき、赤外線LEDから冷房をつける信号をエアコンに送ります。逆に、部屋の中の温度が設定した温度(例えば10℃)を下回ったとき、暖房をつける信号を送ります。
また、節電のため人感センサーにより部屋の中に人がいるときだけこれらの動作をするようにしました。

3.回路図
キャプションを入力できます
三端子レギュレータにより、ACアダプター(DC9~12V)からマイコンを動かすための5Vをとっています。赤外線LEDには約70mA流れるように電流制限用の抵抗値は51Ωに設定しました。このときの抵抗の消費電力は計算上0.26Wになるので、1/2Wの炭素皮膜抵抗で十分なはずです。

4.主な部品
・マイコン:https://akizukidenshi.com/catalog/g/gI-12774/
・三端子レギュレータ:https://akizukidenshi.com/catalog/g/gI-08678/
・焦電型赤外線センサーモジュール:https://akizukidenshi.com/catalog/g/gM-14064/
・FET(2SK4017(Q)):私のお気に入りのMOSFETです。
https://akizukidenshi.com/catalog/g/gI-07597/
・赤外線LED:https://akizukidenshi.com/catalog/g/gI-04313/

5.製作
ブレッドボード上で動作確認をします。
キャプションを入力できます

基板を作成します。
キャプションを入力できます

筐体を作成します。ケースは「いつか使うだろ~」と一年半前に買ったタカチのTW5-3-10Bを使いました。
キャプションを入力できます
部品同士で干渉したので基板の端をカットしました。
スイッチの部分はホットボンドで手抜きをしています()

完成した写真がこちらです。
キャプションを入力できます

6.プログラム
まず、エアコンのリモコンの信号をArduinoに取得させる必要があります。ネットで調べてみるとIRremoteというライブラリを使っている方が大半なのでそれで試してみました。

結果:だめです

リモコンの信号が長すぎたようです。というか家にある大半のリモコンでエラーが出ました()
仕方ないので、こちらのサイトのプログラムを使わせて(パクらせて)もらいました。
受信:https://www.hiramine.com/physicalcomputing/arduino/irreceiver.html
送信:https://www.hiramine.com/physicalcomputing/arduino/irsender.html

室温が27℃よりも高いとき、冷房をつけます。室温が25℃を下回るまでは信号は出さず、LEDを点滅させます(ヒステリシス)。逆に室温が12℃よりも低いとき、暖房をつけます。室温が15℃を上回るまでは信号は出さず、LEDを点滅させます。
せっかくなので割り込み処理でスイッチを押すとエアコンを消せるようにしたつもりですが、たまに失敗してしまいます(なんでだろう?)。
さらに、外出中に勝手にエアコンをつけるのは電気代がもったいないので、人感センサーが反応していない場合はこれらの動作はしないようにしました。

/************自動エアコン制御装置のプログラム**********/ #define led 5 //LED #define sw1 2 //スイッチ1 #define sw2 3 //スイッチ2 #define IRled 11 //赤外線LED #define motion 12 //人感センサ #define temp A5 //温度センサ /****送信信号*****/ // 暖房をON int ARRAY_HIGHLOW1[] = { 3872, 1800, 548, 396, 548, 1344, 548, 392, 528, 1364, 548, 396, 552, 1332, 692, 256, 560, 1332, 548, 400, 548, 1336, 556, 392, 548, 1340, 552, 1336, 556, 388, 556, 1336, 552, 396, 552, 1332, 556, 1336, 552, 1340, 552, 1340, 552, 392, 552, 392, 548, 1344, 548, 1336, 556, 388, 552, 396, 552, 392, 552, 392, 548, 1344, 548, 388, 560, 388, 552, 388, 556, 396, 544, 1340, 556, 388, 556, 388, 552, 396, 552, 388, 552, 396, 548, 392, 556, 1336, 556, 388, 552, 392, 552, 396, 544, 1344, 548, 396, 552, 388, 552, 396, 548, 1340, 552, 392, 652, 300, 540, 400, 548, 392, 548, 1344, 548, 392, 552, 392, 552, 392, 552, 400, 544, 396, 572, 364, 552, 396, 548, 396, 552, 392, 552, 388, 556, 392, 528, 416, 552, 396, 548, 1336, 552, 396, 548, 392, 552, 392, 552, 388, 560, 388, 552, 392, 552, 388, 552, 396, 552, 388, 556, 1336, 552, 392, 552, 1336, 580, 368, 552, 392, 552, 388, 556, 388, 552, 392, 660, 284, 552, 404, 544, 388, 552, 340, 604, 396, 552, 1332, 560, 388, 580, 1312, 736, 1148, 556, 1336, 556, 1336, 548, 1344, 548, 396, 552, 388, 556, 392, 576, 364, 556, 392, 548, 1344, 548, 388, 560,}; // 冷房をON int ARRAY_HIGHLOW2[] = { 3868, 1792, 560, 392, 552, 1340, 552, 392, 548, 1372, 516, 396, 528, 1360, 532, 416, 552, 1340, 548, 392, 548, 1348, 544, 396, 552, 1340, 524, 1364, 528, 416, 552, 1340, 524, 416, 528, 1364, 552, 1340, 548, 1344, 548, 1344, 524, 416, 548, 400, 520, 1368, 524, 1364, 548, 396, 552, 392, 528, 416, 552, 388, 556, 1368, 520, 396, 520, 420, 552, 392, 548, 400, 524, 416, 548, 396, 552, 1340, 552, 388, 552, 396, 524, 420, 548, 396, 548, 1344, 520, 420, 552, 392, 552, 388, 552, 1340, 552, 392, 556, 388, 552, 396, 548, 392, 552, 1340, 528, 412, 556, 392, 548, 396, 548, 1344, 628, 312, 552, 392, 524, 420, 548, 396, 576, 368, 548, 396, 548, 396, 524, 420, 548, 392, 532, 412, 552, 396, 524, 416, 528, 416, 552, 1340, 528, 416, 528, 412, 556, 396, 544, 396, 548, 396, 548, 396, 548, 392, 528, 420, 552, 388, 556, 1336, 552, 396, 548, 1340, 548, 396, 548, 400, 544, 392, 548, 400, 548, 392, 552, 396, 548, 392, 528, 416, 552, 388, 560, 396, 544, 1368, 520, 392, 528, 1396, 520, 1340, 548, 1368, 528, 1336, 552, 1340, 552, 396, 544, 388, 560, 388, 552, 1368, 524, 388, 556, 1340, 548, 1340, 552, }; // エアコンをOFF int ARRAY_HIGHLOW3[] = { 10444, 3868, 1796, 556, 392, 552, 1336, 552, 388, 532, 1360, 552, 396, 548, 1340, 548, 340, 608, 1340, 548, 392, 524, 1364, 552, 348, 600, 1336, 532, 1360, 552, 392, 528, 1360, 532, 416, 524, 1364, 528, 1364, 524, 1364, 548, 1344, 552, 392, 552, 392, 548, 1344, 552, 1336, 528, 420, 548, 396, 520, 420, 552, 340, 580, 1364, 548, 392, 528, 420, 548, 392, 528, 416, 552, 1340, 548, 396, 528, 412, 552, 396, 548, 396, 548, 396, 548, 392, 584, 1308, 552, 376, 544, 416, 524, 416, 528, 420, 524, 1368, 524, 420, 548, 396, 552, 1336, 548, 296, 724, 320, 548, 392, 532, 416, 552, 1336, 628, 316, 552, 392, 548, 400, 548, 392, 528, 420, 548, 368, 552, 412, 548, 400, 548, 396, 524, 420, 548, 392, 532, 416, 524, 416, 552, 1340, 552, 388, 532, 416, 656, 284, 688, 260, 524, 420, 548, 396, 552, 392, 572, 372, 524, 420, 548, 1344, 548, 392, 548, 1344, 548, 396, 524, 416, 528, 416, 552, 392, 552, 396, 544, 368, 552, 420, 524, 416, 532, 416, 552, 392, 548, 1344, 528, 412, 528, 1364, 548, 1344, 552, 1340, 548, 1340, 548, 1340, 528, 416, 552, 392, 528, 416, 712, 1180, 524, 1368, 524, 1364, 552, 392, 528, }; void setup(){ pinMode(led,OUTPUT); pinMode(sw1,INPUT_PULLUP); pinMode(sw2,INPUT_PULLUP); pinMode(IRled,OUTPUT); pinMode(motion,INPUT); pinMode(temp,INPUT); attachInterrupt(0,sendSignal3,FALLING); } int val,p; float cel; void getCel(){ //温度の取得 val = analogRead(temp); cel =(float)val*500.0/1024.0-62.0; //セルシウス温度に変換 } void getMotion(){ p = digitalRead(motion); } /******赤外線送信******/ int iTimeLength; unsigned long ulTimeStart; int iCountHighLow1 = sizeof( ARRAY_HIGHLOW1 ) / sizeof( ARRAY_HIGHLOW1[0] ); int iCountHighLow2 = sizeof( ARRAY_HIGHLOW2 ) / sizeof( ARRAY_HIGHLOW2[0] ); int iCountHighLow3 = sizeof( ARRAY_HIGHLOW3 ) / sizeof( ARRAY_HIGHLOW3[0] ); void sendSignal1(){ //暖房ON for(int iIndexHighLow=0;iIndexHighLow < iCountHighLow1; iIndexHighLow++ ){ iTimeLength=ARRAY_HIGHLOW1[iIndexHighLow]; ulTimeStart=micros(); do{ digitalWrite( IRled, 1 - (iIndexHighLow % 2) ); // iIndexHighLow : 0はhigh, 1はlow digitalWrite( led, 1 - (iIndexHighLow % 2) ); delayMicroseconds(8); digitalWrite(IRled,0); digitalWrite(led,0); delayMicroseconds(7); } while(iTimeLength>micros()-ulTimeStart ); } } void sendSignal2(){ //冷房ON for( int iIndexHighLow = 0; iIndexHighLow < iCountHighLow2; iIndexHighLow++ ){ iTimeLength = ARRAY_HIGHLOW2[iIndexHighLow]; ulTimeStart = micros(); do{ digitalWrite( IRled, 1 - (iIndexHighLow % 2) ); digitalWrite( led, 1 - (iIndexHighLow % 2) ); delayMicroseconds(8); digitalWrite( IRled, 0 ); digitalWrite(led,0); delayMicroseconds(7); } while( iTimeLength > micros() - ulTimeStart ); } } void sendSignal3(){ //エアコンOFF delay(10); for( int iIndexHighLow = 0; iIndexHighLow < iCountHighLow3; iIndexHighLow++ ){ iTimeLength = ARRAY_HIGHLOW3[iIndexHighLow]; ulTimeStart = micros(); do{ digitalWrite( IRled, 1 - (iIndexHighLow % 2) ); digitalWrite( led, 1 - (iIndexHighLow % 2) ); delayMicroseconds(8); digitalWrite( IRled, 0 ); digitalWrite(led,0); delayMicroseconds(7); } while( iTimeLength > micros() - ulTimeStart ); } } void loop(){ getMotion(); getCel(); delay(100); if(p==1){ //人感センサーが反応しているとき if(cel>27){ //室温が27℃よりも高いとき digitalWrite(led,1); delay(200); sendSignal2(); //冷房ON while(cel>25){ digitalWrite(led,1); //LEDを点滅 delay(80); digitalWrite(led,0); delay(3000); getCel(); //温度を取得 } } }else if(cel<12){ //室温が12℃よりも低いとき digitalWrite(led,1); delay(200); sendSignal1(); //暖房ON while(cel<15){ digitalWrite(led,1); //LEDを点滅 delay(100); digitalWrite(led,0); delay(4000); getCel(); } }else{ //人感センサーが反応していないとき、LEDを点滅 digitalWrite(led,1); delay(100); digitalWrite(led,0); delay(1000); } }

7.最後に
1月下旬から作り始めたのですが、完成した今(2月末)は暖かくなってきて今季は実際に動いているところを見られず、少し残念です。夏にちゃんと機能してくれることを楽しみにしています。

8.参考
http://meganezumi.seesaa.net/article/409749989.html
https://www.hiramine.com/physicalcomputing/arduino/irreceiver.html
https://www.hiramine.com/physicalcomputing/arduino/irsender.html

2
toraのアイコン画像
とらごろうです。主にArduinoを使った電子工作をします。
  • tora さんが 2021/02/23 に 編集 をしました。 (メッセージ: 初版)
ログインしてコメントを投稿する

投稿者の人気記事