산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

누수 감지기 및 밸브 제어

구성품 및 소모품

알루미늄 인클로저
× 1
Arduino UNO
× 1
Arduino 이더넷 쉴드 2
× 1
전원 공급 장치
× 1
AC 하우징
× 1
저항이 있는 LED 키트
× 1
릴레이(듀얼 5v 1개 및 듀얼 12v 1개)
× 1
전동 밸브
× 1
JST 커넥터
× 1
물 센서
× 1

이 프로젝트 정보

개요

친구와 채팅을 하다가 누수가 큰 문제라는 것을 깨달았습니다. 내 친구는 일하는 동안 파이프가 부러져서 지하실에 있는 모든 가구를 교체해야 했습니다.

이 프로젝트는 내가 Microsoft IoT 콘테스트에 게시한 것과 유사하지만 이 프로젝트는 Raspberry가 아닌 Arduino를 기반으로 합니다. 제 관점은 다음과 같습니다. RasPi, DragonBoard 또는 PC와 같은 큰 플랫폼에서 많은 책임을 중앙 집중화하는 대신 위임하는 것을 선호합니다. Arduino 및 기타와 같은 간단한 장치에 대한 간단한 책임. 그들은 해야 할 일을 하고, 옵션으로 네트워크를 통해 다른(단순하거나 복잡한) 장치에 연결하여 고급 서비스를 제공합니다. 네트워크 오류가 발생하더라도 그들은 여전히 ​​해야 할 일을 계속합니다.

기본적으로 누수를 모니터링하고 감지된 결함에 따라 주 급수관을 닫는 등의 조치를 취합니다.

또한 MQTT 브로커에 메시지를 게시합니다. 아이디어는 장치가 지역적으로 물을 관리해야 하지만 다른 장치와 함께 홈 자동화를 관리하는 더 큰 시스템에도 관련되어 있다는 것입니다.

다음과 같습니다.

주요 물 입구는 바닥에 있습니다. 첫 번째 장치는 수압을 제어하기 위해 도시 상수도 서비스에 의해 설치됩니다. 사진 상단에 부품을 설치했습니다. 전동 밸브(파란색)는 수동 밸브와 병렬로 설치됩니다. 이 그림에서는 수동 밸브가 열리고 전동 밸브가 우회됩니다. 정전 시 유용합니다. 일반 모드에서는 수동 밸브를 꺼야 합니다.

밸브 내부에 DC 모터(12v)가 있으며 극성에 따라 시계 방향 또는 반시계 방향으로 회전합니다. 밸브가 효과적으로 On인지 Off인지를 나타내는 피드백 루프가 있습니다. 켜려면 왼쪽 상단 연결에 양의 전압을 가하면 됩니다.

컨트롤러는 다음과 같습니다.

왼쪽에서 오른쪽으로:AC 플러그, 재설정 버튼, 상태를 표시하는 일부 LED, 커넥터(센서, 모터), 이더넷 및 USB 인터페이스.

