Sunday, April 12, 2015

[Node-RED] 초음파 센서 Custom Node 만들기

TOPIC : [Node-RED] 초음파 센서 Custom Node 만들기



작성일:
2015411

작성자:
최의신


1. 개요

지난번 “Node-RED 실습에서 초음파 센서를 이용하여 충돌방지 기능을 만들었다.
이것을 구현하기 위해 시리얼 포트 NodeFunction Node를 이용하였다.

이번에는 두 개의 Node를 하나의 Node로 만드는 방법을 설명한다.


2. Node 정의
초음파 센서 Node는 시리얼 포트에 연결되며, 지정된 거리(단위 cm) 이하가 검출되면 메시지를 출력한다. 이때 전송되는 메시지는 다음과 같은 형식으로 전달된다.

{
payload : 측정 거리
, alert : true
}

여기서 Node 동작에 영향을 주는 요소를 Node의 속성으로 지정한다.
속성
설명
serial
시리얼 포트를 지정한다.
threshold
충돌을 감지하는 임계치를 지정한다.
name
Node의 이름을 지정한다.




3. Node 개발
Node-RED에서 Node를 표현하기 위해서는 JavaScript 파일과 HTML 파일이 필요하다.
JavaScript 파일은 Node-RED 런타임에 실행되는 로직을 포함한다.
그리고 HTML 파일은 Node-RED editor(palette. Canvas) 상에서 표시되는 UI 구성 정보를 포함한다.

1) JavaScript
JavaScript에서는 Custom Node의 실행 로직을 담당하는 객체를 생성하고 Node-RED에 이 객체를 등록한다. 코드의 기본 구조는 다음과 같다.

module.exports = function(RED) {
    "use strict";

    function UltrasonicSensor(n) {
        // 실제 인스턴스를 생성한다.
        RED.nodes.createNode(this,n);
       
        // 여기에 Node의 동작을 구현한다.
    }

    RED.nodes.registerType("Ultrasonic",UltrasonicSensor);
}

module.exports CommonJS의 모듈 표준으로 함수나 변수를 module.exports에 할당하면 외부에서 접근할 수 있다.
, Custom Node의 기능을 Node-RED에서 require()를 이용하여 접근하게 된다.

Custom Node의 기능은 “UltrasonicSensor” 함수(생성자)에서 구현하며, RED.nodes.createNode   함수를 이용해 실제 인스턴스를 생성한다. 그리고 이것을 registerType 함수를 이용해서 Node-RED에 등록한다.
registerType 함수의 첫 번째 파리미터는 HTML 파일의 Node 속성 정의에서 지정한 RED.nodes.registerType 함수의 첫 번째 파라미터와 동일해야 한다. 만일 다른 경우 Custom Node는 동작하지 않을 것이다.

Use strict
ECMAScript 5 에서 추가된 모드로 특정 버전의 자바 스크립트에서 오류를 일으킬 만한 기능들을 사용할 수 없게 만든다.
MORE : http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
RED.nodes.createNode 함수에서 생성된 인스턴스는 이벤트 Callback 함수를 등록하여 Node-RED에서 발생하는 이벤트를 수신할 수 있다.
Callback 함수의 등록은 on 함수를 이용한다.

this.on('close', function () {
   // 이벤트 처리
});

여기서는 다음의 이벤트를 등록한다.
이벤트
설명
data
시리얼 포트에 데이터가 수신된 경우 발생한다.
ready
시리얼 포트가 사용 가능한 경우 발생한다.
closed
시리얼 포트를 사용할 수 없는 경우 발생한다.
close
Flowdeploy하거나 Node-RED가 종료되는 경우 발생한다.


2) HTML
하나의 Node를 표시하기 위해서는 HTML 파일에 3개의 <script> 태그를 정의해야 한다.

(1) 편집 방법
첫 번째 <script> Node의 속성 ID 및 속성의 입력 방식을 정의하는 것이다.
이것은 div css를 이용하여 정의하며, 속성은 “id” 부분을 node-input-<속성 ID> 같은 형식으로 정의한다.
다음의 코드는 "name" 속성으로 text 입력을 받는다.

<div class="form-row">
  <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
  <input type="text" id="node-input-name" placeholder="Name">
</div>

그리고 <i> 태그로 아이콘을 표시할 수 있으며, 다음의 URL에서 아이콘을 확인할 수 있다.

http://fortawesome.github.io/Font-Awesome/icons/

(2) 도움말
두 번째 <script> Node의 도움말을 입력하는 부분으로 "<p>" 태그을 이용한다.
만일 한글을 입력해야 하는 경우 HTML 파일의 형식을 "UTF-8"로 저장해야 한다.
그렇지 않으면 Node-RED editor(palette. Canvas) 상에서 한글이 깨질 것이다.
(3) 노드 정의
세 번째 <script> "편집 방법" 태그에서 정의한 속성을 RED.nodes.registerType 함수를 이용하여 등록한다.

<script type="text/javascript">
    RED.nodes.registerType('node-type',{
        // node definition
    });
