기술자료

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

Node.js와 BoneScript 활용하기

기술자료
DBMS별 분류
Etc
작성자
dataonair
작성일
2014-04-17 00:00
조회
5203



오픈소스 하드웨어 비글본 블랙

Node.js와 BoneScript 활용하기



지난 시간에 비글본 블랙을 소개하고 GPIO(General Purpose Input Output)를
제어하는 방법에 대해 살펴봤다. 이번 시간에는 비글본 블랙에 기본으로 설치돼 있는
Node.js와 BoneScript를 자세히 살펴보고자 한다.

또한 비글본 블랙을 인터넷과 연결해 최근 화두가 되고 있는 사물인터넷을 구현해 볼 것이다.



1회에서 소개했던 바와 같이 비글본 블랙은 개발언어로 서버 사이드 언어인 Node.js를 이용하는 특징을 가지고 있다. 또 자바스크립트로 GPIO를 제어할 수 있게 해주는 BoneScript라는 라이브러리를 제공한다는 점을 지난 시간에 소개했다. 이와 같은 특성 덕분에 비글본 블랙을 이용해 웹과 관련된 프로토타입을 쉽게 구현할 수 있다.



사물인터넷

2014년 1월, 라스베이거스에서 열린 CES 2014에서 사물인터넷이 주목을 받았다. 이 행사에서 삼성전자는 SHP(Smart Home Protocol)라는 독자적인 프로토콜을 소개했는데, 이 프로토콜을 이용하면 삼성전자의 스마트홈 가전제품을 웹을 이용해 제어할 수 있다. 삼성전자는 이를 통해 외부 업체를 끌어들여 사물인터넷 생태계를 구축할 계획이라고 밝혔다.

경쟁사인 LG전자는 홈챗이라는 서비스를 소개했는데, 이는 사용자가 스마트폰 메신저로 가전제품을 제어할 수 있게 해주는 서비스다. 예를 들어 사용자가 카카오톡으로 자신의 냉장고에게 음식물에 대한 정보를 물으면 냉장고가 음식물의 상태를 사용자에게 다시 알려준다.

이 외에 킥스타터에서 펀딩에 성공했던 SmartThings도 가정용 사물인터넷 제품을 전시했다. 특히 이 제품은 처음 버전보다 상당히 발전된 모습을 선보여 눈길을 끌었다. 모바일 앱이 기존보다 쉽고 편리하게 집안의 사물을 제어할 수 있도록 바뀌었다. 한 화면에서 집안에 있는 SmartThings 제품을 쉽게 확인하고 제어할 수 있도록 했고, LG의 홈챗과 같이 메신저로 가전제품을 제어하는 기능도 추가됐다. 또 소너스(Sonos)나 필립스 휴 등의 다른 사물인터넷 제품과도 연결돼 제어가 가능한 점도 이 제품의 특징이다. 그 중 가장 눈에 띄는 것은 조본 업(Jawbone UP)과의 연동이다.



tech_img1228.png

조본 업은 손목에 착용하는 밴드 형태의 헬스케어 제품으로 사용자의 활동을 기록하고 관리하는 제품이다. 조본 업을 착용한 사용자가 집안에서 이동하면 SmartThings가 조본 업으로부터 위치정보를 수집해 사용자 근처의 가전제품을 자동으로 작동시킨다. 덕분에 사용자는 가전제품을 제어하기 위해 매번 주머니에서 스마트폰을 꺼내야 하는 번거로움을 줄일 수 있게 됐다.

같은 달 CES 2014 외에도 사물인터넷과 관련된 큰 사건이 있었다. 바로 구글이 네스트라는 벤처기업을 약 3조4,000억 원에 인수한 것이다. 이 사건은 한동안 IT 시장을 시끌벅적하게 했다. 네스트는 이제 막 3년이 된 스타트업이었고, 제품이라고는 겨우 2개밖에 없었기 때문이다. 더군다나 최근에 나온 제품인 화재경보기의 영향력이 크지 않음을 고려하면 실제적으로 이 회사의 제품은 온도조절기 하나라고 볼 수 있다. 또한 IT업계에서 회사를 인수할 때는 대개 기존 매출액의 1.5~2배로 인수가격을 책정하는데, 네스트의 경우 기존 매출액의 10배에 해당되는 액수로 인수됐다. 언론은 이번 네스트의 인수와 관련해 네스트의 직원 300명 전원이 모두 애플 출신이라는 점이 큰 영향을 줬을 것이라고 보도했다. 물론 그 견해에 동의하지만 네스트의 주력 모델인 온도조절기를 살펴보면 그 외에 다른 이유가 있음을 찾을 수 있다.

