요즘 IoT 니 홈 오토메이션이니 말이 많아서 저도 시류에 편승해보고자, 가장 많이들 시도해보는 집안 온습도 측정 예제를 만들어 봤습니다.

먼저 WiFi 모듈들을 테스트 해봤는데.. 가격이 싸면 안정성과 조작성이 너무 나쁘고, 그나마 사용하기 쉽고 안정적인 모듈들은 너무 비싼게 흠이었습니다. 그래서 집에서 노는 안드로이드 폰을 이용해 봤습니다. 아두이노에서 블루투스로 보내주는 메시지를 읽어서 특정 메시지가 오면 특정 서버로 HTTP request를 날려주는 방식입니다.

서버 준비

먼저 우리가 보낼 데이터를 받아서 저장하고, 이쁘게 그래프로 그려주는 서버가 필요합니다. 이런류의 작업을 해주는 cloud server 로 xively, thingspeak 가 있습니다. xively 회원가입을 어떻게 하는지 모르는 관계로(!!) 가입이 간단한 thingspeak를 이용했습니다.

ThingSpeak_logo

서버 사용방법은 쉽습니다. thingspeak.com 에서 가입하시고 [channel]을 생성합니다. [Channel Settings] 탭에서 이름 적당히 넣어주고 Field1, Field2 (온도, 습도용) 를 사용가능한 상태로 만들어주고 save channel 하시면 됩니다. [Private View] 탭으로 가시면 Field1, Field2 차트가 보이실겁니다. 서버에 값을 주기적으로 던져주면 언제든 웹상으로 온습도를 모니터링 할 수 있습니다. 아… [API Keys] 탭에서 채널키(API key) 값을 따로 메모해 두세요. HTTP request 할 때 필요합니다.

하드웨어 구성

이제 하드웨어를 만듭니다.

temp2

하드웨어 구조는 간단합니다. 아두이노+온습도센서(DHT11)+블루투스(HC-06) 을 연결한겁니다. 연결방법은…

아두이노 – 블루투스 : 5V – VCC, GND – GND, D2 – TX, D3 – RX

아두이노 – 온습도센서 : 3.3V – VCC, GND – GND, D5 – pin5

동작 시나리오 및 아두이노 코드

온습도 센서는 DHT11 라이브러리를 이용해서 간단히 값을 읽을 수 있습니다. 아두이노에서 온습도 값을 읽으면 블루투스를 통해 아래와 같이 2개의 메시지를 날려줍니다. (채널키 값은 앞서 메모해둔 API 키 입니다.)

thingspeak:key=채널키&field1=온도[*]

thingspeak:key=채널키&field2=습도[*]

안드로이드 폰에서는 BT Chat 이라는 앱을 실행시켜줍니다. BT Chat 은 블루투스로 특정 문자열이 들어오면 HTTP request를 날리도록 만들어뒀습니다. 아두이노에서 전해준 key=xxx&field1=xxx 형태의 문자열을 분리해서 HTTP request의 파라미터로 이용합니다. 실제로 아래와 같은 형태로 request를 날립니다.

http://184.106.153.149/update?key=xxx&field1=xxx

184.106.153.149 서버가 thingspeak 서버입니다. 위 주소를 복사해서 값을 적당히 바꿔준 후, 브라우저를 통해 접속해도 값이 업데이트 됨을 아실 수 있습니다.

위와같은 동작 시나리오를 아두이노 코드로 옮기면 아래와 같은 코드가 됩니다.

#include <DHT11.h>
#include <SoftwareSerial.h>


int pin=5;    // DHT11 temperature sensor
DHT11 dht11(pin); 

SoftwareSerial Bluetooth(2, 3);  // Bluetooth RX, TX 

void setup()
{
  Bluetooth.begin(9600);
}

void loop()
{
  int err;
  float temp, humi;
  if((err=dht11.read(humi, temp))==0)
  {
    // Send information
    Bluetooth.print("thingspeak:key=xxx&field1=");
    Bluetooth.print((int)temp);
    Bluetooth.print("[*]");

    delay(20000);    // sleep to avoid massive HTTP request

    Bluetooth.print("thingspeak:key=xxx&field2=");
    Bluetooth.print((int)humi);
    Bluetooth.print("[*]");
  }
  else
  {
    Bluetooth.println();
    Bluetooth.print("DHT11 Error No :");
    Bluetooth.print(err);
  }
  //lastCheck = current;
  delay(20000);    // sleep to avoid massive HTTP request
}

간단합니다. 단 온도 메시지를 블루투스로 전송하고 delay() 함수를 통해 20초간 sleep 을 줬다는 점에 유의하세요. 테스트 해보니 thingspeak 서버에 이보다 빠르게 HTTP request 전송을 반복하면 거절당합니다. 정상적으로 처리된 경우 response로 DB에 저장된 갯수가 오지만, 문제가 있는 경우 0으로 옵니다.

안드로이드 앱 설정

원래 BT Chat 이란 앱은 간단한 아두이노-안드로이드 채팅용으로 만들어둔 앱입니다. 여기에 특정 문자열을 받으면 HTTP request가 가능하도록 기능을 추가해 뒀습니다. 아래와 같이 동작합니다. 아두이노에서 전해준 메시지의 빨간색 부분을 request 파리미터로 이용합니다.

인식하는 문자열 형식 : thingspeak:key=xxx&field1=xxx[*]

HTTP Request 변환 : http://184.106.153.149/update?key=xxx&field1=xxx

집에 남는 폰에 BT Chat 앱을 깔아두고, 아두이노와 페어링 시켜준 뒤 “Run in background” 옵션을 켜둡니다. 그럼 알아서 잘 동작할겁니다.

BT Chat 앱은 Google Play에 올려뒀습니다. “bt chat 아두이노” 로 검색하시거나 아래 링크로 받으실 수 있습니다.

https://play.google.com/store/apps/details?id=com.hardcopy.btchat

물론 소스코드 공개되어 있습니다. 적당히 수정해서 사용하고 싶으시면…

https://github.com/godstale/BTChat

온습도 그래프 확인

데이터가 잘 넘어간다면 그대로 한참 놔두세요. 그럼 아래와 같은 그래프가 나올겁니다. 제 경우는 잘 동작하네요.

temp

아두이노 소스코드에 20초 간격으로 HTTP request를 하도록 설정되어 있는데.. 이건 테스트 용이라 그런거고 실제로 사용할 때는 간격을 분 단위로 늘려서 사용하세요. 혹은 30분에 한번씩 최고, 최저값 삭제한 평균을 내서 보내면 더 정확한 값이 기록될 듯 합니다.

좀 위회적인 방법으로 IoT(?), 홈 오토메이션을 구현해 봤는데요.. 이런 방식을 사용하면 여러대의 아두이노를 폰과 붙이기가 힘듭니다. 폰과 연결된 아두이노를 허브 역할을 하도록 해야하는 단점이 있긴합니다. 집에 남는 폰이 없다면 그것도 좀 곤란한 문제가 되겠네요. 암튼 난이도가 높지 않아서 DIY 실습용으로는 해볼만한  프로젝트가 아닌가 싶습니다.

참고자료 :