工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

水漏れ検知器とバルブ制御

コンポーネントと消耗品

アルミニウム筐体
× 1
Arduino UNO
× 1
Arduinoイーサネットシールド2
× 1
電源装置
× 1
ACハウジング
× 1
抵抗付きLEDのキット
× 1
>
リレー(1つのデュアル5vと1つのデュアル12v)
× 1
電動バルブ
× 1
JSTコネクタ
× 1
水センサー
× 1

このプロジェクトについて

概要

友達とおしゃべりをしていると、水漏れが大きな問題だと気づきました。私の友人は、仕事中にパイプが壊れたという理由だけで、地下室のすべての家具を交換しなければなりませんでした。

このプロジェクトは、私がMicrosoft IoTコンテストで公開したプロジェクトと似ていますが、これはRaspberryではなくArduinoに基づいています。私の見解は次のとおりです。大きなプラットフォーム(RasPi、DragonBoard、PCなど)に多くの責任を集中させるのではなく、委任することを好みます。 単純なデバイス(Arduinoなど)に対する単純な責任。彼らは彼らがすることになっていることをし、オプションとして、彼らはネットワークを介して他の(単純または複雑な)デバイスに接続して高度なサービスを提供します。ネットワーク障害が発生した場合でも、想定どおりの動作を継続します。

基本的には、漏水を監視し、検出された障害に応じて、メインの水入口を閉じるなどのアクションをトリガーします。

また、MQTTブローカーにメッセージを公開します。アイデアは、デバイスがローカルで水を管理する必要があるが、他のデバイスと一緒に、ホームオートメーションを管理するより大きなシステムにも関与しているということです。

外観は次のとおりです。

<図>

主な水の入り口は下部にあります。最初のデバイスは、水道圧を制御するために市の水道サービスによってインストールされます。写真上部にパーツを取り付けました。電動バルブ(青色)は手動バルブと並列に取り付けられています。この図では、手動バルブが開いているため、電動バルブはバイパスされています。停電の場合に便利です。通常モードでは、手動バルブをオフにする必要があります。

バルブ内にはDCモーター(12v)があり、極性に応じて時計回りまたは反時計回りに回転します。バルブが効果的にオンかオフかを示すフィードバックループがあります。オンにするには、左上の接続に正の電圧を印加するだけです。

これがコントローラーです:

<図>

左から右へ:ACプラグ、リセットボタン、ステータスを表示するいくつかのLED、コネクタ(センサー、モーターへ)、イーサネット、USBインターフェース。

  • LED1 :赤く点灯=ローカルで水が検出され、赤で点滅=リモートで水が検出され、オフ=水漏れがない
  • LED 2 :黄色に点灯=電動バルブを制御できない、黄色に点滅=MQTTブローカーに到達できない、オフ=すべて良好
  • LED3 :青く点灯=すべて良好、青で点滅=電動バルブが閉じているオフ=システムがダウンしているか電源が入っていない

これが水漏れの可能性があると思う場所にあるセンサーです:

<図>

ボンネットの下にあるものは次のとおりです。

<図>

警告!

私が使用しているAC / DC電源には2つの出力があります。1つは12VDCで、電動バルブ(モーターの回転を制御する2つのリレーによって制御されます)に給電するために使用され、2つ目は正確に5VDCに給電します。 Arduino。そのため、少なくとも6V DCを必要とするVinではなく、5V回路に直接給電しています。 AC / DCを接続したら、ArduinoDCジャックもArduinoUSBケーブルも絶対に差し込まないでください(私は決して言わないでください)。それでもUSB経由でデバッグする場合は、電力線なしで自家製ケーブルをセットアップし、データ線だけを残します。ちなみに、ACハウジングとAC / DC電源間のリンクは110Vです。絶対に触れないでください!

コード

  • 漏水検知と電動バルブ制御
  • MQTTライブラリ
