それはよりシンプルに見え、照明スイッチに接続すれば完了です。 しかし、ライトの動作時間は可変であり、湿度を下げるのに十分ではないかもしれませんが、この問題はタイマーを設定することで解決できます。 加えて、私の愛する人は、「冷たい風を作り出す」ので、水の手順を取るとき、実際に働くファンが好きではありません。
2番目の明らかな解決策は、ファンを個別のスイッチに配置して、その人に制御を与えることです。 しかし、人的要因は、ファンが常にオンになることを忘れており、オンになっている場合はオフにすることです。 ファンの効率はすぐにゼロになる傾向がありました。
Arduinoとシンプルなマイクロコントローラーへの情熱をこの問題に結び付けなければなりませんでした。
処方されたポラキニン
制御デバイスの要件
- 制御デバイスは自動モードで動作するはずです。
- 湿度の上昇からファンをオンにする必要があります。
- ファンをオンにすることは、アパート内の現在の湿度レベルに依存するべきではありません。
- バスルームに誰もいないときにファンが動作するはずです。
- 制御装置はできるだけシンプルで安価でなければなりません。
要素ベースの選択
このデバイスのプロトタイプは、中国製のArduino Unoデバッグボードで作成されました。

その後、すべてがAtmega328マイクロコントローラーに転送され、標準のArduinoブートローダーでフラッシュされました。
最終的なデバイスは、「何があったかを知らない」という原則に基づいて作成されました。 すべての要素は、さまざまな予測のためにインターネットで以前に購入したか、アイドルデバイスから引き裂かれました。
- ソケット付きAtmega328P-PUマイクロコントローラー
- ブレッドボード
- 温湿度センサーDHT11 ;
- アイドル時間からの2桁の7セグメントインジケーターCPS03621BR。
- アマチュア無線ジャンクの箱からのフォトレジスタ。
- LM2596の電圧安定装置 。
- トライアックBT137 ;
- ガルバニック絶縁用のオプトシミスタMOC3061 。
- ボタンといくつかの抵抗器
3x1W LEDドライバーは照明器具に由来し、LM2596スイッチングスタビライザーの電源に完全に対応していました。
ケースとして、古い自動電話交換機のクロスボックスが使用されました。
接続
それ
- 10Kから+の抵抗を介したピン1(リセット)(このレッグへの干渉を避けるため);
- ピン2(D0)-未使用。
- ピン3(D1)-未使用。
- ピン4(D2)-カソード「G」7セグメントインジケーター。
- ピン5(D3)-カソード「。」 7セグメントインジケーター。
- ピン6(D4)-カソード「A」7セグメントインジケーター。
- ピン7(+)-電源3.5V;
- ピン8(-)-接地;
- ピン9(時計)-使用されていません。
- ピン10(時計)-使用されていません。
- ピン11(D5)-カソード「F」7セグメントインジケーター。
- ピン12(D6)-7セグメントインジケーターのカソード「D」。
- ピン13(D7)-カソード「E」7セグメントインジケーター。
- ピン14(D8)-カソード「C」7セグメントインジケーター。
- ピン15(D9)-7セグメントインジケーターのカソード「B」。
- ピン16(D10)-未使用。
- ピン17(D11)-未使用。
- ピン18(D12)-未使用。
- ピン19(D13)-制御回路ファン;
- ピン20(+)-電源3.5V(ダブル);
- ピン21(Aref)-未使用。
- ピン22(-)-接地(二重);
- ピン23(A0 / D14)-接地へのプルアップ抵抗27Kを備えたフォトレジスタ。
- ピン24(A1 / D15)-DHT11センサーからの入力。
- ピン25(A2 / D16)-4.7K抵抗器を介した7セグメントインジケータの2回目の放電の共通アノード。
- ピン26(A3 / D17)-4.7K抵抗器を介した7セグメントインジケータの最初の放電の共通アノード。
- ピン27(A4 / D18)-10Kプルアップ抵抗付きボタン+
- ピン28(A5 / D19)-未使用。
データシートはCPS03621BRインディケーターに見つからなかったため、結論はバッテリーを突っ込んで使用して見つかりました。 インジケータは、共通のアノードであることが判明しました。 カソードのレイアウト:

ファンはBT137トライアックによって制御されます。
サイトavr.ruから接続図を取得しました

誰かが繰り返すことを決めた場合-注意、トライアック本体の電圧は220Vです。