네스트의 온도조절기는 사용자가 원하는 온도를 설정하면 보일러의 온도를 조절해주는 제품이다. 여기까지는 일반적인 보일러 온도조절기와 다른 것이 없다. 하지만 네스트의 온도조절기는 인터넷에 연결돼 새롭고 다양한 서비스를 제공한다. 먼저 사용자가 온도를 조절할 때마다 온도조절기가 사용자의 패턴을 학습하고 어느 정도 시간이 지나면 사용자가 제어하지 않아도 스스로 방안의 온도를 최적으로 유지시킨다. 그리고 인터넷에 연결돼 있기 때문에 사용자가 스마트폰으로 방안의 상태를 확인할 수 있고 외부에서도 방안의 온도를 제어할 수 있다. 솔직히 이 제품에 최첨단 소프트웨어나 하드웨어 기술이 사용된 것은 아니다. 단지 기존 온도조절기를 인터넷에 연결해 새로운 서비스를 잘 만들어준 것뿐이다. 하지만 그것이야말로 구글이 네스트를 거액에 인수한 진짜 이유라고 할 수 있다. 네스트 외에 앞서 언급했던 삼성전자, LG전자, SmartThings의 제품들 모두는 사물과 인터넷을 연결해 새로운 서비스를 만들어내는 것이 핵심 목표다. 이처럼 다양한 사물을 인터넷에 연결하는 것이 점차 중요한 이슈로 떠오르고 있다.



오픈소스 하드웨어의 웹 연결

사물인터넷과 관련해 오픈소스 하드웨어 진영에서도 단순히 오프라인으로 센서와 액추에이터를 제어하는 것 외에 인터넷 연결을 통한 다양한 시도들이 중요해지고 있다. 특히 최근에는 인터넷에 연결되지 않는 제품이 거의 없다고 할 수 있을 정도다. 기본적으로 이더넷이 장착돼 있어 유선으로 인터넷 연결이 가능하고, 일부 최신 모델은 WiFi가 내장돼 있어 곧바로 무선 연결이 가능하다. 심지어 제품 내에 웹서버가 돌아가기도 한다. 비글본 블랙의 Node.js가 그 중 하나다. 비글본 블랙 외에 아두이노 YUN이나 라즈베리 파이도 웹서버를 구동시켜 사용할 수 있다. 이 세 가지 제품을 어떻게 인터넷에 연결해 활용할 수 있는지 간단히 살펴보자.



아두이노 YUN

아두이노 YUN은 한 보드에 아두이노와 리눅스가 모두 포함돼 있는 제품이다. 이 둘은 서로 브릿지를 이용해 데이터를 주고받는다. 그리고 WiFi가 내장돼 있어 인터넷에 무선으로 연결할 수 있다. 아두이노 YUN은 기본적으로 웹서버가 구동되기 때문에 인터넷에 연결된 상태라면 웹브라우저에서 프로그램이 작동하는 것을 확인할 수 있다.

아두이노 YUN에서 웹과 관련된 스케치를 작성하기 위해서는 먼저 SD카드를 준비해야 한다. SD카드에 /arduino/www/라는 빈 폴더를 생성한 뒤 스케치를 작성해 업로드하면 /arduino/ www/ 밑에 스케치의 이름으로 폴더가 생성된다. 이 폴더에 기본 HTML 파일과 jQuery를 압축시킨 zepto.js 파일 등이 복사된다. 이후 웹브라우저에서 arduino.local/sd/[스케치명]으로 이동하면 작성된 프로그램이 돌아가는 것을 확인할 수 있다.



<리스트 1> 라이브러리 설정#include < Bridge.h>
#include < YunServer.h>
#include < YunClient.h>

스케치에서 Bridge, YunServer, YunClient 이 3개의 라이브러리가 필요하다. ‘스케치 - 라이브러리 가져오기...’를 이용하거나 <리스트 1>과 같이 프로그램 상단에 추가하면 된다.


<리스트 2> 브릿지 시작Bridge.begin();

스케치의 setup 함수에 <리스트 2>를 추가한다. 아두이노와 리눅스를 브릿지로 연결하는 코드다. 단, 서버가 리눅스에서 구동되는 것이기 때문에 서버를 제어하기 전에 브릿지를 먼저 연결해야 한다.



<리스트 3> 서버 연결 모드 설정 및 시작server.listenOnLocalhost(); // 동일한 네트워크만 연결 가능하도록 설정
server.begin();

마찬가지로 setup 함수에 <리스트 3>을 추가한다. 여기서 listenOnLocalhost()를 사용하면 동일한 네트워크에서만 연결이 가능하다. 만약 noListenOnLocalhost()를 사용하면 다른 네트워크에서도 연결할 수 있다.



