전문가칼럼

DBMS, DB 구축 절차, 빅데이터 기술 칼럼, 사례연구 및 세미나 자료를 소개합니다.

사물인터넷의 빅데이터 레시피 (4회 최종회) : 실전 사물인터넷 응용 서비스 개발

전문가칼럼
빅데이터 분류
빅데이터일반
작성자
dataonair
작성일
2014-08-26 00:00
조회
10422




◎ 연재기사 ◎


사물 인터넷과 맛있는 데이터: 정보 레시피 (1회)


사물 인터넷의 빅데이터 레시피(2회): 사물 인터넷의 빅데이터 관리: 시계열 데이터베이스(OpenTSDB)


사물 인터넷의 빅데이터 레시피 (3회) : 사물 인터넷의 빅데이터 요리법: 머신 러닝


사물인터넷의 빅데이터 레시피 (4회 최종회) : 실전 사물인터넷 응용 서비스 개발



사물인터넷의 빅데이터 레시피 (4회 최종회)

실전 사물인터넷 응용 서비스 개발



지영민 (yangsamy@gmail.com) - 분당 야탑 영장산 산자락에 자리 잡은 전자부품연구원에서 마늘과 쑥을 먹으면서 곰에서 사람으로 환골탈태하여 세상 밖으로 나가기 위해 사물인터넷 빅데이터 연구에 인고의 시간을 보내고 있다. 마음은 자유로운 영혼이나 자본주의의 노예에서 벗어나지 못함을 한탄하며 찾아올지 모르는 미래의 풍류낭 같은 인생을 꿈꾸며 오늘도 연구에 매진하고 있다.



사물인터넷 실전 응용 서비스 개발

필자가 연재를 기획하면 마지막에는 뭔가 따라 해볼 수 있는 예제를 만드는 것이 좋겠다는 생각을 했다. 그래서 최종 회의 제목을 ‘실전 사물인터넷 응용 서비스 개발’이라고 거창하게() 정했다. 막상 글을 쓰려고 하니 하드웨어, 네트워크, 클라우드 서버, 클라언트까지 그 영역이 너무나 방대했다. 이렇게 많은 내용을 어렵지 않게 쉽게 해볼 수 있는 방법이 무엇이 있을까 고민했다. 생각 끝에 다음과 같이 사물인터넷 실전 응용 서비스를 직접 개발해 보면 어떨까 하는 결론에 이르렀다.

1. 하드웨어: 오픈소스 하드웨어 플랫폼(아두이노)
2. 네트워크: Wifi(아두이노용 Wifi 모듈 사용)
3. 클라우드 서버: PubNub 데이터 스트림 서버
4. 클라이트: HTML5와 Javascript

이 글에서 다룰 실전 응용프로그램을 간략히 설명하면 다음과 같다. 함께 만들 사물인터넷 기기에서 온습도를 센싱해 그 데이터를 인터넷으로 클라우드 서비스로 전송한다. 개발할 서비스에서 이 데이터 스트림을 받아 온습도 정보를 받아 볼 최종 사용자(클라이언트)에게 전송하는 시스템이다.



사물인터넷 클라우드 서버 PubNub 연동하기

우선 IoT 하드웨어가 붙을 수 있는 인터넷 서버인 PubNub 서비스에 대해 알아보자. 이어서 채널을 생성해 우리가 만든 IoT 하드웨어의 데이터 스트림을 수신할 수 있도록 서비스를 준비해 보자.



PubNub 서비스로 클라우드 연동