作業アルゴリズム
周波数が10秒に1回のマイクロコントローラーは、湿度と温度を測定します。
湿度は6つの値のアーカイブに周期的に蓄積されます。 現在の湿度がアーカイブの最初の湿度よりも3%以上高い場合、または絶対湿度値が85%より大きい場合は、ファンをオンにする必要があります。
フォトレジスタに光がない場合、ファンは20分間オンになります。
このボタンは、ファンが20分間強制的にオンになる(動作しない場合)か、オフになります(動作する場合)。
アルゴリズムのすべての定数は実験的に選択されました。
このインジケータは、現在の温度、湿度、カウントダウンタイマーを周期的に表示します。
湿度を下げる必要がある場合は2番目の放電ポイントが点灯し、ファンをオンにするコマンドが与えられると点滅します。
デバイスの完全なロジックは、有限決定性オートマトンによって記述できます。
マシンの入力アルファベットは、次のイベントで構成されます(優先度順):
- 手動モードボタンが押された
- 湿度センサーのトリガー;
- ライトが点灯しています。
- ライトが消灯しています。
- ファンタイマーが機能しました。
多くの州:
- スタンバイモード、ファンが動作しない、タイムアウト。
- ファンをオンにする必要があります、ファンが動作しない、タイマー(いつ)が停止します。
- ファンは自動モードで動作し、タイマーはオンです。
- ファンは手動モードで動作し、タイマーはオンです。
さて、オートマトンの状態遷移表:

プログラミング
私はAVR-studioや他のモンスターをインストールしませんでしたが、それでもIDE Arduinoが必要でした。
board.txtファイルで、内部8MHzクォーツで実行される新しいコントローラーを作成します。
atmega328_8.name=Atmega328 (5V, 8 MHz internal)
atmega328_8.upload.protocol=arduino
atmega328_8.upload.maximum_size=30720
atmega328_8.upload.speed=57600
atmega328_8.bootloader.low_fuses=0xE2
atmega328_8.bootloader.high_fuses=0xDE
atmega328_8.bootloader.extended_fuses=0x05
atmega328_8.bootloader.path=optiboot
atmega328_8.bootloader.file=optiboot_atmega328.hex
atmega328_8.bootloader.unlock_bits=0x3F
atmega328_8.bootloader.lock_bits=0x0F
atmega328_8.build.mcu=atmega328p
atmega328_8.build.f_cpu=8000000L
atmega328_8.build.core=arduino
atmega328_8.build.variant=standard
安価なUSBASPプログラマーをArduino UNOボードのISCPコネクタに接続し、Atmega328Pをソケットに挿入した後、ブートローダーをフラッシュします。
これで、UNOボード上の標準ブートローダーを使用して、環境内の適切なボードを選択して、マイクロコントローラーをデバッグおよびプログラムできます。
このプロジェクトでは、Arduino用の既製のライブラリが使用されました。
- DHT11センサーを操作するためのArduino DHTライブラリ
- 7セグメントインジケーターを操作するための7セグメントディスプレイ 。
完全なスケッチコード
#include <DHT.h> #include <SevenSegmentDisplay.h> #define DEBUG 1 #define TIMER_PERIOD 2400 #define ctrPIN 13 // #define dhtPIN 15 // #define btnPIN 18 // // void(* resetFunc) (void) = 0; // Reset MC function // SevenSegmentDisplay<true, BiDigit<17, 16> > ss(4, 9, 8, 6, 7, 5, 2, 3); // DHT11 8 DHT dht(dhtPIN, DHT11, 3);// 8 //DHT dht(dhtPIN, DHT11); //16 // FSM enum TMode { tmWait, // tmNeedPower, // tmAutoPower, // tmManualPower // }; // enum TDisplayMode { tdmTemp , // tdmHum , // tdmTimer // }; //int h_prev; int t,h,a0; int h_arr[6]; void setup() { // #ifdef DEBUG Serial.begin(9600); Serial.println("Humidity controller start ..."); #endif // pinMode(ctrPIN, OUTPUT); // digitalWrite(ctrPIN, LOW); // pinMode(btnPIN, INPUT); // digitalWrite(btnPIN, HIGH); // DHT11 dht.begin(); // h = dht.readHumidity(); for( int i=0; i<6; i++)h_arr[i] = h; } // 0.5 unsigned long cnt05 = 0; unsigned long ms1 = 0; // boolean flag_light = false; // boolean flag_btn = false; // boolean flag_hum = false; // unsigned int timer = 0; TMode mode = tmWait; TDisplayMode dmode = tdmTemp; boolean blink_stat = false; void loop () { unsigned long ms = millis(); int p = ms - ms1; // if( digitalRead(btnPIN) == LOW ){ int n = 1; for( int i=0; i<9; i++ ){ if( digitalRead(btnPIN) == LOW )n++; delay(10); } if( n > 9 )flag_btn = true; delay(400); #ifdef DEBUG Serial.println("Button is press"); #endif }//end if // , 0.5 if( p < 0 || p > 500 ){ cnt05++; ms1 = ms; // a0 = analogRead(A0); if( a0 > 1000 )flag_light = false; else flag_light = true; // 10 DHT11 if( cnt05%20 == 0 ){ h = dht.readHumidity(); t = dht.readTemperature(); // 3% 85% if( h - h_arr[5] > 3 || h > 85 )flag_hum = true; // for( int i=5; i>0; i--)h_arr[i] = h_arr[i-1]; h_arr[0] = h; #ifdef DEBUG Serial.print("VAL: Temp="); Serial.print(t); Serial.print(" H="); Serial.print(h); Serial.print(" A0="); Serial.print(a0); Serial.print(" X="); Serial.print(cnt05); Serial.print(" TM="); Serial.print(timer); Serial.print(" MODE="); Serial.print(mode); Serial.print(" DMODE="); Serial.print(dmode); Serial.println(""); #endif // switch( dmode ){ case tdmTemp : dmode = tdmHum; break; case tdmHum : dmode = tdmTimer; break; default: dmode = tdmTemp; }//end switch }//end if( cnt05%20 == 0 ) blink_stat = !blink_stat; SetStatusFSM(); }//end if( p < 0 || p > 500 ){ DisplayStatus(); }//end loop() /** * */ void DisplayStatus(){ // int point = -1; switch( mode ){ case tmNeedPower: point = 0; break; case tmAutoPower: case tmManualPower: if( blink_stat )point = 0; break; } switch( dmode ){ case tdmTemp : ss.print((unsigned)t,point,50); break; case tdmHum : ss.print((unsigned)h,point,50); break; case tdmTimer: // if( timer > 120 )ss.print((unsigned)(timer/120),point,50); // else if( timer > 0 )ss.print((unsigned)(timer/2),point,50); // 0 else ss.print(0,point,50); // ss.print((unsigned)(a0/100),point,50); break; }//end switch } /** * */ void SetStatusFSM(){ switch(mode){ // case tmWait : digitalWrite(ctrPIN, LOW); // if( flag_btn ){ timer = TIMER_PERIOD; mode = tmManualPower; } // else if( flag_hum ){ timer = TIMER_PERIOD; mode = tmNeedPower; } break; // case tmNeedPower: digitalWrite(ctrPIN, LOW); // if( flag_btn ){ mode = tmManualPower; } // else if( !flag_light ){ mode = tmAutoPower; } break; // " " case tmAutoPower: // digitalWrite(ctrPIN, HIGH); // if( timer > 0 )timer--; // if( flag_btn ){ mode = tmWait; timer = 0; } // else if( flag_light ){ mode = tmNeedPower; } // else if( timer <= 0 ){ timer = 0; mode = tmWait; } break; // " " case tmManualPower: // digitalWrite(ctrPIN, HIGH); // if( timer > 0 )timer--; // if( flag_btn ){ mode = tmWait; timer = 0; } // else if( timer <= 0 ){ timer = 0; mode = tmWait; } break; } // flag_btn = false; flag_hum = false; }
問題
実装で最初に遭遇した問題は、DHT11センサーが機能しなかったことです。 Arduino UNOではすべてが問題ありませんが、裸のマイクロコントローラーでは機能しません。 問題は、コントローラーの頻度とDHTポーリングプロトコルのタイミングにありました。
DHTライブラリで8 MHzの周波数で動作するコントローラーでは、「3」(クラスコンストラクターの3番目のパラメーター)の遅延を指定する必要があります。DHTdht(dhtPIN、DHT11、3)。
2番目の問題は、リセットボタンと手動ボタンの任意の操作でした。 障害は、これらの調査結果の近くを通る電力線からのリード線によって引き起こされました。 まず、対応する端子のマイクロコントローラーの内蔵プルアップ抵抗が外部10Kに置き換えられました。 干渉は減少しましたが、完全には消えませんでした。 コントローラは、ファンを個別にオン/オフすることで、定期的に寿命を過ごしました。
次に、干渉のソフトウェア抑制を実装しました-ボタンは10ミリ秒の遅延で10回連続してポーリングされ、10個すべての操作でのみボタンが認識されました。
完成したデバイスは次のようになります。

現在、ファン制御コントローラーは試運転中であり、キッチンのファンを制御することを考えています。ストーブをオンにして、煙とガスの臭いを嗅ぎます。
便利なリンクのリスト:
私の記事は私のブログsamopal.proで見つけることができます。