<리스트 4> loop 함수 내에 들어갈 코드YunClient client = server.accept();
// 클라이언트 인스턴스를 생성한다.if (client) { // null 체크
String command = client.readString();
// arduino.local/arduino/[명령]에서 [명령]부분만 추출 command.trim();
// 공백 제거 if (command == "do_something")
client.print("I did something!!");
// GET 요청이 들어온 곳으로 "I did something!!" 전달

client.stop(); // 연결 해제
}
delay(50); // 50ms 멈춤

스케치의 loop 함수에 <리스트 4>를 추가한다. 만약 클라이언트가 서버 쪽에 요청을 하면 YunClient 인스턴스가 할당된다. 예로 앞서 웹브라우저에서 arduino.local/sd/[스케치명]으로 접속이 가능하다고 설명했는데, 이와 같이 접속된 웹브라우저에서 다시 arduino.local/arduino/[명령]으로 GET을 요청하면 서버에서는 요청이 왔다고 인식하게 된다. 그러면 스케치가 server. accept()를 호출할 때 클라이언트 인스턴스가 생성된다. 인스턴스를 받았다면 readString()을 호출해 뒤의 명령 부분만 추출해내고, 추출한 명령 부분을 이용해 아두이노가 특정 동작을 하도록 구현하면 된다. <리스트 4>에서는 명령이 “do_something”인 경우 client.print(“I did something!!”)이 실행되도록 했는데, “I did something”이 앞서 웹브라우저에서 GET 요청을 한 곳으로 전달된다.

아두이노 YUN은 이와 같이 웹 프로그램을 상당히 간편하게 짤 수 있다. 기존에 스케치를 작성하던 대로 코드를 작성하면 되고, 웹페이지 쪽에서는 jQuery를 이용해 GET 요청에 대한 부분을 처리하면 된다. 그리고 기타 센서, 액추에이터와 관련된 로직은 스케치에서 명령문을 받는 곳에 추가하면 된다.



라즈베리 파이

라즈베리 파이는 비글본 블랙과 같이 리눅스 OS가 구동된다. 기본적으로 이더넷을 지원하지만, WiFi를 지원하지 않기 때문에 필요시에는 WiFi 동글을 연결해야 한다. 라즈베리 파이는 비글본 블랙이나 아두이노 YUN과 달리 웹서버가 기본적으로 돌아가지 않는다. 따라서 사용자가 직접 이를 설치해 사용해야 한다. 리눅스이기 때문에 자신이 원하는 웹서버를 설치할 수 있는데, 일반적으로 APM(아파치, PHP, MySQL)을 설치해 사용한다.

필자는 APM이 아닌 WebIOPI라는 라이브러리를 소개하고자 한다. WebIOPI는 오픈소스 라이브러리로 웹을 이용해 라즈베리 파이를 쉽게 제어할 수 있게 해준다. WebIOPI를 설치하기 전에 파이썬이 2.7인지 먼저 확인한 후 업데이트를 한다. 준비가 됐으면 code.google.com/p/webiopi/에 있는 설치파일을 라즈베리 파이에 다운로드한다. 압축돼 있는 설치파일의 압축을 해제하고 setup.sh 파일을 실행하면 된다.



<리스트 5> WebIOPI 서비스 실행webiopi start

tech_img1229.png

설치가 완료됐다면 <리스트 5>와 같이 WebIOPI를 실행시킨다. 그 다음 웹브라우저에서 라즈베리 파이 IP주소의 8000번 포트로 접속하면 계정을 묻는 창이 나타날 것이다. 아이디는 webiopi, 비밀번호는 raspberry를 입력한다. 인증이 완료되면 <그림 2>와 같은 메인메뉴가 나타나는데, 여기서 GPIO Header로 이동하면 라즈베리 파이와 관련된 기본적인 제어를 할 수 있다.

WebIOPI를 이용하면 아두이노 YUN과 유사하게 프로그램을 짤 수 있다. WebIOPI가 설치된 webiopi 폴더로 이동하면 하위에 htdocs 폴더가 있음을 확인할 수 있다.



<리스트 6> script.py 코드import webiopi// 처음 시작할 때 호출
def setup
...// 무한 반복
def loop
...
webiopi.sleep(5)
// 5초 딜레이// 종료될 때 호출
def destroy
...

script.py 코드는 <리스트 6>과 같이 작성한다. 기본적인 구성을 살펴보면, 아두이노 스케치와 유사하게 setup, loop가 있고 destroy라는 함수가 있다. setup과 loop는 아두이노의 스케치에서 사용하는 것과 동일한 것으로 설정, 반복과 관련된 함수다. destroy는 WebIOPI가 종료될 때 호출된다. 코드의 시작 부분에 WebIOPI 라이브러리를 불러오도록 코드를 작성하면 된다.



