TOPIC : [Node-RED]
온도와 습도 실시간 모니터링
작성일:
|
2015년
4월 13일
|
|
작성자:
|
최의신
|
1. 개요
이번에는 DHT22 센서를 이용한 온도와 습도를 실시간으로 모니터링 하는 것을 만들 것이다.
DHT22 센서의 값을 읽는 것은 ATtiny85를
이용하며, 이 값은 시리얼 포트로 Node-RED 서버로
전송이 된다.
전송되는 온도와 습도의 JSON 형식은 다음과 같다.
{
"temperature":23.12, "humidity":45 }
|
2. 환경 구성
1) 개발 환경
l Windows
7
l Node.js
– v0.10.37
l Node-RED
– v0.10.4
l Arduino
IDE 1.0.6
Arduino 1.0.6에서 ATtiny85 링커에 문제가 있어 오류가 발생한다.
다음의 URL에서 ATtiny85 패치를 다운받아 Arduino IDE에 적용한다.
http://forum.arduino.cc/index.php/topic,116674.0.html
|
2) 회로도
3) 부품
l USB
To Serial : 1개
l ATtiny
85 : 1개
l DHT22
: 1개
4) 구현
3. Arduino Source
ATtiny85에서 DHT22 센서를
사용하려면 Arduino에서 기본적으로 제공하는 라이브러리는 사용할 수 없다. 다음의 URL에서 다운로드 하여 라이브러리에 적용한다.
http://playground.arduino.cc/Main/DHTLib
|
|
4. Node-RED 구성
온도와
습도를 모니터링 하기 위한 Node-RED 구성은 다음과 같다.
Node
|
설명
|
실시간 온도,습도 모니터링
|
Node-RED 서버에서 GET /tempchart
요청을 수신한다. 즉 웹 서버의 역할을 하게 된다.
|
온도,습도 차트
|
요청에
대한 응답 문서를 생성한다.
응답문서는 WebSocket으로 전달된 데이터를 차트 입력으로 전달하는 JavaScript를
포함한다.
|
Tempchart
|
요청에 대한 응답 문서를 전송한다.
|
온도센서
|
ATtiny85에서 전송된 온도, 습도
데이터를 수신하는 시리얼 포트이다.
|
온도,습도 전송
|
시리얼 포트에서 전달된 데이터를 WebSocket에 연결된 클라이언트로 전송한다.
|
Import
Source
|
Flow를 구성하는 소스는 첨부된 temp.json 파일을
참조한다.
그리고 Node-RED의 Import 기능을 이용해 쉽게 입력할 수 있다.
|
[{"id":"435211f1.bcadf","type":"websocket-listener","path":"/ws/tempchart","wholemsg":"false"},{"id":"6509f941.05888","type":"serial-port","serialport":"COM6","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false},{"id":"13e94a7d.ec16b6","type":"serial in","name":"온도센서","serial":"6509f941.05888","x":152,"y":198,"z":"da8cdc72.b6d95","wires":[["ae363af8.51c9c8"]]},{"id":"ae363af8.51c9c8","type":"websocket out","name":"온도,습도 전송","server":"435211f1.bcadf","client":"","x":413,"y":198,"z":"da8cdc72.b6d95","wires":[]},{"id":"d956b81c.26a948","type":"http in","name":"실시간 온도,습도 모니터링","url":"/tempchart","method":"get","x":137,"y":89,"z":"da8cdc72.b6d95","wires":[["16e164bf.e91e9b"]]},{"id":"16e164bf.e91e9b","type":"template","name":"온도,습도 차트","field":"payload","template":"<!DOCTYPE HTML>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta HTTP-EQUIV=\"CACHE-CONTROL\" CONTENT=\"NO-CACHE\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>실시간 온도, 습도 측정기</title>\n <link rel=\"stylesheet\" href=\"//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.css\" />\n <script src=\"//code.jquery.com/jquery-1.11.1.min.js\"></script>\n <script src=\"//code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.js\"></script>\n <script src=\"//cdnjs.cloudflare.com/ajax/libs/highcharts/4.0.4/highcharts.js\"></script>\n\n <script>\n var chart; // 온도\n var chart2; // 습도\n\n if(location.protocol==\"https:\"){\n var wsUri=\"wss://\"+window.location.hostname+\":1880/ws/tempchart\";\n } else {\n var wsUri=\"ws://\"+window.location.hostname+\":1880/ws/tempchart\";\n }\n var ws=null;\n\n function wsConn() {\n ws = new WebSocket(wsUri);\n ws.onmessage = function(m) {\n console.log('[@.@] ' + new Date().toLocaleString() + m.data);\n if (typeof(m.data) === \"string\" && m. data !== null){\n var msg =JSON.parse(m.data);\n var today = new Date();\n today.setHours(today.getHours() + 9);\n var t = today.getTime();\n chartAddPoint([t, msg.temperature], [t, msg.humidity]);\n }\n }\n ws.onopen = function() {\n console.log(\"[@.@] connecting...\");\n }\n ws.onclose = function() {\n ws = null;\n setTimeout(wsConn, 10000);\n }\n ws.onerror = function(){\n console.log(\"[@.@] connection error\");\n }\n }\n wsConn();\n\n function chartAddPoint(tval, hval)\n {\n var series = chart.series[0],\n shift = series.data.length > 20;\n chart.series[0].addPoint(eval(tval), true, shift);\n \n var series2 = chart2.series[0],\n shift2 = series2.data.length > 20;\n chart2.series[0].addPoint(eval(hval), true, shift2);\n }\n\n $(function() {\n // 온도\n chart = new Highcharts.Chart({\n chart: {\n renderTo: 'temp',\n defaultSeriesType: 'spline',\n\n },\n title: {\n text: '실시간 온도 데이터'\n },\n xAxis: {\n type: 'datetime',\n tickPixelInterval: 120,\n maxZoom: 20 * 1000\n },\n yAxis: {\n minPadding: 0.2,\n maxPadding: 0.2,\n title: {\n text: '온도 ( °C )',\n margin: 20\n }\n },\n series: [{\n name: '온도',\n data: []\n }]\n });\n // 습도\n chart2 = new Highcharts.Chart({\n chart: {\n renderTo: 'humi',\n defaultSeriesType: 'spline',\n\n },\n title: {\n text: '실시간 습도 데이터'\n },\n xAxis: {\n type: 'datetime',\n tickPixelInterval: 120,\n maxZoom: 20 * 1000\n },\n yAxis: {\n minPadding: 0.2,\n maxPadding: 0.2,\n title: {\n text: '습도 ( % )',\n margin: 20\n }\n },\n series: [{\n name: '습도',\n data: []\n }]\n });\n\n });\n </script>\n</head>\n<body>\n <div id=\"temp\" style=\"width: 100%; height: 300px; margin-left:-5px;\"></div>\n <div id=\"humi\" style=\"width: 100%; height: 300px; margin-left:-5px;\"></div>\n</body>\n</html>","x":412,"y":89,"z":"da8cdc72.b6d95","wires":[["96792a32.6986d8"]]},{"id":"96792a32.6986d8","type":"http response","name":"tempchart","x":658,"y":88,"z":"da8cdc72.b6d95","wires":[]}]
|
위 노드의
동작을 간단하게 살펴보면 “실시간 온도,습도 모니터링”, “온도,습도 차트”, “tempchart”
노드들은 웹 서비스를 위한 구성으로 “http://127.0.0.1:1880/tempchart” 주소로
접속한 사용자에게 웹 페이지를 전송한다.
전송된
웹 페이지에는 WebSocket으로 연결을 시도하며, 연결이
성공한 경우 온도와 습도 데이터를 수신하게 된다. <클라이언트 역할>
if(location.protocol=="https:"){
var
wsUri="wss://"+window.location.hostname+":1880/ws/tempchart";
}
else {
var wsUri="ws://"+window.location.hostname+":1880/ws/tempchart";
}
|
“온도센서”, “온도,습도 전송” 노드들은 시리얼 포트로 전송된 온도와 습도 데이터를 WebSocket으로 연결된 클라이언트에 전송한다 <서버 역할>
5. 실행
temp.json
파일의
내용이 정상적으로 Import 되었다면 CMD 창에서 다음의
명령을 수행한다.
D:\node-red-0.10.4>node
red.js
|
Node-RED
서버
기동이 완료되면 브라우저로 다음의 주소에 접속한다.
http://127.0.0.1:1880/tempchart
|
정상적으로
수행이 되고 있다면 다음과 같은 화면을 볼 수 있을 것이다.
[참고자료]
[1] DHT22
No comments:
Post a Comment