아두이노 프로젝트 2. 가정용 스마트 식물 관리 시스템
개요
가정용 스마트 식물 관리 시스템
몇 가지 장치들을 활용해 가정에서 식물을 효율적으로 관리할 수 있는 가정용 스마트 식물 관리 시스템을 제작합니다.
고려사항
- 워터 펌프 및 온습도 정보를 통한 자동 급수 기능을 추가합니다.
- 블루투스로 연결된 어플리케이션에서 온습도 정보, 모터 작동 정보 및 음성인식을 통한 급수 기능을 지원합니다.
사용 하드웨어
회로 구성
기능 구현
#include <DHT.h>
// 사용 핀번호
const int dht_pin = 2;
const int ENB = 7; //(IN3 = +, IN4 = -)
DHT dht(dht_pin, DHT11);
unsigned long past = 0;
unsigned long past2 = 0;
const unsigned long interval = 500; // 설정 시간때마다 스마트폰으로 현재 습도 및 온도 전송[ms]
int waterState = 0;
int hum = 0;
int temp = 0;
// 사용자 조정 필요 변수
int hum_criticalPoint = 25; // [*]습도 센싱 경계값(본 값보다 측정된 값이 낮을 시 워터펌프 작동)
const unsigned long waterdly = 500; // [*]워터펌프 on 시간(앱에서 눌렀을 때)
void waterOnOff(bool onOff, int val = 0) {
if (onOff == 0) { //off
digitalWrite(ENB, LOW);
Serial3.write(-10); //거치 스마트폰 전송 구분자
Serial3.write(0); //모터상태 전송
waterState = 0;
} else if (onOff == 1) { //on
digitalWrite(ENB, HIGH);
Serial3.write(-10); //거치 스마트폰 전송 구분자
Serial3.write(10); //모터상태 전송
waterState = 1;
}
if (val != 0) {
waterState = val;
}
}
int dhtfunc(char choice) {
int hh = (int)dht.readHumidity(); // 슴도
int tt = (int)dht.readTemperature(); // 섭씨 온도
if (isnan(hh) || isnan(tt)) {
Serial.println("Failed to read from DHT sensor!");
waterOnOff(0);
return -1;
}
switch (choice) {
case 'h':
return hh;
break;
case 't':
return tt;
break;
default:
break;
}
}
void setup() {
dht.begin();
pinMode(ENB, OUTPUT);
digitalWrite(ENB, LOW);
Serial.begin(9600);
Serial.println("strat");
Serial1.begin(9600); // 사용자 스마트폰
Serial3.begin(9600); // 거치된 스마트폰
}
unsigned long ppast = 0;
void loop() {
hum = dhtfunc('h');
temp = dhtfunc('t');
if (millis() - past2 > waterdly && waterState == 3) {
waterOnOff(0);
}
if (Serial1.available()) { // 사용자 스마트폰 수신 파트
int dump = Serial1.read();
waterOnOff(1, 3);
past2 = millis();
}
/////////////////////////// 테스트용 코드
if (millis() - ppast > 300) {
ppast = millis();
Serial.print(hum);
Serial.print("\t\t\t");
Serial.print(temp);
Serial.print("\t\t\t");
Serial.println(waterState);
}
////////////////////////////
// 습도 기준 워터펌프 작동 유뮤 부분
if (hum == -1 || temp == -1) {
// 사용자 스마트폰 전송
Serial1.write(-1); // 전송 시작 구분자
Serial1.write(-99); // 습도 전송
Serial1.write(-99); // 섭씨 온도 전송
// 거치 스마트폰 전송
Serial3.write(-1); // 전송 시작 구분자
Serial3.write(-99); // 습도 전송
Serial3.write(-99); // 섭씨 온도 전송
if (waterState == 0) { // 모터 상태 전송
Serial3.write(-10);
Serial3.write(0);
} else {
Serial3.write(-10);
Serial3.write(10);
}
past = millis();
} else {
if (hum < hum_criticalPoint && waterState == 0) waterOnOff(1);
if (hum > hum_criticalPoint && waterState == 1) waterOnOff(0);
}
// 스마트폰 통신 부분
if ((millis() - past) >= interval) { // 스마트폰으로 현재 습도 및 온도 전송(interval 마다 반복)
// 사용자 스마트폰 전송
Serial1.write(-1); // 전송 시작 구분자
Serial1.write(hum); // 습도 전송
Serial1.write(temp); // 섭씨 온도 전송
// 거치 스마트폰 전송
Serial3.write(-1); // 전송 시작 구분자
Serial3.write(hum); // 습도 전송
Serial3.write(temp); // 섭씨 온도 전송
if (waterState == 0) { // 모터 상태 전송
Serial3.write(-10);
Serial3.write(0);
} else {
Serial3.write(-10);
Serial3.write(10);
}
past = millis();
}
delay(5);
}
자동 급수 기능
MLX90614 모듈 사용을 위해 <Adafruit_MLX90614.h> 라이브러리, 그래픽 LCD 사용을 위해 <U8glib.h> 라이브러리를 사용했습니다.
라이브러리 다운로드 및 사용 방법은 아두이노 라이브러리 문서를 확인해주세요.
GY-906 비접촉 온도 센서(MLX-90614)는 물체에서 방사되는 적외선을 측정하여 온도로 계산합니다.
측정 물체 재질, 환경, 거리에 따라 적외선 방사율이 달라지기 때문에 보정이 필요할 수 있습니다.
특히 거리의 경우 2cm 이상 시점부터는 오차 범위가 커지는 것을 체온 테스트로 확인했습니다.
본문에서는 30번 측정 후 1초 간격으로 마지막으로 측정된 온도가 그래픽 LCD에서 깜빡거리도록 설정했습니다.
측정값은 보정 단계별로 3%씩 증가하거나 감소하여 최종 결과값으로 표현됩니다.
측정값 보정 푸쉬 버튼
up, down 푸쉬버튼을 두고 측정값 보정 단계를 조절합니다.
푸쉬버튼에서 발생하는 채터링 현상을 방지하기 위한 코드를 Calibrate() 함수에 포함했습니다.
버튼을 누른 후 떨어지는 것까지 확인하여 이후 동작을 진행하는 원리입니다.
전원 스위치
해당 프로젝트 전원은 12V 어댑터를 연결하여 활용합니다.
전원 스위치 사용을 위해 어댑터의 GND와 아두이노의 GND를 연결하고, 어댑터의 VCC는 로커 스위치를 통해 아두이노에 연결되도록 했습니다.
결과
사진

Comment
아이디어 스케치와 비슷한 형태로 간단한 케이스를 MDF로 제작하여 테스트한 모습입니다.
초록색이 보정단계 up 버튼, 노란색은 보정단계 down 버튼, 빨간색은 전원 스위치입니다.
비접촉 온도 센서는 하단부에 동그랗게 구멍을 뚫어 외부에 노출되도록 했습니다.
추신
공집사의 아두이노 프로젝트 결과물은 판매되는 제품이 아니며, 프로젝트 수준에서 간단하게 진행되었습니다.
문의 및 의뢰는 크몽 공집사로 연락주시면 감사하겠습니다.