<리스트 7> script.py에서 매크로 함수 선언하기@webiopi.macro // 매크로 함수
def MacroFunc():
...


<리스트 8> index.html에서 WebIOPI 매크로 호출하기webiopi().callMacro("MacroFunc", [], callback);
// callMacro(매크로명, 변수, 콜백)



<리스트 9> index.html에서 매크로 호출하는 버튼 태그 생성하기button = webiopi().createMacroButton("macro", "Left", "MotorLeft");
// createMacroButton("macro" 고정, 버튼에 표시할 텍스트, 매크로명)
content.append(button);



그리고 웹브라우저 쪽에서 호출할 수 있도록 script.py 코드에 <리스트 7>과 같은 매크로 함수를 설정한다. 이렇게 정의된 함수는 웹브라우저 쪽 자바스크립트 코드에서 <리스트 8>과 같이 바로 호출할 수 있고, <리스트 9>와 같이 매크로를 호출하는 버튼을 생성해 웹페이지 화면에 추가할 수도 있다.



<리스트 10> index.html에 webiopi.js 참조하기

단, 웹브라우저에서 자바스크립트로 WebIOPI를 사용하기 위해서는 <리스트 10>과 같이 선언해야 한다. 지금까지 WebIOPI를 이용해 라즈베리 파이의 웹 프로그램을 작성해 봤다. 라즈베리 파이는 리눅 패키지를 설치해서 웹 프로그램을 작성할 수도 있다.



비글본 블랙

이번에는 비글본 블랙으로 웹 프로그램을 작성해 보겠다. 기본적으로 비글본 블랙에는 Node.js를 개발할 수 있는 ‘클라우드9’이라는 웹 앱용 개발툴이 설치돼 있다.



tech_img1230.png

비글본 블랙을 컴퓨터에 연결하고 웹브라우저에서 192.168. 7.2:3000/으로 이동하면 <그림 3>과 같이 클라우드9이 뜨는 것을 볼 수 있다. 이 클라우드9을 사용해 바로 코드를 작성하고 곧바로 웹에서 실행해 볼 수도 있다. 간단히 비글본 블랙의 USER LED를 제어하는 것을 직접 해보도록 하겠다. 우측 상단에 ‘+’버튼을 눌러서 새 문서를 생성한다.



<리스트 11> USER LED를 제어하는 코드// BoneScript를 불러온다.
var b = require('bonescript');
// USER LED 4개 모두 출력 상태로 전환
b.pinMode('USR0', b.OUTPUT);
b.pinMode('USR1', b.OUTPUT);
b.pinMode('USR2', b.OUTPUT);
b.pinMode('USR3', b.OUTPUT);
// USER LED 4개를 모두 켠다.
b.digitalWrite('USR0', b.HIGH);
b.digitalWrite('USR1', b.HIGH);
b.digitalWrite('USR2', b.HIGH);
b.digitalWrite('USR3', b.HIGH);
// 2초 뒤에 restore 함수를 호출하도록 설정
setTimeout(restore, 2000);// USER LED 초기화 함수
function restore() {
var p = '/sys/class/leds/beaglebone:green:usr';
// USER LED를 4개 모두 끈다
b.digitalWrite('USR0', b.LOW);
b.digitalWrite('USR1', b.LOW);
b.digitalWrite('USR2', b.LOW);
b.digitalWrite('USR3', b.LOW);
// resetUSR0 함수를 호출한다.
// resetUSR0 함수가 호출되면
// 순서대로 아래 함수들이 호출된다.
resetUSR0();

function resetUSR0() {
// 지정 경로에 'heartbeat'라고 기록
b.writeTextFile(p+'0/trigger', 'heartbeat', resetUSR1);
}
function resetUSR1() {
b.writeTextFile(p+'1/trigger', 'mmc0', resetUSR2);
}
function resetUSR2() {
b.writeTextFile(p+'2/trigger', 'cpu0', resetUSR3);
}
function resetUSR3() {
b.writeTextFile(p+'3/trigger', 'mmc1', complete);
}
function complete() {
}
}

<리스트 11>과 같이 코드를 작성한다. <리스트 11>은 4개의 USER LED가 모두 켜진 후 4초가 지나면 다시 초기화하도록 하는 코드다. run 버튼을 눌러서 이를 실행해 본다. 만약 run 버튼이 아닌 debug 버튼으로 돼 있다면 디버그 모드 옵션을 끈 뒤 run으로 변경한 후에 실행한다. 실행하면 곧바로 비글본 블랙이 제어되는 것을 확인할 수 있다.