<울>
  • LED1 :빨간색 유지 =로컬에서 물 감지, 빨간색 깜박임 =원격으로 물 감지, 꺼짐 =누수 없음
  • <울>
  • LED 2 :노란색 유지 =전동 밸브를 제어할 수 없음, 노란색 깜박임 =MQTT 브로커에 연결할 수 없음, 꺼짐 =모두 양호
  • <울>
  • LED3 :파란색 점등 =정상, 파란색 깜박임 =전동 밸브가 닫힘 꺼짐 =시스템이 다운되었거나 전원이 공급되지 않음
  • 다음은 물이 누출될 수 있다고 생각되는 위치에 있는 센서입니다.

    다음은 내부에 있는 내용입니다.

    경고!

    내가 사용하고 있는 AC/DC 전원 공급 장치에는 두 개의 출력이 있습니다. 첫 번째 출력은 12V DC이고 전동 밸브(모터 회전을 제어하는 ​​두 개의 릴레이로 제어)에 전원을 공급하는 데 사용되며 두 번째 출력은 정확히 5V DC에 전원을 공급합니다. 아두이노. 그렇기 때문에 최소 6V DC가 필요한 Vin이 아닌 5V 회로에 직접 전원을 공급하고 있습니다. AC/DC가 연결되면 Arduino DC 잭이나 Arduino USB 케이블을 절대 연결하지 않아야 합니다. 여전히 USB를 통해 디버그하려면 전원 라인 없이 집에서 만든 케이블을 설정하고 데이터 라인만 유지하십시오. 그건 그렇고, AC 하우징과 AC/DC 전원 공급 장치 사이의 링크는 110V입니다. 절대 만지지 마세요!

    <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • 누수 감지 및 전동 밸브 제어
  • MQTT 라이브러리
  • 누수 감지 및 전동 밸브 제어Arduino
    #include #include #include #include #include #include #include /* 다음은 HW 작동 방식입니다. 세 가지 하위 시스템이 있습니다. 메인 상자:- 이더넷 실드가 있는 Arduino Uno - 빨간색 LED:물이 감지되면 계속 켜져 있고 원격으로 물이 감지되면 로컬로 깜박이고 그렇지 않으면 꺼집니다. 노란색 LED:밸브가 고장 났을 때 켜짐, MQTT 브로커에 연결할 수 없을 때 깜박임(어떤 이유로든), 그렇지 않으면 꺼짐 - 파란색 LED:밸브가 열려 있고 시스템이 누출을 모니터링 중일 때 켜짐, 밸브가 꺼졌을 때 깜박임 시스템이 다운됨 - 푸시 버튼 :일단 누르면 자체 테스트가 트리거됨 - 원격 전동 밸브를 제어하기 위한 이중 릴레이 - 원격 밸브에 설치된 개폐 제한 스위치를 감지하기 위한 또 다른 이중 릴레이 - 물 세트 감지기(모두 병렬)(앞판 패널의 모든 3개의 커넥터가 병렬로 연결됨) 전동 밸브에는 다음 연결이 있습니다. - 노란색 및 B lue :모터에 전원을 공급하는 DC- 검정색 :리미트 스위치 입력(우리 회로에서 GND로 설정됨)- 빨간색 =밸브가 완전히 닫힌 위치에 도달하면 GND로 바뀝니다(참고:리미트 스위치의 내부 설계로 인해 , 밸브의 전원이 꺼지면 연속성이 유지된다는 보장이 없습니다. - 녹색 =밸브가 완전히 열린 위치에 도달하면 GND로 바뀝니다(참고:리미트 스위치의 내부 설계로 인해 연속성이 보장되지 않습니다. 전원이 꺼지면 밸브가 유지됨)*/// Networkbyte mac[] ={ 0xDE, 0xAD, 0xBE, 0xCF, 0xFC, 0xEE }; // 아두이노의 MAC 주소IPAddress ip(192, 168, 12, 215); // 아두이노의 IP 주소IPAddress server(192, 168, 12, 130); // MQTT 브로커의 addressEthernetClient ethClient;// MQTT PubSubClient 클라이언트(ethClient); #define mqttClientPrefix "GLX" // MQTT 발행/구독을 사용하기 위한 접두어 #define mqttClientLocation "BASEMENT" // 클라이언트 식별자의 두 번째 부분#define mqttClientUID "001" // 클라이언트 식별자의 마지막 부분#define mqttClientStatusTopic "Status" // 장치 상태를 게시하는 데 사용할 주제 #define mqttClientFaultTopic "Fault" // Faultsconst에 게시/구독하는 데 사용할 주제 int mqttInterval =20; // 시스템이 MQTT 브로커에 보고하는 빈도를 결정합니다(즉, 모든 mqttInterval * mainLoopDelay ms )int mqttIntervalCnt =0; // downint를 계산하는 데 사용되는 지역 변수 isConnectedToBroker =-1; // 연결 시 1, -1 =알 수 없음, 0 =연결할 수 없음 // Pin-outconst int SystemLedPin =A0; // 파란색 led const int FaultLedPin =A1; // 노란색 led const int AlarmLedPin =A2; // 빨간색 led const int WaterDetectorPin =2; // 물이 감지되면 LOW로 가고, 그렇지 않으면 VCCconst로 풀업됨 int ToggleButtonPin =3; // 누군가 버튼을 누르면 LOW로 이동하고 버튼을 놓으면 HIGH로 이동합니다. 그렇지 않으면 GNDconst로 풀다운 int SdCardPin =4; // 이더넷 실드의 SD 카드, 사용되지 않음const int ValveClosedPin =5; // 모터가 닫힌 스위치 한계에 도달하면 LOW로 가고, 그렇지 않으면 HIGHconst로 pull-up int ValveOpenedPin =6; // 모터가 개방 스위치 한계에 도달하면 LOW로 가고, 그렇지 않으면 HIGHconst로 pull-up int ValveControl1 =8; // 전동 밸브 전원 공급 장치를 제어하는 ​​첫 번째 릴레이를 제어하기 위해 const int ValveControl2 =7; // 전동 밸브 전원 공급 장치를 제어하는 ​​두 번째 릴레이 제어 // D10, D11, D12 및 D13 핀은 이더넷 실드용으로 예약되어 있으므로 사용하지 마십시오. // WaterLeakage(로컬) int isWaterDetected =0; // 마지막 양호한 판독값에 따른 상태 // WaterLeakage (remote)int isWaterDetectedRemotely =0; // 다른 모니터링 장치에서 수신된 메시지에 따른 상태 // 전동 valveint isValveClosed =-1; // 전동 밸브의 상태(-1 =알 수 없음, 0 =열림, 1 =닫힘)) const int valveTimeOut =15; // 초 단위로, valveint isConnectedToValve =-1; // 시스템이 전동 밸브를 제어할 수 없는 경우 0, 1 =연결됨, -1 =알 수 없음// 수동 RESET 버튼volatile 부울 isResetRequested =0; // 버튼이 인터럽트를 트리거할 때 변경됩니다. // Logicconst int mainLoopDelay =500; // 메인 루프 내 고정 지연, in msvoid(* resetFunc) (void) =0;// 초기화 void setup(){ wdt_disable(); // '켜짐' 상태이거나 초기화 시간이 필요한 경우 항상 비활성화하는 것이 좋습니다. Serial.begin(9600); Serial.println(F("설정 시작")); // 하드웨어 설정 pinMode (SystemLedPin, OUTPUT); 핀모드(FaultLedPin, OUTPUT); 핀모드(AlarmledPin, OUTPUT); 핀모드(WaterDetectorPin, INPUT); 핀모드(ToggleButtonPin, INPUT); 핀모드(ValveOpenedPin, INPUT); // 12V DC 릴레이는 기본적으로 유휴 상태입니다. 핀은 릴레이 1의 NO쪽에 연결되지만 풀업이 있습니다. 따라서 핀은 기본적으로 HIGH입니다. 핀모드(ValveClosedPin, INPUT); // 12V DC 릴레이는 기본적으로 유휴 상태입니다. 핀은 릴레이 2의 NO쪽에 연결되지만 풀업이 있습니다. 따라서 핀은 기본적으로 HIGH입니다. 핀모드(밸브컨트롤1, 출력); 디지털 쓰기(밸브 제어1, 높음); // 5V DC 릴레이 1은 기본적으로 유휴 상태입니다. 즉, 모터는 GND 핀모드(ValveControl2, OUTPUT)에 연결되어 있습니다. digitalWrite(밸브컨트롤2, 높음); // 5V DC 릴레이 2는 기본적으로 유휴 상태입니다. 즉, 모터는 GND에 연결되어 있습니다. pinMode(SdCardPin, OUTPUT); digitalWrite(SdCardPin, HIGH); // SD 카드를 사용하지 않기 때문에 비활성화하려면 // 자체 테스트 testLeds(); // 네트워크 및 MQTT 설정 client.setServer(server, 1883); client.setCallback(MQTTBrokerCallback); Ethernet.begin(맥, 아이피); Serial.print(F("현재 IP는 :")); Serial.print(Ethernet.localIP()); Serial.print(F(" - MQTT 브로커 IP는 :")); Serial.println(서버); // 처음에는 밸브의 상태를 알지 못하며 리미트 스위치가 그렇게 안정적이지 않습니다. // 전동 밸브를 열고 완료를 기다립니다. 최악의 경우, 이미 열려 있는 경우 제한 스위치에 잠시 닿게 됩니다. if (openValve() ==0) { Serial.println(F("밸브가 열려 있고 시스템이 현재 모니터링 중입니다")); // 집에 다른 모니터링 장치가 있습니다. MQTT 브로커에 보고할 수 있는 결함을 들어보겠습니다. subscribeToRemoteWaterSensors(); } else { Serial.println(F("밸브를 열 수 없습니다. 시스템이 고장났습니다. 배관 바이패스를 사용하세요.")); }; enableInterruptOnResetButton(); 지연(1500); // 하드웨어가 스스로 정렬하도록 허용합니다. Serial.println(F("End of setup")); }// Main loopvoid loop(){ // LED configureLedsWithInitialStates(); // 재설정 요청에 반응 if (isResetRequested ==1) { Serial.println(F("누군가 버튼을 눌러 이 장치를 재설정했습니다.")); 게시 상태(); 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 =mqtt간격; } else { if (isConnectedToValve ==0) { Serial.println(F("시스템이 고장났습니다. 전동 밸브를 제어할 수 없습니다. 모니터링이 이루어지지 않습니다.")); } else { Serial.print(F(".")); } mqttIntervalCnt =mqttIntervalCnt - 1; } // 휴식을 취합니다. delay(mainLoopDelay / 2 ); 클라이언트.루프(); // LED configureLedsWithFinalStates(); 지연(mainLoopDelay / 2); }//// 로컬 물 센서 관리//void readLocalWaterSensor(){ isWaterDetected =!getDebouncedValue(WaterDetectorPin, 100, 10); Serial.print(isWaterDetected); }//// 리셋 버튼 관리//void enableInterruptOnResetButton(){ isResetRequested =0; attachInterrupt(1, onResetRequested, CHANGE);} 무효 onResetRequested(){ detachInterrupt(1); isResetRequested =1; }// 밸브 열기 시퀀스 관리int openValve(){ Serial.print(F("밸브 열기...")); // 먼저, 모터가 "닫힌" 리미트 스위치를 다시 짧게 눌러 밸브가 닫혔는지 확인합니다(이러한 리미트 스위치는 신뢰할 수 없기 때문에...) setupRelays(1); if (waitForEndOfCycle(ValveClosedPin) ==0) { // 이제 밸브를 열어 보겠습니다. setupRelays(2); if (waitForEndOfCycle(ValveOpenedPin) ==0) { isConnectedToValve =1; isValveClosed =0; 설정 릴레이(0); // 전원 릴레이 OFF Serial.println(F("")); 반환 0; } } 설정 릴레이(0); // 전원 릴레이 OFF isConnectedToValve =0; return -1;}// 밸브 닫기 시퀀스 관리int closeValve(){ Serial.print(F("밸브 닫기...")); // 먼저, 모터가 "개방" 리미트 스위치를 다시 짧게 눌러 밸브가 열려 있는지 확인합니다(해당 리미트 스위치는 신뢰할 수 없기 때문에...) setupRelays(2); if ( waitForEndOfCycle(ValveOpenedPin) ==0) { // 이제 밸브를 닫도록 합시다. setupRelays(1); if (waitForEndOfCycle(ValveClosedPin) ==0) { isConnectedToValve =1; isValveClosed =1; 설정 릴레이(0); // 전원 릴레이 OFF Serial.println(F("밸브가 꺼져 있습니다. 모든 방과 청소 감지기를주의 깊게 검사하십시오"))); 반환 0; } } 설정 릴레이(0); // 전원 릴레이 OFF isConnectedToValve =0; return -1;}// 올바른 극성으로 모터에 공급하기 위해 릴레이 설정void setupRelays(int 시나리오){ switch (scenario) { case 0:// 모두 OFF, 전동 밸브에 전원이 전송되지 않음 digitalWrite(ValveControl1, HIGH ); digitalWrite(밸브컨트롤2, 높음); 부서지다; case 1:// 종료 사이클 digitalWrite(ValveControl1, HIGH); digitalWrite(밸브컨트롤2, LOW); 부서지다; 사례 2:// 사이클 열기 digitalWrite(ValveControl1, LOW); digitalWrite(밸브컨트롤2, 높음); 부서지다; 기본값:Serial.print(F("예기치 않은 릴레이 시나리오:")); Serial.println(시나리오); 디지털 쓰기(밸브 제어1, 높음); digitalWrite(밸브컨트롤2, 높음); 부서지다; }}// 전동 밸브의 모터가 리미트 스위치에 도달할 때까지 기다립니다. int waitForEndOfCycle(int limitSwitchPin){ int cnt =valveTimeOut; while (cnt> 0) { if (getDebouncedValue(limitSwitchPin, 10, 10) ==LOW) { return 0; } cnt =cnt - 1; Serial.print(F(".")); 지연(1000); }; Serial.println(F(" - 밸브를 닫는 동안 시간 초과에 도달했습니다. 밸브의 전원이 제대로 켜져 있고 케이블이 연결되어 있는지 확인하십시오.")); return -1;}// 이 루틴은 잘못된 경고를 방지하는 데 도움이 됩니다. alarmsint getDebouncedValue(int inputPin, int intervalInMs, int requiredConfirmations){ int Confirms =1; int 현재 값 =디지털 읽기(입력 핀); while (confirmations <=requiredConfirmations) { delay(intervalInMs); if (currentValue ==digitalRead(inputPin)) { 확인 =확인 + 1; } else { 확인 =1; 현재값 =디지털읽기(입력핀); } } 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);} 무효 configureLedsWithFinalStates(){ if (isWaterDetectedRemotely ==1) { digitalWrite(AlarmLedPin, LOW);}; if (isConnectedToBroker ==0) { digitalWrite(FaultLedPin, LOW);}; if (isValveClosed ==1) { digitalWrite(SystemLedPin, LOW);}; } 무효 clearLeds(){ digitalWrite(AlarmLedPin, LOW); digitalWrite(FaultLedPin, LOW); digitalWrite(SystemLedPin, LOW);} 무효 testLeds(){ clearLeds(); digitalWrite(경고 핀, 높음); 지연(500); digitalWrite(FaultLedPin, HIGH); 지연(500); digitalWrite(SystemLedPin, HIGH); 지연(500); clearLeds();}//// MQTT 관련 함수//// 들어오는 MQTT 메시지 처리void MQTTBrokerCallback(char* subscribedTopic, byte* 페이로드, unsigned int length){ Serial.print(F("MQTT 브로커에서 받은 새 메시지. Topic =")); Serial.print(subscribedTopic); 문자열 payloadAsString =(char*)페이로드; 문자열 realPayload =payloadAsString.substring(0,길이); // 그렇지 않으면 버퍼가 In과 Out 사이에서 공유되기 때문에 쓰레기를 얻습니다. Serial.print(F(", content=")); Serial.print(리얼페이로드); if (realPayload.indexOf("WaterDetected")> 0 &&realPayload.indexOf(mqttClientLocation) ==-1 ) // 자체 트리거 오류를 피하기 위해 테스트의 두 번째 부분이 필요합니다. { isWaterDetectedRemotely =1; } // for (int i=0;i 

    회로도


    제조공정

    1. 어려운 차단 및 제어용 밸브
    2. Raspberry Pi 센서 및 액추에이터 제어
    3. 수영장 채우기 제어
    4. Portenta H7 듀얼 코어 디버깅
    5. Arduino, 1Sheeld 및 Android를 사용한 범용 원격 제어
    6. LCD 애니메이션 및 게임
    7. Arduino로 코인 억셉터 제어
    8. Arduino 제어 센터
    9. 오디오 주파수 감지기
    10. Bluetooth가 탑재된 Arduino로 LED 제어!