</script>

registerType 함수의 첫 번째 파라미터는 JavaScriptregisterType 함수에서 등록한 이름과 동일한 이름이며, 두 번째 파라미터는 Node를 정의한 객체이다.
여기서 사용하는 Node 정의는 다음과 같다.

이벤트
설명
category
Node의 분류명을 지정한다.
defaults
Node의 속성을 정의한다.
inputs
입력의 개수를 나타낸다. 0 또는 1
outputs
출력의 개수를 나타낸다. 0 또는 1개 이상
icon
아이콘의 이름을 지정한다.
color
Node의 배경색을 지정한다.
label
Node에 표시되는 라벨을 지정하며, 함수를 지정하면 결과값이 표시된다.
paletteLabel
Node-RED editor palette에 표시될 라벨을 지정한다.
align
아이콘과 라벨의 정열 방향을 지정한다.

나머지 Node 정의는 다음의 URL에서 확인할 수 있다.

http://nodered.org/docs/creating-nodes/node-html.html#node-type




4. 초음파 센서 Custom Node 개발

1) JavaScript
초음파 센서는 시리얼 포트로 데이터를 전달하기 때문에 Node-RED에 있는 Serial Node를 복사하여 input에 해당되는 부분의 코드를 수정하여 구현하였다.
다음은 데이터를 수신하고, 지정된 임계치와 비교하여 결과를 출력하는 부분의 코드이다.

if (node.serialConfig.out === "char") {
    buf[i] = msg;
    i += 1;
    if ((msg === splitc[0]) || (i === bufMaxSize)) {
        var m = new Buffer(i);
        buf.copy(m,0,0,i);
        if (node.serialConfig.bin !== "bin") { m = m.toString(); }

if ( Number(n.threshold) > Number(m) )
        {
            node.send({"payload":m, "alert":true});
        }
        m = null;
        i = 0;
    }
}
else { node.log("should never get here"); }

코드에서 m 변수는 시리얼 포트로 전달된 장애물의 거리를 저장하며, n. threshold 속성은 사용자가 입력한 임계치를 저장한다.
만일 장애물의 거리가 임계치 보다 작으면 send 함수를 이용해 거리와 경고를 출력한다.
전체 코드는 첨부된 소스를 참조한다.

2) HTML
<!-- 1) Node의 속성을 정의한다. -->
<script type="text/x-red" data-template-name="Ultrasonic">
    <div class="form-row node-input-serial">
        <label for="node-input-serial"><i class="fa fa-random"></i> Serial Port</label>
        <input type="text" id="node-input-serial">
    </div>   
    <div class="form-row">
        <label for="node-input-threshold"><i class="fa fa-circle"></i> Threshold</label>
        <input type="text" id="node-input-threshold" placeholder="50">
    </div>
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
    <div class="form-tips"><b>Note:</b> 임계치 단위는 cm 입니다.</div>
</script>


<!-- 2) Node의 도움말을 등록한다. -->
<script type="text/x-red" data-help-name="Ultrasonic">
   <p>이 노드는 초음파 센서에서 측정된 장애물과의 거리를 시리얼 포트에서 읽어 들인다.</p>
   <p>측정된 거리가 지정된 임계치 보다 작으면 측정 거리와 true 값을 출력한다.</p>
</script>

<!-- 3) 단계 1)에서 정의한 속성에 대한 타입을 등록한다. -->
<script type="text/javascript">
    RED.nodes.registerType('Ultrasonic',{
        category: 'IBMer',
        color:"#B56AFF",
        defaults: {
            name: {value:""},
            serial: {type:"serial-port",required:true},
            threshold: {value:"50",required:true}
        },
        inputs:0,
        outputs:1,
        icon: "ultrasonic.png",
        label: function() {
            var serialNode = RED.nodes.node(this.serial);
            return this.name||(serialNode?serialNode.label().split(":")[0]+" TH: " + this.threshold:"serial");
        },
        labelStyle: function() {
            return this.name?"node_label_italic":"";
        }
    });   
</script>

3) 설치
첨부된 파일(.js, .html)들은 Node-RED 폴더 아래의 "nodes" 폴더로 복사한다.
하지만 setting.js 파일의 nodeDir 속성을 변경하여 설치 폴더를 바꿀 수 있다.
그리고 아이콘 파일(.png)Node-RED 폴더 아래의 "public/icons" 폴더로 복사한다.

이제 Node-RED를 실행하고 접속하면 다음과 같이 Node-RED palette에 추가된 것을 확인할 수 있다.


그리고 NodeCanvas에 추가하면 Node의 도움말 정보를 확인할 수 있다.
 


4) 실행
Ultrasonic Node의 속성을 지정하고 DEPLOY 하면 실행이 된다.




[참고자료]

[1] Node-RED
http://nodered.org/docs/creating-nodes/

[2] Node-RED 실습
http://klabcamss.blogspot.kr/2015/04/topic-node-red-2015-4-4-1.html

No comments:

Post a Comment