이어서 간단한 웹 프로그램을 작성해 보겠다. 현재 비글본 블랙의 IP가 192.168.7.2로 잡혀 있는데, 192.168.7.2:9000으로 이동하면 ‘Hello, beaglebone black!’이 출력되도록 할 것이다.



<리스트 12> HTTP 서버 실행하기// http 라이브러리 사용
var http = require('http');
// 서버 생성
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
// 응답으로 다음 텍스트를 출력한다.
res.end('Hello, bealgebone black!\n');
}).listen(9000, '192.168.7.2');
// 9000번 포트를 연다.

새 문서를 생성하고 <리스트 12>와 같이 작성한다. run 버튼을 눌러 실행하고 웹브라우저를 통해 이동하면 <그림 4>과 같은 화면을 볼 수 있다. 만약 추가적으로 비글본 블랙의 센서와 액추에이터를 제어하고 싶다면 요청이 들어오는 부분에 BoneScript를 이용해 해당 제어 로직을 추가하면 된다.

tech_img1231.png

지금까지 아두이노 YUN, 라즈베리 파이, 비글본 블랙을 이용해 웹 프로그램을 작성해 봤다. 이를 통해 세 제품 모두 웹에서 요청이 들어왔을 때 센서와 액추에이터를 제어하는 프로그램을 쉽게 만들 수 있음을 알 수 있었다. 이처럼 오픈소스 하드웨어를 이용한 웹 프로그램 개발 환경이 점차 좋아지고 있다. 덕분에 이제 누구나 네스트의 온도조절기나 SmartThings의 가정용 사물인터넷 제품과 같은 것을 어렵지 않게 구현할 수 있다. 실제로 네스트의 온도조절기를 구현할 수도 있다. 스파크 블로그(goo.gl/IuPAeZ)에는 스파크 코어라는 오픈소스 하드웨어를 이용해 네스트의 온도조절기와 거의 유사한 제품을 만드는 방법이 나와 있다.



Node.js

앞서 소개했듯이 비글본 블랙은 개발 언어로 Node.js를 사용한다. Node.js는 최근 크게 주목받고 있는 서버 사이드 언어라고 할 수 있는데, 이미 링크드인, 페이팔, 이베이, 페이스북 같은 사이트에 사용되고 있다. Node.js는 클라이언트 사이드의 대표 언어인 자바스크립트로 프로그래밍을 하고, 언어의 특성상 비동기 방식으로 구현된다. 또한 크롬 브라우저에도 탑재돼 있는 V8 엔진을 사용하는데, 이 V8 엔진은 다음과 같은 특징을 가지고 있다.

먼저 자바스크립트를 바이트코드로 컴파일하거나 인터프리터로 실행하기 전에 실제 환경에 맞는 기계어로 컴파일한다. 또한 인라인 캐싱이라는 최적화 기법을 사용하고 있어 메소드 또는 클래스를 분석해 재사용이 가능한 코드는 캐시에 저장하고, 이를 통해 불필요한 작업을 제거한다. 이런 특징 덕분에 Node.js는 상당히 빠른 성능을 보여준다. 현재까지의 기록으로는 동시접속자 수 25만 명에 성공했고, 초당 2만 번의 트래픽 테스트도 통과했다. 그리고 아파치와의 성능비교에서도 거의 3배 이상의 속도차를 보여줬다. 비글본 블랙에서 사용되는 Node.js는 다음과 같은 장점이 있다.

첫 번째, 비글본 블랙과 같은 오픈소스 하드웨어에서 돌리기에 부담이 적다. <리스트 12>에서도 보았듯이 몇 줄의 코드만으로 HTTP 서버를 돌릴 수 있는데, 이 점은 비글본 블랙과 같은 오픈소스 하드웨어에 상당히 중요하다고 할 수 있다. 비글본 블랙, 아두이노 YUN, 라즈베리 파이 등의 성능이 많이 좋아졌다고는 하지만, 실제 사물인터넷과 관련된 프로토타입을 구축하면 웹서버도 구동시켜야 하고 각종 센서와 액추에이터를감해진다. 또한 오픈소스 하드웨어에서 구동되는 웹서버가 상당히 무거운 작업을 요하는 것이 아니기 때문에 경량화된 Node.js를 사용하는 것이 좋다. 그런 점에서 비글본 블랙에 사용되는 Node.js는 비글보드 재단이 기존의 몇몇 기능을 제거해 비글본 블랙에 맞게 한번 더 최적화시킨 버전이다.

