제조공정
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
|
기능 목록 <울>
환기 시스템 구축에 필요한 부품 <울>
배선도
OLED 디스플레이
그렇다면 IO 확장기를 사용하는 이유는 무엇입니까? <울>
시스템 구축
Arduino Nano를 IO Expander에 연결하고 다음 코드로 프로그래밍합니다. 6핀 헤더는 소프트웨어 직렬 디버그 포트이며 최종 설치에서는 필요하지 않습니다.
1-Wire에서 I2C 주소와 일치하도록 ONEWIRE_TO_I2C_ROM 정의 주소를 변경했는지 확인하십시오.
/* IO 확장기
*
* 지하실/크롤 공간 환기 시스템 v1.1
*
*/
#include
#include
#include
#include "IOExpander.h"
#define 화씨
#define ONEWIRE_TO_I2C_ROM "i4s71"
#define INIT_OLED "st13;si;sc;sd"
#define HUMIDITY_SENSOR_INSIDE "s6t1"
#define HUMIDITY_SENSOR_OUTSIDE "s8t #define FAN_ON "r1o"
#define FAN_OFF "r1f"
#define ABSOLUTE_DELTA_FAN_ON 1 // 절대 습도가 내부>=외부인 경우 팬 켜짐
#define ABSOLUTE_DELTA_FAN_OFF 0.5 // 팬 오프 내부의 절대 습도 델타 <=외부
#define OUTSIDE_RELATIVE_FAN_ON 88 // 외부 상대 습도가 <=%
#define OUTSIDE_RELATIVE_FAN_OFF 90인 경우 팬 켜기 // 외부 상대 습도가>=%
#define MINIMUM_TEMPERATURE 15 // 외부 온도 <=15C/59F인 경우 순환 환기 켜기/끄기
#define FAN_ON_TIME (20*60*1000L) // 20분
#define FAN_OFF_TIME (20*60*1000L) // 20분
//#define SERIAL_DEBUG
#define SERIAL_TIMEOUT 5000 // DHT22 읽기 간 5초 지연
#ifdef SERIAL_DEBUG
SoftwareSerial swSerial(8,7);
#endif
struct HS {
float temp;
float 상대;
float 절대;
bool 오류;
};
int led =13;
bool init_oled =true;
긴 켜짐, 꺼짐;
#ifdef 화씨
#define C2F(temp) 섭씨에서 화씨로(온도)
섭씨에서 화씨로 부동(섭씨로 부동)
{
return ((섭씨*9)/5)+ 32;
}
#else
#define C2F(temp)(temp)
#endif
void SerialPrint(const char* str, float decimal , 문자 오류)
{
Serial.print(str);
if (error) Serial.print(F("NA"));
else Serial.print(십진수 , 1);
}
부동 이슬점(부동 온도, 부동 습도)
{
float t =(17.625 * temp) / (243.04 + temp);
float l =log(humidity/100);
float b =l + t;
// Augus 사용 t-로슈-마그누스 근사
return (243.04*b)/(17.625-b);
}
#define MOLAR_MASS_OF_WATER 18.01534
#define UNIVERSAL_GAS_1447 243.04*b)/(17.625-b) />
float AbsoluteHumidity(float temp, float 상대)
{
//https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-에서 가져옴 상대 습도 습도 대 절대 습도/
//정밀도는 -30 ~ 35°C 범위에서 약 0.1°C입니다.
//August-Roche-Magnus 6.1094 exp(17.625 x T)/ (T + 243.04)
//Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97)
//참조 https://www.eas.ualberta.ca/jdwilson/EAS372_13 /Vomel_CIRES_satvpformulae.html // Buck (1981) 사용
return (6.1121 * pow(2.718281828, (17.67 * temp) / (temp + 243.5)) * 상대 * MOLAR_MASS_OF_WATER) / ((273.;
}
ReadHumiditySensor(HS* hs) 무효
{
SerialCmd("sr");
if (SerialReadFloat(&hs->temp) &&
SerialReadFloat(&hs->상대)) {
//hs->이슬점 =DewPoint(hs->temp, hs->상대);
hs->절대 =AbsoluteHumidity(hs->temp, hs->상대);
hs->오류 =false;
}
else hs ->오류 =true;
SerialReadUntilDone();
}
무효 설정() {
Serial.begin(115200);
#ifdef SERIAL_DEBUG
swSerial.begin(115200);
//swSerialEcho =&swSerial;
#endif
pinMode(led, OUTPUT);
wdt_enable(WDTO_8S);
offtime =millis() - FAN_OFF_TIME;
}
void loop() {
HS 내부, 외부;
정적 부울 팬 =false;
정적 부울 주기 =false;
정적 long last_time =-(60L * 1000L);
Serial.println();
if (SerialReadUntilDone()) {
// 습도 센서를 1분에 한 번만 읽거나 너무 빨리 읽으면 자체 발열합니다.
if (millis() - last_time> 60L * 1000L)
{
if (SerialCmdDone(HUMIDITY_SENSOR_INSIDE) )
ReadHumiditySensor(&inside);
if (SerialCmdDone(HUMIDITY_SENSOR_OUTSIDE))
ReadHumiditySensor(&outside);
i f(내부.오류 || 외부 오류) 팬 =false;
else {
if (fan) {
if (outside.relative>=OUTSIDE_RELATIVE_FAN_OFF || inside.absolute - outside.absolute <=ABSOLUTE_DELTA_FAN_OFF)
주기 =팬 =false;
else {
if (cycle &&outside.temp <=MINIMUM_TEMPERATURE &&
millis() - ontime> FAN_ON_TIME) 팬 =false;
}
if (!fan) offtime =millis();
}
else {
if (outside.relative <=OUTSIDE_RELATIVE_FAN_ON &&inside.absolute - outside.absolute>=ABSOLUTE_DELTA_FAN_ON)
주기 =팬 =true;
if (주기 &&외부.temp <=MINIMUM_TEMPERATURE)
팬 =(millis() - 오프타임> FAN_OFF_TIME) ? true :false;
if (fan) ontime =millis();
}
}
if (fan) SerialCmdDone(FAN_ON);
else SerialCmdDone(FAN_OFF);
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM)) {
if (init_oled) {
SerialCmdDone(INIT_OLED);
init_oled =false;
}
SerialCmdDone("st13;sc;sf0;sa1;sd70,0,\"내부\";sd127,0,\"외부\";sf1;sa0;sd0,12,248,\""
#ifdef 화씨
"F"
#else
"C"
#endif
"\";sd0,30,\"%\";sf0;sd0,50,\"g/m\";sd20,46,\"3\";");
SerialPrint("sf1;sa1;sd70,12,\"", C2F(inside.temp ), inside.error);
SerialPrint("\";sd70,30,\"", inside.relative, inside.error);
SerialPrint("\";sd70,48,\" ", inside.absolute, inside.error);
SerialPrint("\";sd127,12,\"", C2F(outside.temp), outside.error);
SerialPrint("\";sd127,30,\"", outside.relative, outside.error);
SerialPrint("\";sd127,48,\"", outside.absolute, outside.error);
직렬 .print("\";");
Serial.print("sf0;sa0;sd0,0,\"");
if (팬) Serial.print("FAN");
else Serial.print("v1.1");
Serial.println("\";sd");
SerialReadUntilDone();
}
else init_oled =true;
last_time =millis();
}
delay(1000);
}
else {
digitalWrite(led, HIGH);
delay(500);
digitalWrite(led, LOW);
delay(500);
init_oled =참;
}
wdt_reset();
}
참고: USB 포트를 사용하여 Arduino Nano를 프로그래밍하는 경우 동일한 단일 직렬 포트도 사용하므로 IO Expander에서 연결을 해제해야 합니다. 대신 디버그하려면 ICSP 포트를 사용하여 ATmega328P를 프로그래밍하십시오. 소프트웨어 디버깅 포트를 활성화하려면 SERIAL_DEBUG 정의의 주석 처리를 제거하십시오.
110VAC 전선을 두 팬에 연결합니다.
PG7 및 PG9용 외함의 양쪽에 7/16" 및 9/16" 구멍을 뚫습니다. dremel 도구를 사용하여 글랜드가 꼭 맞을 때까지 구멍을 약간 확대합니다. PG7은 12VDC 입력 전압을 공급하고 PG9는 센서 및 팬을 공급합니다.
열려 있고 막히지 않은 통풍구를 찾으십시오. 이것은 우리가 지하실/크롤 공간의 공기를 날려 버릴 배기 장치가 될 것입니다. 반대쪽에 있는 다른 모든 통풍구가 공기 흡입구가 되기 때문에 열려 있는지 확인하십시오. 인접한 환기구를 닫아 전체 지하실/거실 공간에 국부적인 공기 흐름 대신 지역적인 공기 흐름을 만듭니다.
타이 랩을 사용하여 통풍구 내부에 팬을 장착합니다. 팬이 올바른 방향으로 공기를 내보내도록 하십시오.
기존 액세스 포인트를 찾아 외부 습도 센서 와이어를 내부에 끼웁니다. 주변 온도/습도를 정확하게 측정할 수 있도록 습도 센서가 집과 장애물에서 충분히 멀리 떨어져 있는지 확인하십시오. 현지에서 발행한 일기 예보와 대조하여 판독값을 확인하십시오.
외부 습도 센서를 키스톤 잭과 인클로저에 배선하고 내부에 장착합니다.
내부 습도 센서를 키스톤 잭과 인클로저에 배선하고 내부에 장착합니다. 중앙 위치 또는 추가적인 수분 조절이 필요한 지역이 바람직합니다.
50피트 RJ11 와이어를 습도 센서에 연결하고 팬 와이어가 있는 와이어를 제어 인클로저가 설치될 사용 가능한 액세스 포인트에 연결합니다.
모든 전선을 연결하고 모든 부품을 제어 인클로저에 조립/공급합니다. 50피트 RJ11 전선이 미리 압착된 커넥터와 함께 제공되는 경우 글랜드를 통해 전선을 공급하고 새 커넥터를 압착하기 위해 전선을 잘라야 합니다.
시스템을 테스트하고 모든 것이 올바르게 작동하는지 확인하십시오. 릴레이와 팬을 테스트하려면 IO Expander에서 Arduino를 분리하고 컴퓨터에 직접 연결하여 수동으로 제어합니다. 모든 것이 제대로 작동하는지 확인한 후 양면 테이프와 포장용 폼을 사용하여 모든 부품을 인클로저에 조립하여 보드를 고정하고 Smart Moisture Control Ventilation System의 이점과 절약 효과를 누리십시오.
2019년 3월 20일 업데이트
지난 몇 달 동안 내 크롤 스페이스에서 환기 시스템을 중단 없이 실행했고 온수 히터에서 누출된 후 최대 상대 습도가 95% 이상인 상태에서 상대 습도를 50% 미만으로 성공적으로 떨어뜨렸습니다. 환기 시스템은 계속 작동하는 제어 시스템입니다!
SSD1306 0.96" OLED 디스플레이에서 SH1106 1.3" OLED 디스플레이로 전환했습니다. 훨씬 더 크고 읽기 쉽습니다. IO Expander 펌웨어 업데이트로 쉽게 변경할 수 있었습니다. 코드에서 'ST10'을 'ST13'으로 변경하기만 하면 됩니다.
2019년 9월 12일 업데이트
OLED 디스플레이가 블랭크에 전원을 공급하는 콜드 부팅 문제를 수정한 v1.1이 출시되었습니다. 여전히 내 크롤링 공간을 환기시키는 작업을 하고 있습니다!
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">/* IO Expander * * Basement/Crawlspace Ventilation System v1.1 * */#include섹션>#include #include #include "IOExpander.h#define FAHRENHEIT#define ONEWIRE_TO_I2C_ROM "i4s71#define INIT_OLED "st13;si;sc;sd"#define HUMIDITY_SENSOR_INSIDE "s6t1"#define HUMIDITY_SENSOR_TO_I2C_ROM "define HUMIDITY_SENSOR_INSIDE " define FAN_OFF "r1f#define ABSOLUTE_DELTA_FAN_ON 1 // 내부의 절대 습도 델타>=외부인 경우 팬 켜기 #define ABSOLUTE_DELTA_FAN_OFF 0.5 // 내부의 절대 습도 델타 <=외부인 경우 팬 끄기#define OUTSIDE_RELATIVE_FAN_ON 88 // 상대 외부의 경우 팬 켜기 습도는 <=%#define OUTSIDE_RELATIVE_FAN_OFF 90 // 외부 상대 습도가>=%#define MINIMUM_TEMPERATURE 15인 경우 팬 끄기 // 외부 온도 <=15C/59F#define FAN_ON_TIME(20*60*1000L)인 경우 순환 환기 켜기/끄기 // 20분#define FAN_OFF_TIME (20*60*1000L) // 20분//#define SERIAL_DEBUG#define SERIAL_TIMEOUT 5000 // 5초 de DHT22 읽기 사이에 배치#ifdef SERIAL_DEBUGSoftwareSerial swSerial(8,7);#endifstruct HS { float temp; 부동 소수점; 부동 절대; bool 오류;};int led =13;bool init_oled =true;긴 온타임, 오프타임;#ifdef 화씨#define C2F(온도) 섭씨ToFahrenheit(temp)float 섭씨ToFahrenheit(float 섭씨){ return ((섭씨*9)/5) +32;}#else#define C2F(temp) (temp)#endifvoid SerialPrint(const char* str, float decimal, char error){ Serial.print(str); if (오류) Serial.print(F("NA")); else Serial.print(decimal, 1);} float DewPoint(부동 온도, 부동 습도){ float t =(17.625 * temp) / (243.04 + temp); float l =log(습도/100); float b =l + t; // August-Roche-Magnus 근사값 사용 return (243.04*b)/(17.625-b);}#define MOLAR_MASS_OF_WATER 18.01534#define UNIVERSAL_GAS_CONSTANT 8.21447215float Absolutetempmidity(float)에서 가져옴 carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/ //정밀도는 -30 ~ 35°C 범위에서 약 0.1°C입니다. //August-Roche- 매그너스 6.1094 exp(17.625 x T)/(T + 243.04) //Buck(1981) 6.1121 exp(17.502 x T)/(T + 240.97) //참조 https://www.eas.ualberta.ca/jdwilson/ EAS372_13/Vomel_CIRES_satvpformulae.html // 사용 벅(1981) return (6.1121 * pow(2.718281828, (17.67 * temp) / (temp + 243.5)) * 상대 * MOLAR_MASS_OF_WATER.1 / ((5) 습도 센서 읽기(HS* hs){ SerialCmd("sr"); if (SerialReadFloat(&hs->temp) &&SerialReadFloat(&hs->relative)) { //hs->dewpoint =DewPoint(hs->temp, hs->relative); hs->absolute =절대습도(hs->temp, hs->상대); hs->오류 =거짓; } 그렇지 않으면 hs->오류 =true; SerialReadUntilDone();} 무효 설정() { Serial.begin(115200);#ifdef SERIAL_DEBUG swSerial.begin(115200); //swSerialEcho =&swSerial;#endif pinMode(led, OUTPUT); wdt_enable(WDTO_8S); offtime =millis() - FAN_OFF_TIME;}void 루프() { 내부, 외부 HS; 정적 부울 팬 =false; 정적 부울 주기 =거짓; 정적 긴 last_time =-(60L * 1000L); 직렬.println(); if (SerialReadUntilDone()) { //if (init_oled) { // if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM)) { // SerialCmdDone(INIT_OLED); // init_oled =거짓; // } //} // 습도 센서는 1분에 한 번만 읽습니다. 그렇지 않으면 너무 빨리 읽을 경우 자체 발열합니다. if (millis() - last_time> 60L * 1000L) { if (SerialCmdDone(HUMIDITY_SENSOR_INSIDE)) ReadHumiditySensor(&inside); if (SerialCmdDone(HUMIDITY_SENSOR_OUTSIDE)) ReadHumiditySensor(&outside); if (inside.error || outside.error) 팬 =false; else { if (fan) { if (outside.relative>=OUTSIDE_RELATIVE_FAN_OFF || inside.absolute - outside.absolute <=ABSOLUTE_DELTA_FAN_OFF) 주기 =팬 =거짓; else { if (cycle &&outside.temp <=MINIMUM_TEMPERATURE &&millis() - ontime> FAN_ON_TIME) 팬 =false; } if (!fan) 오프타임 =millis(); } else { if (outside.relative <=OUTSIDE_RELATIVE_FAN_ON &&inside.absolute - outside.absolute>=ABSOLUTE_DELTA_FAN_ON) 주기 =팬 =true; if (cycle &&outside.temp <=MINIMUM_TEMPERATURE) 팬 =(millis() - 오프타임> FAN_OFF_TIME) ? 허위 사실; if (fan) ontime =millis(); } } if (팬) SerialCmdDone(FAN_ON); 그렇지 않으면 SerialCmdDone(FAN_OFF); if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM)) { if (init_oled) { SerialCmdDone(INIT_OLED); init_oled =거짓; } SerialCmdDone("st13;sc;sf0;sa1;sd70,0,\"INSIDE\";sd127,0,\"OUTSIDE\";sf1;sa0;sd0,12,248,\"" #ifdef 화씨 "F" # else "C" #endif "\";sd0,30,\"%\";sf0;sd0,50,\"g/m\";sd20,46,\"3\";"); SerialPrint("sf1;sa1;sd70,12,\"", C2F(inside.temp), inside.error); SerialPrint("\";sd70,30,\"", inside.relative, inside.error); SerialPrint("\";sd70,48,\"", inside.absolute, inside.error); SerialPrint("\";sd127,12,\"", C2F(outside.temp), outside.error); SerialPrint ("\";sd127,30,\"", outside.relative, outside.error); SerialPrint("\";sd127,48,\"", outside.absolute, outside.error); Serial.print(" \";"); Serial.print("sf0;sa0;sd0,0,\""); if (fan) Serial.print("FAN"); else Serial.print("v1.1"); Serial.println("\";sd"); SerialReadUntilDone(); } 그렇지 않으면 init_oled =true; last_time =밀리(); } 지연(1000); } else { digitalWrite(led, HIGH); 지연(500); 디지털 쓰기(LED, LOW); 지연(500); init_oled =참; } wdt_reset();}
제조공정
구성품 및 소모품 Arduino UNO × 1 A7 GPRS/GPS 모듈 × 1 수질 센서 × 1 필요한 도구 및 기계 납땜 인두(일반) 앱 및 온라인 서비스 Microsoft Azure Arduino IDE 이 프로젝트 정보 소개 2016년 9월, 오염된 물이 공장으로 유입되어 정수장을 폐쇄해야 했습니다. 상수도 회사는 오염원을 정확히 찾아낼 수 없었고 이로 인해 심각한
이 프로젝트에서는 Arduino 보안 및 경보 시스템을 만드는 방법을 배웁니다. 다음 비디오를 보거나 아래에 작성된 튜토리얼을 읽을 수 있습니다. 개요 알람은 A 버튼을 누른 후 10초 후에 활성화됩니다. 물체를 감지하기 위해 초음파 센서를 사용하고 알람이 무언가를 감지하면 부저가 소리를 내기 시작합니다. 알람을 중지하려면 4자리 비밀번호를 삽입해야 합니다. 사전 설정된 비밀번호는 1234이지만 변경할 수도 있습니다. B 버튼을 눌러 암호 변경 메뉴로 들어갑니다. 계속하려면 현재 암호를 입력해야 하고 새 4자리 암호를 입력