column_img_1368.jpg
▲ PubNub 데이터 스트림 서버(http://www.pubnub.com)

우선 서비스를 이용하려면 회원 가입을 해야 한다. 다음과 같이 회원 정보를 입력해 가입을 완료하면, 이용에 필요한 채널과 키를 받을 수 있다.

column_img_1369.jpg
▲ PubNub 가입

가입을 마치고 나면, 데이터 스트림을 처리할 수 있는 기본 채널이 생성된다. 필자는 기본 채널의 이름을 IoT 하드웨어에서 받을 정보인 ‘Temperature’로 생성해 보았다.

column_img_1370.jpg
▲채널 이름 설정(Dev Console에서 변경)

채널 이름을 설정했으면, 이 채널로 데이터가 잘 전송되는지 확인을 해야 한다. PubNub에서는 Rest API를 통해 브라우저에게 스트림을 전송하는 방법을 지원한다. 브라우저에 다음과 같은 규칙으로 데이터를 전송해 보자.



http://pubsub.pubnub.com
/publish
/pub-key
/sub-key
/signature
/channel
/callback
/message
(참고: http://www.pubnub.com/http-rest-push-api/)



위 규칙으로 발급받은 공개키(pub-key), 서브키(sub-key), 채널(channel) 정보를 사용해 API를 구성하면 다음과 같다. ▷http://pubsub.pubnub.com/publish/pub-c-2d1ff461-5e21-4974-bdb1-347d81590fc1/sub-c-4b5048bc-a562-11e2-8282-12313f022c90/0/temperature/0/%22test%22 필자의 공개키(pub-key)와 서브키(sub-key)를 독자 여러분께 공개했는데, 문제가 생기면 다시 변경하기로 하고 일단 여기에 공개한다. 이를 보면 ‘주소/데이터 생성/공개키/하위키/서명(0)/채널/콜백(0)/전송 데이터’로 구성된 것을 알 수 있다. 여기서 채널은 위에서 생성한 temperature이고, 서명과 콜백은 사용하지 않아 0으로 설정한다.

column_img_1371.jpg
▲ 브라우저에서 본 PubNub 데이터 전송 테스트 화면

데이터를 전송하면 JSON 형식으로 응답이 오며, 이를 브라우저에서 확인할 수 있다.

column_img_1372.jpg
▲ Dev 콘솔 화면에서 데이터 수신 확인

이 테스트를 하기 위해서는 데이터를 전송할 클라이언트 브라우저와 위에서 채널 이름을 설정했던 PubNub Dev 콘솔 두 가지가 떠 있어야 한다. Message 창에서 temperature 채널에서 ‘test’ 데이터 스트림을 수신한 것을 확인할 수 있다. 여기까지가 준비가 되면, 일단 클라우드 서비스에서의 서버 준비는 완료된 것이다. 이제 위 Rest API를 통해 IoT 하드웨어에서 센싱한 데이터를 데이터 스트림으로 연결하는 방법에 대해 살펴보자.



사물인터넷 하드웨어 만들기

최근 몇 년 사이에 오픈소스 하드웨어 플랫폼이 많은 사랑을 받고 있다. 그 중 가장 각광 받는 하드웨어 플랫폼인 아두이노를 갖고 사물인터넷 하드웨어를 구성해 보자. 아두이노를 사용한 이유는 국내에 이미 많은 사용자가 있고, 쉽게 구매할 수 있기 때문이다. 따라서 이 글을 읽는 독자들 가운데 사물인터넷 응용서비스를 직접 구축해 보고 싶다면, 아래 링크를 참고해 제품을 구매하기 바란다. 하드웨어는 다음과 같이 아두이노 레오나르도, 무선 와이파이 모듈, 센싱 모듈 세 가지로 구성된다. 아두이노 레오나도는 메인 프로세서 역할을 하며, 와이파이 모듈과센싱 모듈을 제어하게 된다. 와이파이 모듈은 인터넷과 연결하기 위함이고, 센싱 모듈은 온습도를 파악하는 역할을 한다. 가장 범용적인 센서 모듈을 선택했다. 각 하드웨어의 자세한 사양은 인터넷을 통해 쉽게 접할 수 있으므로 여기서는 소개하지 않는다.

column_img_1373.jpg
▲ 아두이노 레오나르도 (출처:http://www.devicemart.co.kr/goods/view.phpseq=35707)

column_img_1374.jpg
▲ 와이파이 모듈 (출처:http://www.devicemart.co.kr/goods/view.phpseq=1112572)

column_img_1375.jpg
▲ DHT22 온습도 센서 (출처: http://www.devicemart.co.kr/goods/view.phpseq=1112664) 이것으로 세 가지 하드웨어를 모두 준비했다고 하자. 이제 아두이노 개발환경을 설치해 보자. 우선 아두이노 IDE를 설치를 해야 한다. http://arduino.cc/en/main/software에서 자신의 컴퓨터에 맞는 인스톨 버전을 설치한다.

column_img_1376.jpg
▲ 아두이노 IDE 설치하기

설치가 완료되면, 아두이노 IDE를 실행해 보자. 다음과 같은 첫 화면을 볼 수 있을 것이다. 이것으로 하드웨어 개발을 위한 모든 환경은 준비가 끝났다. 계속해서 아두이노 IDE를 실행해 보자.

column_img_1377.jpg
▲ 아두이노 IDE
이두이노 IDE가 실행됐다면, 하드웨어 개발을 위한 개발환경 준비가 끝난 것이다. 우선 스케치 이름을 설정해 자신만의 프로젝트 환경을 설정한다. 필자는 IoT_example이라는 이름으로 설정해 다음과 같이 저장했다.

column_img_1378.jpg
▲ 스케치 폴더를 IoT_example로 저장

계속해서 각 센서와 와이파이 모듈을 제어하는 드라이버를 내려 받아 프로젝트에 사용할 준비를 해 보자. 우선 온습도 센서 모듈 제어 소스코드를 내려 받아 필요한 파일을 프로젝트에 포함시켜 보자.

column_img_1379.jpg

▲ 온습도 센서 모듈 제어 소스코드 다운로드 (http://www.dfrobot.com/wiki/index.php/DHT22_Temperature_and_humidity_module_SKU:SEN0137) 온습도 센서 모듈의 라이브러리 파일은 위 경로에서 내려 받을 수 있다. 내려 받은 소스코드에서 DHT22.cpp 및 DHT22.h를 아래와 같이 스케치에 넣자.

column_img_1380.jpg
▲ 온습도 센서 라이브러리 추가(DHT22.cpp / DHT22.h)

다음은 와이파이 모듈의 제어 라이브러리를 내려 받아 스케치에 추가한다. 아래 링크에서 내려 받는다.
- 라이브러리 파일 경로: http://www.seeedstudio.com/wiki/images/f/fc/Wizfi250.zip
- 위키의 Fi250 사용법: http://www.seeedstudio.com/wiki/Wifi_Shield_(Fi250)

내려 받은 Debug.h, WizFi250.cpp, WizFi250.h 세 가지 라이브러리 코드 파일을 스케치에 추가한다.

column_img_1381.jpg
▲ WiFi 모듈 라이브러리에 추가 (WizFi250.h / WizFi250.cpp / Debug.h)

이 같이 준비가 완료되면, 아두이노를 통해 하드웨어 모듈을 제어할 수 있는 환경 준비가 끝난 것이다. 이제 IoT_example에 센서 모듈과 와이파이 모듈을 초기화하고, 값을 읽고 이를 인터넷으로 전달하는 코드를 만들어 보자.

column_img_1382.jpg
▲ 아두이노 프로젝트 구성 화면

#include
#include
#include "WizFi250.h"
#include "DHT22.h"
#define SSID "Your SSID" //Set your SSID
#define KEY "Your AP Key" //Set your phrase
#define AUTH "WPA2" // Set the encrypt type
#define TSN_HOST_IP "54.249.82.170" //http://pubsub.pubnub.com
#define TSN_REMOTE_PORT 80
#define LOCAL_PORT 9000
#define spi_CS 8
WizFi250 wizfi250(&Serial1);
boolean returnValue=false;
// Data wire is plugged into port 4 on the Arduino
// Connect a 4.7K resistor between VCC and the data pin (strong pullup)
#define DHT22_PIN 4
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);
char *http_get_request = "GET /publish/pub-c-2d1ff461-5e21-4974-bdb1-347d81590fc1/
sub-c-4b5048bc-a562-11e2-8282-12313f022c90/0/temperature/0/%hi.%01hi HTTP/1.1\r\n"\
"Host: pubsub.pubnub.com\r\n"\
"Connection: keep-alive\r\n\r\n";
boolean start_flag = 0;
void setup(void)
{
//start serial port
Serial.begin(9600);
Serial1.begin(115200);
while (!Serial);
wizfi250.reset();
pinMode(spi_CS,OUTPUT);
digitalWrite(spi_CS,HIGH);
Serial.println("--------- IoT Hardware Start --------");
delay(1000);
Serial.println("Join " SSID );
delay(1000);
while (!wizfi250.join(SSID, KEY, AUTH)) {
Serial.println("Failed join " SSID);
Serial.println("Please Restart");
}
wizfi250.clear();
while (!wizfi250.connect(TSN_HOST_IP,TSN_REMOTE_PORT,LOCAL_PORT)) {
Serial.println("Reconnecting.. to the PubNub");
}
start_flag = 1;
}
void loop(void)
{
DHT22_ERROR_t errorCode;
// The sensor can only be read from every 1-2s, and requires a minimum
// 2s warm-up after power-on.
delay(2000);
if(start_flag == 1) {
Serial.print("Sending Sensing Data...");
errorCode = myDHT22.readData();
switch(errorCode)
{
case DHT_ERROR_NONE:
char buf[500];
sprintf(buf, http_get_request, myDHT22.getTemperatureCInt()/10, abs(myDHT22.getTemperatureCInt()%10));
wizfi250.send(buf);
delay(5);
char c;
for(int i=0;i<320;i++){
if (wizfi250.receive((uint8_t *)&c, 1, 100) > 0) {
Serial.print((char)c);
}
}
sprintf(buf, "\r\nInteger-only reading: Temperature %hi.%01hi C, Humidity %i.%01i %% RH",
myDHT22.getTemperatureCInt()/10, abs(myDHT22.getTemperatureCInt()%10),
myDHT22.getHumidityInt()/10, myDHT22.getHumidityInt()%10);
Serial.println(buf);
break;
case DHT_ERROR_CHECKSUM:
Serial.print("check sum error ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
break;
case DHT_BUS_HUNG:
Serial.println("BUS Hung ");
break;
case DHT_ERROR_NOT_PRESENT:
Serial.println("Not Present ");
break;
case DHT_ERROR_ACK_TOO_LONG:
Serial.println("ACK time out ");
break;
case DHT_ERROR_SYNC_TIMEOUT:
Serial.println("Sync Timeout ");
break;
case DHT_ERROR_DATA_TIMEOUT:
Serial.println("Data Timeout ");
break;
case DHT_ERROR_TOOQUICK:
Serial.println("Polled to quick ");
break;
}
}
}



모든 소스코드 준비가 완료됐다. 그럼 아두이노 IDE 개발환경에서 현재 우리가 사용하는 보드를 설정해 컴파일과 다운로드가 이루어질 수 있게 설정하자. 보드를 설정하고 도구 → 시리얼 포트에서 현재 접속된 아두이노가 어떤 시리얼 포트번호에 연결돼 있는지도 설정해 줘야 한다. 참고로 아두이노 레오나르도는 부트로더 부팅 중에 시리얼 포트 번호와 끝난 후 장치로 인식되었을 때의 포트번호가 다르게 인식됨을 알아 두자.



column_img_1383.jpg
▲ 아두이노 보드 선택 화면

위 화면의 왼쪽 상단의 화살표 버튼을 클릭하면, 다운로드 후 실행된다. 다운로드가 완료된 후 우측 상단에 시리얼 모니터를 클릭하면, 아래와 같이 시리얼로 아두이노 보드에서 동작하는 내용을 확인할 수 있다.

column_img_1384.jpg
▲ 시리얼로 아두이노 보드에서 동작하는 내용 확인

아두이노 보드가 와이파이 모듈을 통해 AP 접속이 완료되면, 센싱 모듈에서 센싱한 온도 값을 앞서 설정한 PubNub 서버로 전송한다. PubNub 서버의 Dev Console에서 아래와 같이 이 내용을 확인할 수 있다.

column_img_1385.jpg
▲ PubNub에서 온도 값 수신 확인

서비스 응용 클라이언트

마지막으로 사물인터넷 하드웨어에서 센싱된 온도 정보를 받아 볼 수 있는 클라이언트를 만들어 보자. PubNub 서비스에서 제공하는 라이브러리를 사용해 쉽게 만들 수 있다. 다양한 예제들을 제공하고 있는데, 그 중 가장 보편적으로 쉽게 사용할 수 있는 Javascript를 사용해 브라우저에서 값을 받아 보는 예제를 다음과 같이 만들어 보았다. 단순히 html 파일만 있으면, 스마트폰에서 자신의 집안 온도를 체크할 수 있다.



< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
< html>
< head>
< meta http-equiv="Content-type" content="text/html; charset=utf-8" />
< title>Document Write Testcase< /title>
< /head>
< script src=http://cdn.pubnub.com/pubnub.min.js >< /script>
< script>(function(){
var pubnub = PUBNUB.init({
publish_key : 'pub-c-2d1ff461-5e21-4974-bdb1-347d81590fc1',
subscribe_key : 'sub-c-4b5048bc-a562-11e2-8282-12313f022c90'
})
pubnub.subscribe({
channel : "temperature",
message : function(m){ console.log(m);
document.getElementById('temperature').innerHTML = m; },
connect : publish
})
function publish() {}
})();< /script>
< body>
< h1>우리집 온도< /h1>
< h2 id="temperature">< /h2>
< /body>
< /html>

위 소스 코드를 iot.html로 저장하고, 이를 브라우저에서 열어보면 다음과 같이 27.2도 값이 전송된 것을 확인할 수 있다. 이는 실시간으로 동작하기 때문에 온도 값이 변경되면, 브라우저에도 자동으로 변경된 값이 나타난다.



column_img_1386.jpg
▲ 브라우저에서 받아본 온도 값

사물인터넷 서비스 클라이언트

위 html 파일을 스마트폰의 웹 브라우저에서 보면, 다음과 같이 값이 조회되는 것을 확인할 수 있다.

column_img_1387.jpg
▲ 스마트폰 브라우저를 통한 클라이언트 실행 화면

사물인터넷 빅데이터 레시피 연재를 마치며

사물인터넷과 빅데이터 분석을 주제로 한 연재를 4회에 걸쳐서 진행했다. 연재를 시작할 때 필자의 바람은 기술적-경험적 내용을 정리해 전달하는 것이었다. 하지만 이 연재의 최종회를 쓰는 시점에는 당초 계획이 것이 잘 이뤄졌는지 의문의 들면서 필자의 부족함을 더 많이 깨우친 것 같다. 시간이 더 허용되었다면 많은 것을 더 정리-전달해 드리고 싶었는데 그렇지 못한 것 같아 아쉬움도 많이 남는다. 이런 아쉬움은 다른 경로를 통해 여러분들과 또 소통하게 될 기회가 있을 거라는 믿음으로 위로하며 연재를 마무리한다. 언제든지 필자의 메일과 연락처는 공개도 있으니 관련 분야의 질문이나 논의가 있으면, 자유롭게 연락을 주고 받았으면 한다. 그럼 그 동안 부족한 글을 읽어 주신 여러분께 진심으로 감사의 말을 전한다.

column_img_1388.jpg
▲ 아두이노 및 하드웨어 모듈

column_img_1389.jpg
▲ 하드웨어 모둘 결합

column_img_1390.jpg
▲ 온습도 센서 모듈

column_img_1391.jpg
▲ 아두이노와 온습도 센서 연결 예시

- 인터넷에 나오는 연결 모습과 실제 모듈의 VCC/GND의 위치가 뒤바뀌어 있음
- 연결할 때 위 실제 모듈 사진처럼 가운데가 VCC이므로 이를 유의해야 함.
- 본 예제에서는 GPIO 4번 핀으로 데이터를 읽었기 때문에 아래 사진에서처럼 7번 말고 4번으로 연결해야 함

column_img_1392.jpg
▲ 아두이노와 온습도 센서 연결 화면