두 번째, 다양한 써드파티 모듈이 존재한다. 2014년 2월 13일을 기준으로 5만8,962개의 모듈이 존재한다. 기본 라이브러리만으로도 원하는 기능을 거의 다 구현할 수 있지만, 만약 기능이 없는 경우 써드파티 모듈을 활용해 쉽게 개발할 수 있다. 이 써드파티 모듈은 NPM(Node Packaged Modules)을 이용해 쉽게 사용할 수 있으며, 이를 통해 얻을 수 있는 생산성 향상은 비글본 블랙이 실제 프로토타입 용도라는 점을 고려할 때 중요한 요소로 작용한다. 비글본 블랙은 개발자가 원하는 기능을 쉽고 빠르게 구현할 수 있게 해주는 하드웨어 플랫폼으로, 비글본 블랙을 사용하는 사람은 주로 프로토타입 하드웨어를 만들기 위한 목적으로 이를 사용한다고 볼 수 있다. 여기에 NPM을 이용할 수 있게 되면서 단순히 하드웨어뿐만이 아닌 소프트웨어적으로도 자신이 원하는 것을 더 빨리 구현할 수 있게 된다.

세 번째, 하드웨어와 소프트웨어 그리고 웹서비스가 모두 동일한 언어로 개발된다. Node.js는 자바스크립트를 사용하며, 이 자바스크립트는 클라이언트 사이드에서 독보적으로 사용되는 언어이다. 따라서 Node.js는 자바스크립트 개발자가 서버 사이드와 클라이언트 사이드 양쪽 개발을 병행할 수 있게 해주는 장점을 가지고 있다. 만약 동시에 개발하지 않고 각각 다른 사람이 맡아서 개발을 한다고 해도 언어가 동일하기 때문에 서로간에 로직이나 데이터를 맞추는 것이 쉬워진다. 비글본 블랙은 BoneScript라는 자바스크립트 라이브러리를 제공함으로써 자바스크립트로 하드웨어도 제어할 수 있다. 이를 통해 하드웨어, 소프트웨어 그리고 웹서비스의 모든 레이어를 일관성 있게 관리할 수 있다. 이와 관련해 네스트의 온도조절기를 다시 한 번 살펴보면, 네스트의 온도조절기는 핵심이 하드웨어에만 국한된 것이 아니다. 하드웨어, 소프트웨어 그리고 웹서비스가 서로 유기적으로 조화를 이룸으로써 그와 같은 제품이 만들어진 것이다. 이와 같은 경쟁력을 갖는 데 있어서 전체를 볼 줄 아는 것이 상당히 중요하다고 할 수 있는데, 비글본 블랙은 Node.js와 BoneScript를 사용하기 때문에 모든 레이어를 동일한 언어로 사용할 수 있고 덕분에 하드웨어, 소프트웨어, 웹서비스 전체를 쉽게 볼 수 있다는 장점을 가진다. 물론 Node.js를 사용할 때 비동기방식으로 인해 개발이 어려워질 수 있다는 단점도 있다. 비글본 블랙은 단순히 하나의 센서나 액추에이터만 사용하는 경우보다 여러 개의 센서와 액추에이터를 동시에 연결하고 제어하는 경우가 많다. 이런 경우 다음과 같은 이슈가 발생할 수 있다. 사용자가 동시에 여러 센서의 값을 요청한다거나 또는 여러 액추에이터의 제어를 요청하는 것이다. 예로 사용자가 비글본 블랙의 8번 헤더의 18, 19, 20의 센서값을 요청한다고 가정해보겠다.


<리스트 13> 비동기방식의 Node.js// BoneScript 불러오기
var b = require('bonescript');
// 모두 입력상태로 전환
b.pinMode('P8_18', b.INPUT);
b.pinMode('P8_19', b.INPUT);
b.pinMode('P8_20', b.INPUT);// P8_18의 값을 콜백을 이용해 읽는다.
b.digitalRead('P8_18', readP818);function readP818(x) {

// P8_18의 값 저장
var p818 = x.value;

// P8_19의 값을 콜백을 이용해 읽는다.
b.digitalRead('P8_19', readP819);

function readP819(x) { // P8_19의 값 저장
var p819 = x.value;

// P8_20의 값을 콜백을 이용해 읽는다.
b.digitalRead('P8_20', readP820);

function readP820(x) {
// P8_20의 값
var p820 = x.value; // 콘솔에 출력
console.log("P8_18 : "+p818);
console.log("P8_19 : "+p819);
console.log("P8_20 : "+x.value);
}
}
}

Node.js는 비동기로 구현해야 하기 때문에 <리스트 13>과 같이 작성해야 한다. 핀의 센서값을 읽어오는 digitalRead 함수가 콜백을 통해 값을 전달하기 때문에 사용자에게 요청한 3개 센서의 값을 동시에 알려주기 위해서는 콜백 안에 다시 다른 요청을 하도록 해야 한다. 반대로 사용자가 동시에 3개의 액추에이터를 제어하려고 할 때도 <리스트 13>과 같이 구성해야 사용자에게 성공 여부를 동시에 전달할 수 있다.