漏水検知と電動バルブ制御 Arduino
 #include  #include  #include  #include  #include  #include  #include  / * HWの仕組みは次のとおりです。3つのサブシステムがあります。-メインボックス:-Arduino Unoとイーサネットシールド-赤いLED:水が検出されると点灯し、水がリモートで検出されると局所的に点滅します。それ以外の場合はオフになります-黄色のLED:バルブが故障しているときは点灯、MQTTブローカーに到達できないときは点滅(何らかの理由で)、それ以外の場合は消灯-青色のLED:バルブが開いていてシステムが漏れを監視しているときは点灯、バルブがオフになっているときは点滅システムがダウンしている-プッシュボタン:一度押すと、セルフテストがトリガーされます-リモート電動バルブを制御するためのデュアルリレー-リモートVAにインストールされている開閉制限スイッチを感知するための別のデュアルリレーlve-水検出器のセット(すべて並列)(フロンパネルの3つのコネクタすべてが並列に接続されています)電動バルブには次の接続があります:-黄色と青:モーターに電力を供給するDC-黒:リミットスイッチ入力(回路ではGNDに設定されます)-赤=バルブが完全に閉じた位置に達するとGNDに変わります(注:リミットスイッチの内部設計により、電源を入れた場合にバルブが一度作動すると導通が維持される保証はありませんオフ)-緑=バルブが完全に開いた位置に達するとGNDに変わります(注:リミットスイッチの内部設計により、電源をオフにした場合にバルブが一度作動すると導通が維持される保証はありません)* /// Networkbyte mac [] ={0xDE、0xAD、0xBE、0xCF、0xFC、0xEE}; // ArduinoのMACアドレスIPAddressip(192、168、12、215); // ArduinoのIPアドレスIPAddressserver(192、168、12、130); // MQTTブローカーのaddressEthernetClientethClient; // MQTT PubSubClient client(ethClient); #define mqttClientPrefix "GLX" //任意のMQTTパブリケーション/サブスクリプションを使用するためのプレフィックス#definemqttClientLocation "BASEMENT" //クライアント識別子の2番目の部分#definemqttClientUID "001" //クライアント識別子の最後の部分#definemqttClientStatusTopic "Status" //デバイスステータスのパブリッシュに使用されるトピック#definemqttClientFaultTopic "Fault" // Faultsconstのパブリッシュ/サブスクライブに使用されるトピックintmqttInterval =20; //システムがMQTTブローカーにレポートする頻度を決定します(つまり、すべてのmqttInterval * mainLoopDelay ms)int mqttIntervalCnt =0; //ダウンカウントに使用されるローカル変数isConnectedToBroker =-1; //接続時に1、-1 =不明、0 =接続できません// Pin-outconst int SystemLedPin =A0; //青色LEDconst int FaultLedPin =A1; //黄色のLEDconst int AlarmLedPin =A2; //赤のLEDconst int WaterDetectorPin =2; //水が検出されると、LOWになります。それ以外の場合は、VCCconst int ToggleButtonPin =3にプルアップされます。 //誰かがボタンを押すとLOWになり、ボタンを離すとHIGHになります。それ以外の場合は、GNDにプルダウンします。constintSdCardPin =4; //イーサネットシールド上のSDカード、未使用const int ValveClosedPin =5; //モーターが閉じたスイッチの限界に達すると、LOWになります。それ以外の場合は、HIGHにプルアップします。intValveOpenedPin=6; //モーターがオープンスイッチの制限に達するとLOWになり、それ以外の場合はHIGHにプルアップします。intValveControl1=8; //電動バルブ電源を制御する最初のリレーを制御するconstint ValveControl2 =7; //電動バルブ電源を制御する2番目のリレーを制御する//これらのピンはイーサネットシールド用に予約されているため、D10、D11、D12、およびD13は使用しないでください// WaterLeakage(local)int isWaterDetected =0; //最後の良好な読み取り値によるステータス// WaterLeakage(remote)int isWaterDetectedRemotely =0; //他の監視デバイスから受信したメッセージごとのステータス//電動valveintisValveClosed =-1; //電動バルブのステータス(-1 =不明、0 =開、1 =閉))const int ValveTimeOut =15; //秒単位で、valveintの開閉に許可される最大時間isConnectedToValve =-1; //システムが電動バルブを制御できない場合は0、1 =接続済み、-1 =不明//手動リセットボタンvolatileboolean isResetRequested =0; //これはボタンが割り込みをトリガーすると変更されます// Logicconst int mainLoopDelay =500; //メインループ内の固定遅延、msvoid(* resetFunc)(void)=0; //初期化voidsetup(){wdt_disable(); //それが「オン」のままであるか、初期化時間が必要な場合は、常に無効にすることをお勧めしますSerial.begin(9600); Serial.println(F( "セットアップの開始")); // HWセットアップpinMode(SystemLedPin、OUTPUT); pinMode(FaultLedPin、OUTPUT); pinMode(AlarmLedPin、OUTPUT); pinMode(WaterDetectorPin、INPUT); pinMode(ToggleButtonPin、INPUT); pinMode(ValveOpenedPin、INPUT); // 12VDCリレーはデフォルトでアイドル状態です。ピンはリレー1のNO側に接続されていますが、プルアップがあります。したがって、ピンはデフォルトでHIGHです。 pinMode(ValveClosedPin、INPUT); // 12VDCリレーはデフォルトでアイドル状態です。ピンはリレー2のNO側に接続されていますが、プルアップがあります。したがって、ピンはデフォルトでHIGHです。 pinMode(ValveControl1、OUTPUT); digitalWrite(ValveControl1、HIGH); // 5V DCリレー1はデフォルトでアイドル状態です。つまり、モーターはGNDピンモード(ValveControl2、OUTPUT)に接続されています。 digitalWrite(ValveControl2、HIGH); // 5V DCリレー2はデフォルトでアイドル状態です。つまり、モーターはGNDに接続されていますpinMode(SdCardPin、OUTPUT); digitalWrite(SdCardPin、HIGH); // SDカードを使用しないため無効にします//セルフテストtestLeds(); //ネットワークとMQTTのセットアップclient.setServer(server、1883); client.setCallback(MQTTBrokerCallback); Ethernet.begin(mac、ip); Serial.print(F( "現在のIPは:")); Serial.print(Ethernet.localIP()); Serial.print(F( "-MQTTブローカーIPは:")); Serial.println(サーバー); //最初は、バルブのステータスがわからず、リミットスイッチの信頼性はそれほど高くありません。 //電動バルブを開いて、完了するのを待ちましょう。最悪の場合、すでに開いている場合は、(openValve()==0){Serial.println(F( "バルブが開いており、システムが監視中です"));の場合、リミットスイッチに短時間ヒットします。 //家の中には他の監視デバイスがあります。MQTTブローカーに報告できる障害を聞いてみましょうsubscribeToRemoteWaterSensors(); } else {Serial.println(F( "バルブを開くことができません。システムが故障しています。配管バイパスを使用してください")); }; enableInterruptOnResetButton(); delay(1500); //ハードウェアがそれ自体を分類できるようにするSerial.println(F( "End of setup")); } //メインloopvoidloop(){// LED configureLedsWithInitialStates(); //リセット要求に反応するif(isResetRequested ==1){Serial.println(F( "誰かがこのデバイスをリセットするためにボタンを押した")); publishStatus(); wdt_enable(WDTO_1S); //ウォッチドッグを有効にします。1秒のdelay(5000)で起動します。 Serial.println(F( "このメッセージは表示されません")); } //水漏れが検出されたかどうかを確認しましょうreadLocalWaterSensor(); if(isWaterDetected ==1 || isWaterDetectedRemotely ==1){if(isValveClosed ==0){closeValve();}; } // MQTTブローカーに公開if(mqttIntervalCnt ==0){if(isWaterDetected ==1){publishFault();} publishStatus(); mqttIntervalCnt =mqttInterval; } else {if(isConnectedToValve ==0){Serial.println(F( "システムが故障しています-電動バルブを制御できません。監視が行われていません")); } else {Serial.print(F( "。")); } mqttIntervalCnt =mqttIntervalCnt-1; } //少し休憩を取りますdelay(mainLoopDelay / 2); client.loop(); // LED configureLedsWithFinalStates(); delay(mainLoopDelay / 2); } ////ローカル水センサー管理// voidreadLocalWaterSensor(){isWaterDetected =!getDebouncedValue(WaterDetectorPin、100、10); Serial.print(isWaterDetected); } ////リセットボタン管理// voidenableInterruptOnResetButton(){isResetRequested =0; attachInterrupt(1、onResetRequested、CHANGE);} void onResetRequested(){detachInterrupt(1); isResetRequested =1; } //バルブ開放シーケンスを管理しますintopenValve(){Serial.print(F( "Opening Valve ...")); //最初に、モーターに「閉じた」リミットスイッチをもう一度短く押してバルブが閉じたことを確認します(これらのリミットスイッチはそれほど信頼できないため...)setupRelays(1); if(waitForEndOfCycle(ValveClosedPin)==0){//ここで、バルブを開いてみましょうsetupRelays(2); if(waitForEndOfCycle(ValveOpenedPin)==0){isConnectedToValve =1; isValveClosed =0; setupRelays(0); //電源リレーOFFSerial.println(F( "")); 0を返します。 }} setupRelays(0); //電源リレーOFFisConnectedToValve =0; return -1;} //バルブ閉鎖シーケンスを管理しますintcloseValve(){Serial.print(F( "Closing Valve ...")); //最初に、モーターに「開いた」リミットスイッチをもう一度短く押してバルブが開いていることを確認します(これらのリミットスイッチはそれほど信頼性がないため...)setupRelays(2); if(waitForEndOfCycle(ValveOpenedPin)==0){//ここで、バルブを閉じてみましょうsetupRelays(1); if(waitForEndOfCycle(ValveClosedPin)==0){isConnectedToValve =1; isValveClosed =1; setupRelays(0); //電源リレーOFFSerial.println(F( "バルブがオフになっています。すべての部屋とクリーンアップ検出器を注意深く検査してください")); 0を返します。 }} setupRelays(0); //電源リレーOFFisConnectedToValve =0; return -1;} //モーターに正しい極性を供給するためにリレーを設定しますvoidsetupRelays(intscenario){switch(scenario){case 0://すべてオフ、電力が送られていません電動バルブdigitalWrite(ValveControl1、HIGH ); digitalWrite(ValveControl2、HIGH);壊す;ケース1://サイクルを閉じるdigitalWrite(ValveControl1、HIGH); digitalWrite(ValveControl2、LOW);壊す;ケース2://オープニングサイクルdigitalWrite(ValveControl1、LOW); digitalWrite(ValveControl2、HIGH);壊す;デフォルト:Serial.print(F( "予期しないリレーシナリオ:")); Serial.println(シナリオ); digitalWrite(ValveControl1、HIGH); digitalWrite(ValveControl2、HIGH);壊す; }} //リミットスイッチが電動バルブのモーターに当たるまで待ちますintwaitForEndOfCycle(int limitSwitchPin){int cnt =ValveTimeOut; while(cnt> 0){if(getDebouncedValue(limitSwitchPin、10、10)==LOW){return 0; } cnt =cnt-1; Serial.print(F( "。")); delay(1000); }; Serial.println(F( "-バルブを閉じているときにタイムアウトになりました。バルブの電源が十分に入っていて、ケーブルが接続されているかどうかを確認してください。")); return -1;} //このルーチンは、誤ったアラームを回避するのに役立ちますint getDebouncedValue(int inputPin、int intervalInMs、int requiredConfirmations){int Confirmations =1; int currentValue =digitalRead(inputPin); while(confirmations <=requiredConfirmations){delay(intervalInMs); if(currentValue ==digitalRead(inputPin)){確認=確認+ 1; } else {確認=1; currentValue =digitalRead(inputPin); }} return currentValue;} //// LED管理// void configureLedsWithInitialStates(){clearLeds(); // if(isWaterDetectedRemotely ==1 || isWaterDetected ==1){digitalWrite(AlarmLedPin、HIGH);};を再評価しますif(isConnectedToValve ==0 || isConnectedToBroker ==0){digitalWrite(FaultLedPin、HIGH);}; digitalWrite(SystemLedPin、HIGH);} void configureLedsWithFinalStates(){if(isWaterDetectedRemotely ==1){digitalWrite(AlarmLedPin、LOW);}; if(isConnectedToBroker ==0){digitalWrite(FaultLedPin、LOW);}; if(isValveClosed ==1){digitalWrite(SystemLedPin、LOW);}; } void clearLeds(){digitalWrite(AlarmLedPin、LOW); digitalWrite(FaultLedPin、LOW); digitalWrite(SystemLedPin、LOW);} void testLeds(){clearLeds(); digitalWrite(AlarmLedPin、HIGH); delay(500); digitalWrite(FaultLedPin、HIGH); delay(500); digitalWrite(SystemLedPin、HIGH); delay(500); clearLeds();} //// MQTT関連関数////着信MQTTメッセージの処理voidMQTTBrokerCallback(char * subscribedTopic、byte * payload、unsigned int length){Serial.print(F( "MQTTブローカーから受信した新しいメッセージ。トピック=")); Serial.print(subscribedTopic);文字列payloadAsString =(char *)payload;文字列realPayload =payloadAsString.substring(0、length); //それ以外の場合、バッファはInとOutの間で共有されるため、ガベージが発生しますSerial.print(F( "、content =")); Serial.print(realPayload); if(realPayload.indexOf( "WaterDetected")> 0 &&realPayload.indexOf(mqttClientLocation)==-1)//自己トリガー障害を回避するためにテストの2番目の部分が必要です{isWaterDetectedRemotely =1; } // for(int i =0; i  

回路図


製造プロセス

  1. 遮断と制御が難しいバルブ
  2. ラズベリーパイセンサーとアクチュエーター制御
  3. プールフィルコントロール
  4. PortentaH7デュアルコアデバッグ
  5. Arduino、1Sheeld、Androidを使用したユニバーサルリモコン
  6. LCDアニメーションとゲーム
  7. Arduinoでコインアクセプターを制御する
  8. Arduinoコントロールセンター
  9. 可聴周波数検出器
  10. LEDを制御するBluetoothを搭載したArduino!
  11. FirmataとXboxOneControllerを使用してArduinoRoverを制御する