물론 이와 같은 단점도 존재하지만 비글본 블랙과 같은 오픈소스 하드웨어에서는 다른 웹서버에 비해 Node.js가 사용하기에 적합하다고 할 수 있다. 실제로 비글본 블랙뿐만이 아니라 아두이노와 라즈베리 파이에서도 Node.js를 많이 사용한다. 하지만 비글본 블랙은 최적화한 Node.js와 BoneScript 라이브러리가 기본으로 설치돼 있어서 제품 수령 후 즉시 개발이 가능하다는 차이점이 있다.



BoneScript

BoneScript는 Node.js에서 비글본 블랙의 하드웨어를 제어하기 위해 제공되는 라이브러리다. 명령어의 이름이나 쓰임을 보면, 아두이노와 상당히 유사하게 만들어졌음을 알 수 있다. 비글본 블랙 공식 홈페이지의 BoneScript 페이지(beagleboard. org/Support/BoneScript/)에 가면 BoneScript에 대한 함수와 예제들이 잘 정리돼 있다. 만약 비글본 블랙이 PC에 연결돼 있는 상태라면 웹브라우저 상에서 바로 예제를 실행해 볼 수 있다. 그리고 github.com/jadonk/bonescript에 들어가면 BoneScript의 소스 코드도 볼 수 있다.



BoneScript 사용법

<리스트 14> 라이브러리 불러오기var b = require('bonescript');

BoneScript를 사용하려면 먼저 <리스트 14>와 같이 라이브러리를 불러와야 한다. 여기서 라이브러리가 선언된 변수는 함수를 호출하거나 상수를 사용할 때 쓰인다. 자주 사용하는 함수는 다음과 같다.

- pinMode (pin, direction)
- pin : 핀 번호
- direction : INPUT(입력), OUTPUT(출력), INPUT_PULLUP(입력 설정 후 풀업으로 고정)



<리스트 15> 핀의 모드 설정// 8번 헤더 13번 핀을 출력으로 설정
b.pinMode("P8_13", b.OUTPUT);

pinMode는 핀의 모드를 설정하는 함수다. 여기서 핀 번호를 8번 헤더의 13번이라고 가정했을 때 P8_13과 같이 입력한다. 모드는 INPUT, OUTPUT, INPUT_PULLUP 세 가지가 존재한다. 여기서 INPUT과 INPUT_PULLUP은 동일한 입력이지만 저항을 설정하는 것에서 차태를 LOW, 전압이 3.3V인 상태를 HIGH라고 하는데, 그냥 INPUT으로 설정한 경우에는 하이임피던스 상태가 돼서 전압이 LOW와 HIGH 사이에 왔다갔다 하게 된다. 이로 인해 하드웨어가 해당 핀이 LOW인지 HIGH인지 정확히 구분하지 못하게 되므로 INPUT_PULLUP은 전압을 HIGH에 고정시켜주는 것이다. INPUT_PULLUP이 아닌 INPUT을 사용하는 경우에는 전압을 고정시키기 위해 별도로 풀업이나 풀다운을 구현해야 한다. 옵션으로 먹스(mux), 풀업(pullup), 슬류(slew) 비율을 설정할 수도 있고, 마지막에 콜백을 지정하면 성공 여부를 받을 수 있다.

- digitalWrite (pin, value)
- pin : 핀 번호
- value : LOW, HIGH


<리스트 16> digitalWrite 함수 사용법b.pinMode("P8_13", b.OUTPUT);
// 8번 헤더 13번 핀의 전압을 HIGH로 설정
b.digitalWrite("P8_13", b.HIGH);

digitalWrite는 디지털핀의 전압을 LOW 또는 HIGH로 변경하는 함수다. 이 함수를 사용하기 전에 사용하고자 하는 핀이 디지털핀으로 돼 있는지 확인하고, pinMode 함수를 이용해 출력 모드로 설정해줘야 한다. digitalWrite 함수를 이용하면 핀을 HIGH로 설정해 전원으로 사용하거나, 또는 LOW로 설정해 그라운드로 사용할 수도 있다.

- digitalRead (pin, callback)
- pin : 핀 번호
- callback ( x ) : x.value(값), x.err(에러)



<리스트 17> digitalRead 함수 사용법b.pinMode("P8_13", b.INPUT);
b.digitalRead("P8_13", callback);function callback(x){
// 디지털핀 전압
console.log('x.value = ' + x.value);
// 에러 확인
console.log('x.err = ' + x.err);
}

digitalRead 함수는 디지털핀의 전압을 읽는 함수이고 콜백을 이용해 값을 읽어온다. 콜백이 호출됐을 때 매개변수의 value 속성이 0이면 LOW, 1이면 HIGH를 뜻한다. 이 함수를 사용하기 전에 pinMode 함수를 이용해 핀을 입력모드로 설정해야 하고, 하이임피던스 상태가 되지 않게 하기 위해 풀다운 또는 풀업 상태로 만들어줘야 한다.

- analogWrite (pin, value)
- pin : 핀 번호
- value : 0~1



<리스트 18> analogWrite 함수 사용법// PWM핀에서 HIGH는 1.8V
// 9번 헤더 14번 핀의 전압을 0.7 * 1.8V로 설정
b.analogWrite('P9_14', 0.7);

analogWrite는 전압을 단순히 LOW와 HIGH가 아니라 그 사이의 원하는 값으로 변경하는 함수이다. 예로 전압은 0이 LOW, 1이 HIGH라고 가정했을 때, 0.2나 0.7 등으로 설정하는 것이다. 이 함수를 사용하려면 핀이 PWM핀인지 확인해야 하지만, 디지털핀과 같이 pinMode 함수를 이용해서 모드를 설정할 필요는 없다. analogWrite 함수의 PWM(pulse width modulation) 구현 원리는 임의로 100초에 해당하는 주기가 존재한다고 가정했을 때 앞에 30초 동안에는 전압을 HIGH로 설정하고, 뒤에 70초 동안에는 전압을 LOW로 설정함으로써 마치 전압이 0.3인 것 같이 만드는 것이다. 옵션으로 주기(frequency)를 설정할 수도 있다.

- analogRead (pin, callback)
- pin : 핀 번호
- callback ( x ) : x.value(값), x.err(에러)



<리스트 19> analogRead 함수 사용법b.analogRead("P9_36", callback);function callback(x){
// PWM 전압
console.log('x.value = ' + x.value);
// 에러 확인
console.log('x.err = ' + x.err);
}
}

analogRead는 PWM핀의 전압값을 읽는 함수다. 0과 1 사이의 값이 들어오는데, 1이 1.8V라고 가정하고 계산하면 된다.

- attachInterrupt (pin, handler, mode, callback)
- pin : 핀 번호
- handler : 콜백 호출 여부, 그냥 true로 설정하면 된다.
- mode : RISING, FALLING, CHANGE
- callback ( x ) : x.value(값), x.err(에러)



<리스트 20> attachInterrupt 함수 사용법// 8번 헤더 19번 핀을 입력으로 설정
b.pinMode("P8_19", b.INPUT);
// 8번 헤더 19번 핀에 전압이 변경될 때
// 인터럽트가 발생하도록 설정
b.attachInterrupt("P8_19", true, b.CHANGE, interruptCallback);function interruptCallback(x) {
// 핀에 대한 정보값 출력
console.log(JSON.stringify(x));

attachInterrupt는 디지털핀의 변화가 감지됐을 때 인터럽트가 발생하도록 설정하는 함수다. 여기서 변화란 세 가지가 있는데, RISING은 LOW에서 HIGH로, FALLING은 HIGH에서 LOW로, CHANGE는 RISING 또는 FALLING이 일어났을 때를 말한다. 이 함수는 지금도 개발 중이기 때문에 사용하기 전에 꼭 문서를 확인하고 사용하는 것이 좋다. 우선 여기서는 항상 인터럽트 콜백을 받는다고 가정하고 handler의 변수를 true로 고정한다. 변화가 감지돼 인터럽트가 발생하면 지정된 콜백으로 상태 정보값이 날라온다. 인터럽트를 이용하면 핀의 상태 변화를 확인하기 위해 매번 반복문을 사용해 확인할 필요가 없다는 장점이 있다.

- detachInterrupt (pin)
- pin : 핀 번호



<리스트 21> detachInterrupt 함수 사용법// 8번 헤더 19번 핀의 인터럽트 해제
b.detachInterrupt("P8_19");



비글본 블랙의 경쟁력

비글본 블랙의 경쟁력은 Node.js와 BoneScript를 활용해 사물인터넷 프로토타입을 쉽게 구현할 수 있다는 것이다.
국내에서도 최근 비글본 블랙에 대한 관심이 많아져 비글본 블랙을 사용하는 사람들이 늘어났지만,
사람들의 사용기를 보면 거의 다 CNC나 3D 프린터를 제어하는 용도로 사용하는 경우가 많다.


반면에 해외에서는 비글본 블랙을 활용해 주로 로봇이나 사물인터넷과 관련된 것을 만든다(youtu.be/dEes9k7-DYY).
결론적으로 비글본 블랙은 다른 하드웨어 플랫폼과 비교했을 때 사물인터넷 프로토타입을 구현하기에 좋은 환경을 가지고 있다고 할 수 있다.