<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트 &#187; NT-ARSv1</title>
	<atom:link href="http://www.ntrexgo.com/archives/tag/nt-arsv1/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ntrexgo.com</link>
	<description>엔티렉스, 디바이스마트 컨텐츠 통합 사이트</description>
	<lastBuildDate>Thu, 03 Mar 2022 06:47:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>[소스코드공개] Processing을 이용한 NT-ARSv1 모니터링 프로그램</title>
		<link>http://www.ntrexgo.com/archives/19652</link>
		<comments>http://www.ntrexgo.com/archives/19652#comments</comments>
		<pubDate>Wed, 23 Oct 2013 05:55:48 +0000</pubDate>
		<dc:creator>NTRexLAB</dc:creator>
				<category><![CDATA[--응용예제]]></category>
		<category><![CDATA[Monitoring]]></category>
		<category><![CDATA[NT-ARSv1]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[Program]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=19652</guid>
		<description><![CDATA[이번 글의 목적은 사실 Processing이라는 언어에서 저희 제품인 NT-ARSv1의 데이터를 핸들링하는 예제를 보여드릴려고 했습니다. 그런데 예제 작업을 하다보니 그냥 정식버전이라고 부르기엔 좀 약하지만 어쩌다 보니 그냥 모니터링 프로그램이 되어 버렸습니다. 그래도 Processing의 전체 소스코드도 공개하는 (사실 배포본을 만들어도 소스는 공개되지만 말이죠^^) 모양새가 되었습니다.

&#160;
이 프로그램은 자바기반의 Processing으로 만들어 졌습니다. 그래서 자바가 설치되어 있어야합니다. 윈도우에 기본으로 포함되어 있진 않아도 다들 깔려있기 때문에 별 문제없이 실행이 될겁니다. NT-ARSv1[바로가기]과의 연결은 이전에 응용예제[바로가기]에서 많이 다루었으니 그 글들을 확인하시기 바랍니다. 일단 PC와 NT-ARSv1은 잘 연결되었다고 보고 글을 적도록 하죠.
일단 프로그램부터 다운로드 받으셔야죠^^

&#160;
먼저 압축된 파일을 풀고

&#160;
하나밖에 없는 응용프로그램을 실행하시면 됩니다. Processing 에디터인 PDE프로그램에서 source 폴더에 있는 pde화일을...]]></description>
				<content:encoded><![CDATA[<p>이번 글의 목적은 사실 Processing이라는 언어에서 저희 제품인 NT-ARSv1의 데이터를 핸들링하는 예제를 보여드릴려고 했습니다. 그런데 예제 작업을 하다보니 그냥 정식버전이라고 부르기엔 좀 약하지만 어쩌다 보니 그냥 모니터링 프로그램이 되어 버렸습니다. 그래도 Processing의 전체 소스코드도 공개하는 (사실 배포본을 만들어도 소스는 공개되지만 말이죠^^) 모양새가 되었습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/0001.jpg" rel="lightbox[19652]"><img class="aligncenter size-large wp-image-19653" alt="000" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/0001-620x457.jpg" width="620" height="457" /></a></p>
<p>&nbsp;</p>
<p>이 프로그램은 자바기반의 Processing으로 만들어 졌습니다. 그래서 자바가 설치되어 있어야합니다. 윈도우에 기본으로 포함되어 있진 않아도 다들 깔려있기 때문에 별 문제없이 실행이 될겁니다. NT-ARSv1[<a href="http://www.ntrexgo.com/archives/1611" target="_blank">바로가기</a>]과의 연결은 이전에 응용예제[<a href="http://www.ntrexgo.com/archives/category/ntrex-lab/applications-ntrex-lab" target="_blank">바로가기</a>]에서 많이 다루었으니 그 글들을 확인하시기 바랍니다. 일단 PC와 NT-ARSv1은 잘 연결되었다고 보고 글을 적도록 하죠.</p>
<p>일단 프로그램부터 다운로드 받으셔야죠^^</p>
<div class="symple-box red none" style="text-align:center; width:100%;"> 
<strong>NT-ARSv1 Monitoring Program 다운로드받기 <a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/monitorNTARSv1.zip">monitorNTARSv1</a></strong><br />
</div>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/00112.jpg" rel="lightbox[19652]"><img class="aligncenter size-full wp-image-19654" alt="001" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/00112.jpg" width="599" height="185" /></a></p>
<p>&nbsp;</p>
<p>먼저 압축된 파일을 풀고</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/00212.jpg" rel="lightbox[19652]"><img class="aligncenter size-full wp-image-19655" alt="002" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/00212.jpg" width="515" height="263" /></a></p>
<p>&nbsp;</p>
<p>하나밖에 없는 응용프로그램을 실행하시면 됩니다. Processing 에디터인 PDE프로그램에서 source 폴더에 있는 pde화일을 열면 전체 소스코드를 열람하실수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/00310.jpg" rel="lightbox[19652]"><img class="aligncenter size-large wp-image-19656" alt="003" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/00310-620x457.jpg" width="620" height="457" /></a></p>
<p>&nbsp;</p>
<p>그 상태에서 AVAILABLEPORTS라는 드롭다운리스트를 열면 현재 PC에서 접근가능한 가상 COM Port의 리스트가 뜹니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/0048.jpg" rel="lightbox[19652]"><img class="aligncenter size-full wp-image-19657" alt="004" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/0048.jpg" width="419" height="253" /></a></p>
<p>&nbsp;</p>
<p>거기서 ARS가 연결된 포트를 선택해 주시면 됩니다. 본 예제를 적을때 제 PC에서는 COM14번이었습니다. 만약 잘못된 COM 포트를 선택하시면 프로그램 오류가 납니다. 물론 에러 디택팅을 통해서 다시 선택하게 할 수 있겠지만, 말씀드렸듯이 정식버젼도 아니고 또, 예제의 성격이라고 비겁하게 변명하겠습니다.ㅠㅠ. 그렇게 COM 포트까지 선택하면</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/0056.jpg" rel="lightbox[19652]"><img class="aligncenter size-large wp-image-19658" alt="005" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/0056-620x450.jpg" width="620" height="450" /></a></p>
<p>&nbsp;</p>
<p>갑자기 그래프가 그려지기 시작할겁니다. 프로그램 하단에 Roll각도와 Pitch각도를 기본으로 그리도록 되어있습니다. 보고 싶은 각도를 선택하면 됩니다. 물론 그래프별로 legend를 달았어야합니다만, 클릭한번하면 어떤 그래프인지 알 수 있기때문에 과감하게 생략했습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/0065.jpg" rel="lightbox[19652]"><img class="aligncenter size-large wp-image-19659" alt="006" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/0065-620x453.jpg" width="620" height="453" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/0074.jpg" rel="lightbox[19652]"><img class="aligncenter size-large wp-image-19660" alt="007" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/0074-620x453.jpg" width="620" height="453" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/10/0084.jpg" rel="lightbox[19652]"><img class="aligncenter size-large wp-image-19661" alt="008" src="http://www.ntrexgo.com/wp-content/uploads/2013/10/0084-620x450.jpg" width="620" height="450" /></a></p>
<p>&nbsp;</p>
<p>그리고, Pause를 누르면 그래프가 일시 정지됩니다. 또한 STOP을 누르면 ARS에 데이터를 보내지 말라는 명령(&lt;CAE&gt;)을 전송해서 데이터를 받지를 않습니다. 만들고 나서 보니 Pause버튼과 STOP 버튼이 큰 차이가 없네요.ㅠ. 아무튼 STOP버튼을 누르고 프로그램을 종료하시기 바랍니다. 그리고 한번 COM 포트를 선정했으면 다시 프로그램을 실행해서 재선택을 해야합니다. 소소한 버그인데 다음 버젼이 언제 만들어질진 몰라도 그때 반영해야할 듯 합니다.</p>
<p style="text-align: center;">
<object width="640" height="480">
<param name="allowfullscreen" value="true" />
<param name="allowscriptaccess" value="always" />
<param name="movie" value="http://www.youtube.com/v/Srf1RB_mWFM?autoplay=0&loop=0&rel=0" />
<param name="wmode" value="transparent">
<embed src="http://www.youtube.com/v/Srf1RB_mWFM?autoplay=0&loop=0&rel=0" type="application/x-shockwave-flash" wmode="transparent" allowfullscreen="true" allowscriptaccess="always" width="640" height="480">
</embed>
</object>


<p>이제 필요한 핵심적인 코드만 살짝 설명하도록 하겠습니다.</p><pre class="crayon-plain-tag">void calAngles(String s) {
  int lastPosInString = s.indexOf('&gt;');
  s = s.substring(1, lastPosInString);

  int arsResultArray[] = int(split(s, ','));

  rollAng = subset(rollAng, 1);
  pitchAng = subset(pitchAng, 1);
  rollAngVel = subset(rollAngVel, 1);
  pitchAngVel = subset(pitchAngVel, 1);

  rollAng = append(rollAng, float(arsResultArray[0])*0.001*180/PI);
  pitchAng = append(pitchAng, float(arsResultArray[1])*0.001*180/PI);
  rollAngVel = append(rollAngVel, float(arsResultArray[2])*0.001*180/PI);
  pitchAngVel = append(pitchAngVel, float(arsResultArray[3])*0.001*180/PI);   
}</pre><p>
위 함수는 가장 중요한 ARS로부터 각도 데이터를 받아서 실제 각도로 사용하는 루틴입니다. 그래프를 그리기 위해 500개의 데이터를 저장해서 그걸 반복적으로 그리도록 해서 12행부터 15행까지를 만들었습니다. 그 형태는 사용하시고자 하는 형태로 적절히 바꾸시면 됩니다.</p>
<p>일단, NT-ARSv1은 한 세트의 데이터가 &lt;, &gt;로 묶여있습니다. 그래서 indexOf()함수를 2행에서 이용해서 &gt;의 위치를 확인합니다. 그리고, 첫 글자는 &lt;이기 때문에 &lt;와 &gt;안에 있는 데이터만 가지고 오겠다는것이 3번행의 의미입니다.</p>
<p>그러면 NT-ARS가 보낸 데이터중 &lt;와 &gt;를 빼고 roll각도, pitch각도, roll각속도, pitch각속도 만 남게 됩니다. 이를 콤마(,)를 기준으로 분리(split)해서 배열로 저장하는 것이 5번행입니다. 그래서 5번행까지 실행되면 배열에 roll각도, pitch각도, roll각속도, pitch각속도가 순서대로 저장됩니다. 아직 문제가 남아 있는데요. 이렇게 저장된 값은 아직도 문자열입니다. 그래서 다시 int로 형변환을 한것입니다. Processing에서는 이렇게 해도 -부호까지 고려하기 때문에 부호에는 신경쓸 필요가 없습니다.</p>
<p>이제 12행부터 15번행까지는 같은 내용이니 12번행만 기준으로 이야기하면, ARS는 라디안단위의 각도 혹은 각속도에 1000을 곱해서 전송하기 때문에, 그래프로 표현하기 위해서 다시 0.001일 곱하고, 라디안을 디그리(degree)로 표현하기 위해 180/Pi를 곱한겁니다. 추가로 append 명령은 배열의 끝에 값을 추가하는 명령입니다. 소스코드를 보시면 아시겠지만, 하나를 추가하고 다시 제일 첫번째 값을 지우면서 전체 배열의 크기는 500을 유지하도록 되어 있습니다.</p>
<p>위에 보내드린 압축화일을 풀면 다 나오는 거지만, 전체 코드도 같이 공개합니다. 소스코드는 monitorNTARSv1.pde, arsClass.pde, initPanel.pde이렇게 세개의 화일로 되어 있습니다.</p><pre class="crayon-plain-tag">/* ****************************************************************************
This program is monitoring program of NT-ARSv1 made by NTRexLAB.
The commercial web-page of NT-ARSv1 is http://ntrexgo.com
In NT-ARSv1, commands are as follows:
  &lt;CAO&gt; : to get data at once
  &lt;CAH&gt; : to get data continuously at 10ms intervals
  &lt;CAE&gt; : to stop recieving data.
And incomming data is organized as follows:
  &lt;Roll angle, Pitch angle, Roll angular velocity, Pitch angular velocit&gt;.
The NT-ARSv1's output data are multiplying 1000 times after expressed radians.   

                                                by PinkWink in NTRexLAB
**************************************************************************** */

import controlP5.*;
import processing.serial.*;

ControlP5 cp5;
Serial arsPort;

DropdownList l;
ArsButtons pauseBt, stopBt, rollAngBt, pitchAngBt, rollAngVelBt, pitchAngVelBt;

int graphPanelXPos = 110;
int graphPanelYPos = 100;
int graphPanelXSize = 500;
int graphPanelYSize = 240;
int graphPanelYCenterPos = graphPanelYPos+graphPanelYSize/2; 
int panelGridHalfLength = 15;
int panelGridYDivision = graphPanelYSize/6;
int selectPanelXPos = graphPanelXPos;
int selectPanelYPos = graphPanelYPos+graphPanelYSize+40;
int selectPanelXSize = graphPanelXSize;
int selectPanelYSize = panelGridYDivision;
int buttonXStartPos = graphPanelXPos+60;
int buttonYPos = selectPanelYPos+selectPanelYSize/2;
int buttonXDiv = selectPanelXSize/5;

float resizingYSize = float(graphPanelYSize)/180;
float resizingAngVelYSize = float(graphPanelYSize)/1000;

float[] rollAng = new float[graphPanelXSize];
float[] pitchAng = new float[graphPanelXSize];
float[] rollAngVel = new float[graphPanelXSize];
float[] pitchAngVel = new float[graphPanelXSize];

String availablePort[];
String connectPort;

String[] graphYLabel = {"90", "60", "30", " 0", "-30", "-60", "-90"};

boolean arsConnection = false;

PFont fontText, bigfontText;

color ColorOfBackground = color(245,245,245);
color ColorOfListBoxBackground = color(190,190,190);
color ColorOfListBoxActive = color(150,150,150);
color ColorOfListBoxForeground = color(150,150,150);
color ColorOfListBoxSetColor = color(100,100,100);
color ColorOfRollAngLine = color(255,0,0);
color ColorOfPitchAngLine = color(0,255,0);
color ColorOfRollAngVelLine = color(255,100,0);
color ColorOfPitchAngVelLine = color(100,255,0);

void setup() {
  size(650, 450);

  fontText = loadFont("CenturyGothic-12.vlw");
  bigfontText = loadFont("CenturyGothic-32.vlw");

  pauseBt = new ArsButtons(graphPanelXPos, graphPanelYPos-30, false, "rec");
  stopBt = new ArsButtons(graphPanelXPos+80, graphPanelYPos-30, false, "rec");
  rollAngBt = new ArsButtons(buttonXStartPos, buttonYPos, true, "ell");
  pitchAngBt = new ArsButtons(buttonXStartPos+buttonXDiv, buttonYPos, true, "ell");
  rollAngVelBt = new ArsButtons(buttonXStartPos+buttonXDiv*2, buttonYPos, false, "ell");
  pitchAngVelBt = new ArsButtons(buttonXStartPos+buttonXDiv*3, buttonYPos, false, "ell");

  cp5 = new ControlP5(this);
  l = cp5.addDropdownList("AvailablePorts");

  comPortList(l);
}

void draw() {
  background(ColorOfBackground);
  drawGraphPanel();
  drawText();
  drawGraph();
}

void mousePressed(){
  if(mouseButton==LEFT){
    if(rollAngBt.isButtonClicked(mouseX, mouseY, 10)) {
      rollAngBt.buttonClick(); }
    if(pitchAngBt.isButtonClicked(mouseX, mouseY, 10)) {
      pitchAngBt.buttonClick(); }
    if(rollAngVelBt.isButtonClicked(mouseX, mouseY, 10)) {
      rollAngVelBt.buttonClick(); }
    if(pitchAngVelBt.isButtonClicked(mouseX, mouseY, 10)) {
      pitchAngVelBt.buttonClick(); }
    if(pauseBt.isButtonClicked(mouseX, mouseY, 10)) {
      pauseBt.buttonClick(); }
    if(stopBt.isButtonClicked(mouseX, mouseY, 10)) {
      if(stopBt.buttonClicked) {
        stopBt.buttonClick();
        arsPort.write("&lt;CAH&gt;");
        delay(20);
      }else {
        stopBt.buttonClick(); 
        arsPort.write("&lt;CAE&gt;");
        delay(20);
      }
    }
  }
}

void drawGraph() {
  noFill();  
  if (rollAngBt.buttonClicked) {
    stroke(ColorOfRollAngLine);
    strokeWeight(2);
    beginShape();
      for (int xPos=0; xPos&lt;rollAng.length; xPos++) {
        float tmp = saturatingValue(rollAng[xPos], 90);        
        vertex(xPos+graphPanelXPos, graphPanelYCenterPos - tmp*resizingYSize);
      }
    endShape();
  }
  if (pitchAngBt.buttonClicked) {
    stroke(ColorOfPitchAngLine);
    strokeWeight(2);
    beginShape();
      for (int xPos=0; xPos&lt;pitchAng.length; xPos++) {
        float tmp = saturatingValue(pitchAng[xPos], 90); 
        vertex(xPos+graphPanelXPos, graphPanelYCenterPos - tmp*resizingYSize);
      }
    endShape();
  }
  if (rollAngVelBt.buttonClicked) {
    stroke(ColorOfRollAngVelLine);
    strokeWeight(1);
    beginShape();
      for (int xPos=0; xPos&lt;rollAngVel.length; xPos++) {
        float tmp = saturatingValue(rollAngVel[xPos], 500);
        vertex(xPos+graphPanelXPos, graphPanelYCenterPos - tmp*resizingAngVelYSize);
      }
    endShape();
  }
  if (pitchAngVelBt.buttonClicked) {
    stroke(ColorOfPitchAngVelLine);
    strokeWeight(1);
    beginShape();
      for (int xPos=0; xPos&lt;pitchAngVel.length; xPos++) {
        float tmp = saturatingValue(pitchAngVel[xPos], 500);
        vertex(xPos+graphPanelXPos, graphPanelYCenterPos - tmp*resizingAngVelYSize);
      }
    endShape();
  }
}

void serialEvent(Serial p) {
  String arsValues = "";

  arsValues = arsPort.readStringUntil(10);
  if (!pauseBt.buttonClicked &amp;&amp; (arsValues != null)) {
      calAngles(arsValues);
  }  
}

float saturatingValue(float target, float limitValue) {
  float resizingResult;
  float tmp = abs(target);
  if (tmp&gt;limitValue) {
    resizingResult = target/tmp*limitValue;
  } else {
    resizingResult = target;
  }        
  return resizingResult;
}

void calAngles(String s) {
  int lastPosInString = s.indexOf('&gt;');
  s = s.substring(1, lastPosInString);

  int arsResultArray[] = int(split(s, ','));

  rollAng = subset(rollAng, 1);
  pitchAng = subset(pitchAng, 1);
  rollAngVel = subset(rollAngVel, 1);
  pitchAngVel = subset(pitchAngVel, 1);

  rollAng = append(rollAng, float(arsResultArray[0])*0.001*180/PI);
  pitchAng = append(pitchAng, float(arsResultArray[1])*0.001*180/PI);
  rollAngVel = append(rollAngVel, float(arsResultArray[2])*0.001*180/PI);
  pitchAngVel = append(pitchAngVel, float(arsResultArray[3])*0.001*180/PI);   
}

void controlEvent(ControlEvent theEvent) {

  if (theEvent.isGroup() &amp;&amp; theEvent.name().equals("AvailablePorts")){
    int connectPortNo = (int)theEvent.group().getValue();
    connectPort = availablePort[connectPortNo];
  }
  if (!arsConnection) { 
    arsPort = new Serial(this, connectPort, 115200); 
    arsConnection = true;
  }

  delay(100);  
  arsPort.write("&lt;CAH&gt;");    
}

void comPortList(DropdownList ddl) {
  availablePort = arsPort.list();

  ddl.setPosition(10, 70);
  ddl.setSize(80, 60);
  ddl.setItemHeight(15);
  ddl.setBarHeight(15);
  ddl.setColorBackground(ColorOfListBoxBackground);
  ddl.setColorActive(ColorOfListBoxActive);
  ddl.setColorForeground(ColorOfListBoxForeground);
  ddl.setValue(0);
  ddl.captionLabel().toUpperCase(true);
  ddl.captionLabel().set("AvailablePorts");
  ddl.captionLabel().setColor(ColorOfListBoxSetColor);  
  ddl.captionLabel().style().marginTop = 3;
  ddl.valueLabel().style().marginTop = 3; 

  for (int i=0; i&lt;availablePort.length; i++) {
    l.addItem(availablePort[i], i);
  }
}</pre><p>
&nbsp;</p><pre class="crayon-plain-tag">class ArsButtons {
  int posX, posY;
  String type;
  boolean buttonClicked;    
  color ColorOfClickedButton = color(150,150,150);    

  ArsButtons(int tmpX, int tmpY, boolean initValue, String tmpType) {
    buttonClicked = initValue;
    posX = tmpX;
    posY = tmpY;
    type = tmpType;

    drawButton();
  }

  boolean isButtonClicked(int X, int Y, int buttonArea) {
    boolean buttonClickedResult = false;

    if (type=="rec") {
      if(X&lt;(posX+buttonArea) &amp;&amp; X&gt;posX &amp;&amp; Y&lt;(posY+buttonArea) &amp;&amp; Y&gt;posY) {
        buttonClickedResult = true; }
    } else if (type=="ell") {      
      if(X&lt;(posX+buttonArea/2) &amp;&amp; X&gt;(posX-buttonArea/2) 
          &amp;&amp; Y&lt;(posY+buttonArea/2) &amp;&amp; Y&gt;(posY-buttonArea/2)) {
            buttonClickedResult = true; }
    }
    return buttonClickedResult;
  }

  void buttonClick() {
    if (buttonClicked) {
      buttonClicked = false;
    } else {
      buttonClicked = true;
    }
  }  

  void drawButton() {
    fill(ColorOfBackground);
    if (type=="rec") {
      rect(posX, posY, 10, 10);
      if (buttonClicked) { fill(ColorOfClickedButton); } 
      else { fill(ColorOfBackground); } 
      rect(posX+2, posY+2, 6, 6);
    } else if (type=="ell") {      
      ellipse(posX, posY, 10, 10);
      if (buttonClicked) { fill(ColorOfClickedButton); } 
      else { fill(ColorOfBackground); }
      ellipse(posX, posY, 6, 6);
    } 
  }
}</pre><p>
&nbsp;</p><pre class="crayon-plain-tag">void drawGraphPanel(){
  stroke(ColorOfListBoxForeground);
  strokeWeight(1.5);
  fill(color(255,255,255));
  rect(graphPanelXPos, graphPanelYPos, graphPanelXSize, graphPanelYSize); 

  fill(ColorOfBackground);
  rect(selectPanelXPos, selectPanelYPos, selectPanelXSize, selectPanelYSize);

  pauseBt.drawButton();
  stopBt.drawButton();
  rollAngBt.drawButton();
  pitchAngBt.drawButton();
  rollAngVelBt.drawButton();
  pitchAngVelBt.drawButton();

  strokeWeight(1);
  for (int i=(graphPanelYPos+panelGridYDivision); 
              i&lt;(graphPanelYPos+graphPanelYSize); i=i+panelGridYDivision) {
    for (int j=(graphPanelXPos+buttonXDiv);
              j&lt;(graphPanelXPos+graphPanelXSize); j=j+buttonXDiv) {
      line(j+panelGridHalfLength, i, j-panelGridHalfLength, i);
      line(j,i+panelGridHalfLength, j, i-panelGridHalfLength);   
    }
  }

  int tmpX = graphPanelXPos+graphPanelXSize/10;
  for (int i=0; i&lt;9; i++) {
    line(tmpX-panelGridHalfLength+i*graphPanelXSize/10, graphPanelYCenterPos, 
          tmpX+panelGridHalfLength+i*graphPanelXSize/10, graphPanelYCenterPos);
  }  
}

void drawText() {
  textFont(bigfontText);
  fill(100);  
  text("NT-ARSv1 Monitor",10,35);
  textFont(fontText);
  text("This Processing code is monitoring program for NT-ARSv1",280,51);
  text("NT-ARSv1 Monitoring Ver. 0.80 by PinkWink in NTRexLAB.",280,63);
  //text("by PinkWink in http://pinkwink.kr/",420,75);
  text("x division = 1 second",
    graphPanelXPos+graphPanelXSize/2-50,graphPanelYPos+graphPanelYSize+15);
  for (int i=0; i&lt;7; i++){
    text(graphYLabel[i], graphPanelXPos-20, graphPanelYPos+panelGridYDivision*i+5);
  }
  text("RollAngle", buttonXStartPos+11, buttonYPos+5);
  text("PitchAngle", buttonXStartPos+buttonXDiv+11, buttonYPos+5);
  text("RollAngVel", buttonXStartPos+buttonXDiv*2+11, buttonYPos+5);
  text("PitchAngVel", buttonXStartPos+buttonXDiv*3+11, buttonYPos+5);  
  text("Pause", graphPanelXPos+13, graphPanelYPos-20);
  text("STOP", graphPanelXPos+93, graphPanelYPos-20);    
}</pre><p>
사용하고 있는 라이브러리 중 serial 라이브러리는 기본으로 같이 설치되는데요. 또 하나 사용하고 있는게 controlP5입니다. 이는 Processing 공식 홈페이지에서 추가 다운로드가 가능합니다. DropdownList를 꼭 쓰고 싶었는데 직접 만들기가 귀찮아서 가져다 사용했습니다. 그리고, arsClass는 GUI를 Processing에서 기본 지원을 하지 않기 때문에 배포되는 라이브러리를 사용하거나 직접 만들거나 해야하는데요. 이번에는 사용되는 총 6개의 버튼을 직접 만들었습니다. 그 공통 속성과 함수를 모아논 클래스입니다. initPanel은 기본적인 화면 구성을 별도로 배치 시켜 둔것입니다.</p>
<p>그러면 이제 저희 NT-ARSv1을 Processing에서 코딩하시고자 하는 분들께 작은 도움이라도 되었으면 합니다.^^</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/19652/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>아두이노에서 NT-ARSv1의 데이터를 받는 예제</title>
		<link>http://www.ntrexgo.com/archives/18397</link>
		<comments>http://www.ntrexgo.com/archives/18397#comments</comments>
		<pubDate>Mon, 16 Sep 2013 02:08:14 +0000</pubDate>
		<dc:creator>NTRexLAB</dc:creator>
				<category><![CDATA[--응용예제]]></category>
		<category><![CDATA[blog-posts]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[ARS]]></category>
		<category><![CDATA[NT-ARSv1]]></category>
		<category><![CDATA[아두이노]]></category>
		<category><![CDATA[예제]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=18397</guid>
		<description><![CDATA[NT-ARSv1의 출력 데이터를 아두이노에서 해석하는 예제입니다. Roll, Pitch와 그 각속도 이렇게 4개의 값중에서 사용자가 선택할 수 있으며, 출력된 데이터는 문자열이 아니라 double형의 숫자로 받도록 했습니다. 이미 예전에 [바로가기]에서 NT-ARSv1의 데이터를 받는 부분을 다루었는데요. 당시에는 단순히 값을 한 번 확인하는 것과 아두이노와 ARS와의 연결에 대한 부분을 다루었다면 이번에는 약간 함수화를 했습니다. 기본적으로 하드웨어적인 연결은 [바로가기]와 같으니 먼저 읽고 넘어오시기 바랍니다.
&#160;

&#160;
일단 오늘 보여드릴 예제는 몇몇개의 함수로 구현되어 있어서 함수별로 하나씩 확인해보도록 하겠습니다.
[crayon-69e13d4b36e34235715484/]
먼저 getARSresultAtOnce() 함수입니다. 이 함수는 NT-ARSv1의 데이터를 STRING의 형태로 저장하는 것이 목적입니다. 여러가지 형태로 다양하게 사용하실려면 이 함수만 사용하신 다음 간편하게 응용하시면 됩니다. 함수이름에도 나타나 있지만, ARS의 &#60;CAO&#62;명령을 사용합니다. 만약 사용자가 &#60;CAH&#62;명령을...]]></description>
				<content:encoded><![CDATA[<p>NT-ARSv1의 출력 데이터를 아두이노에서 해석하는 예제입니다. Roll, Pitch와 그 각속도 이렇게 4개의 값중에서 사용자가 선택할 수 있으며, 출력된 데이터는 문자열이 아니라 double형의 숫자로 받도록 했습니다. 이미 예전에 [<a href="http://www.ntrexgo.com/archives/17654" target="_blank">바로가기</a>]에서 NT-ARSv1의 데이터를 받는 부분을 다루었는데요. 당시에는 단순히 값을 한 번 확인하는 것과 아두이노와 ARS와의 연결에 대한 부분을 다루었다면 이번에는 약간 함수화를 했습니다. 기본적으로 하드웨어적인 연결은 [<a href="http://www.ntrexgo.com/archives/17654" target="_blank">바로가기</a>]와 같으니 먼저 읽고 넘어오시기 바랍니다.</p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/08/0011.jpg" rel="lightbox[18397]"><img class="aligncenter size-large wp-image-17655" alt="001" src="http://www.ntrexgo.com/wp-content/uploads/2013/08/0011-620x527.jpg" width="620" height="527" /></a></p>
<p>&nbsp;</p>
<p>일단 오늘 보여드릴 예제는 몇몇개의 함수로 구현되어 있어서 함수별로 하나씩 확인해보도록 하겠습니다.</p><pre class="crayon-plain-tag">String getARSresultAtOnece() {
  String outputValuesOfARS = "";

  Serial1.print("&lt;CAO&gt;");

  delay(2);

  while (Serial1.available()) {
    char incomingChar = Serial1.read();
    outputValuesOfARS += incomingChar;
  }

  return outputValuesOfARS;
}</pre><p>
먼저 getARSresultAtOnce() 함수입니다. 이 함수는 NT-ARSv1의 데이터를 STRING의 형태로 저장하는 것이 목적입니다. 여러가지 형태로 다양하게 사용하실려면 이 함수만 사용하신 다음 간편하게 응용하시면 됩니다. 함수이름에도 나타나 있지만, ARS의 &lt;CAO&gt;명령을 사용합니다. 만약 사용자가 &lt;CAH&gt;명령을 사용하고자 하시면 이후 코딩을 다르게 작성하셔야합니다. 그리고 6번 행의 delay문은 &lt;CAO&gt;명령을 하달한 다음 바로 시리얼 데이터를 읽도록 해버리면 미처 데이터가 도착하기 전에 지나가버립니다. 그래서 적절한 시간만큼 기다리라고 해둔겁니다. 물론 데이터가 실제로 들어올때까지 기다리라는 조건문을 넣어둘 수도 있지만, 그러면 또한 여러가지 이유로 실제 데이터가 도착하지 않는 에러 상황이 발생했을때, 대응하는 코딩을 해야하기도 하고, 이 글은 NT-ARSv1을 아두이노에서 간편히 사용하실 분들을 위한 부분이라 그냥 단순하게 delay문으로 처리했습니다.</p>
<p>실제 핵심은 8번에서 11번행입니다. 아두이노는 데이터를 시리얼 통신으로 쓸때는 String 변수를 사용하는 것이 가능하지만, 받을때는 char형만 가능하므로 위 코드처럼 받은 하나의 문자를 누적해서 저장하게 됩니다. 여기서도 에러에 대한 방어는 빠져 있는데요. &#8220;&gt;&#8221;라는 문자가 눈에 보이는 마지막문자이고, 실제로는 캐리지리턴이 같이 들어옵니다만, 여하튼 제대로 하나의 데이터가 다 들어왔는지 체크하실려면 저 부분에 &#8220;&gt;&#8221;라는 문자가 들어왔는지를 확인할 필요가 있습니다. 또한 콤마&#8221;,&#8221;가 3개가 들어왔는지까지 카운팅하시면 에러방어대책은 충분할 것입니다만, 지금은 예제거든요^^</p>
<p>이제 위의 getARSresultAtOnce() 함수를 사용해서 roll값을 받는 부분을 별도로 getRollAngle()이라는 함수로 만들었습니다.</p><pre class="crayon-plain-tag">double getRollAngle() {
  String outputValuesOfARS = getARSresultAtOnece();

  int firstComma = outputValuesOfARS.indexOf(',');

  String rollAngleST = outputValuesOfARS.substring(1, firstComma);
  double rollAngle = rollAngleST.toInt() * 0.001;

  return rollAngle;
}</pre><p>
getARSresultAtOnce()의 결과 데이터가 &lt;roll, pitch, roll_vel, pitch_vel&gt;의 형태로 저장되는데요. 이 결과에서 roll데이터만 추출하는 것입니다. 먼저 4번행에서 아두이노의 String 클래스에서 지원하는 indexOf()라는 함수를 이용해서 콤마(,)의 위치를 찾고, 5번행에서 substring()함수를 이용해서 roll데이터 부분만 추출합니다. 아직까지는 String 형태이므로 7번행에서 toInt()함수를 이용해서 숫자의 형태로 변환합니다. 그리고 NT-ARSv1은 내부적으로 1000이 곱해서 출력되므로, 다시 0.001로 나눠줍니다. 이렇게 하면 radian단위의 각도로 roll을 얻을 수 있습니다.</p><pre class="crayon-plain-tag">double getPitchAngle() {
  String outputValuesOfARS = getARSresultAtOnece();

  int firstComma = outputValuesOfARS.indexOf(',');
  int secondComma = outputValuesOfARS.indexOf(',', firstComma+1);

  String pithchAngleST = outputValuesOfARS.substring(firstComma+1, secondComma);
  double pitchAngle = pithchAngleST.toInt() * 0.001;

  return pitchAngle;
}</pre><p>
그 다음은 getPitchAngle()함수로 별 설명이 없어도 알 수 있으실 테지만, 두번째 데이터인 Pitch를 추출하는 함수입니다. getRollAngle() 함수와 다른 점은 Pitch 데이터는 첫 번째 콤마(,) 부터 두번째 콤마 사이에 있는 데이터이기 때문에 4번 5번행처럼 첫째 두번째 콤마를 찾아야합니다. 그리고 나머지는 동일합니다. 이런 원리로 NT-ARSv1의 세번째 네번째 데이터인 각각의 각 속도도 추출할 수 있습니다. 이제 전체 코드를 보여드리면,</p><pre class="crayon-plain-tag">// 2013.09.16 NTRexLAB.
// NT-ARSv1 example
// ARDUINO MEGA ADK. ARDUINO IDE 1.0.5

void setup() {
  // initialize serial and serial1 communications at 115200 bps:
  Serial.begin(115200);
  Serial1.begin(115200);
}

void loop() {

  double rad2degree = 180/3.141592;

  double rollAngle = getRollAngle();
  Serial.print(" Roll Angle is ");
  Serial.print(rollAngle*rad2degree);
  Serial.println(" degree.");

  double pitchAngle = getPitchAngle();
  Serial.print(" Pitch Angle is ");
  Serial.print(pitchAngle*rad2degree);
  Serial.println(" degree.");

  double rollAngVel = getRollAngVel();
  Serial.print(" Roll Angular velocity is ");
  Serial.print(rollAngVel*rad2degree);
  Serial.println(" degree/second.");

  double pitchAngVel = getPitchAngVel();
  Serial.print(" Pitch Angular velocity is ");
  Serial.print(pitchAngVel*rad2degree);
  Serial.println(" degree/second.");

  while(true);
}

// Getting output data of NT-ARSv1 after "&lt;CAO"&gt; commander.
// The resulting data is stored in the form of a String.
String getARSresultAtOnece() {
  String outputValuesOfARS = "";

  Serial1.print("&lt;CAO&gt;");

  delay(2);

  while (Serial1.available()) {
    char incomingChar = Serial1.read();
    outputValuesOfARS += incomingChar;
  }

  return outputValuesOfARS;
}

double getRollAngle() {
  String outputValuesOfARS = getARSresultAtOnece();

  int firstComma = outputValuesOfARS.indexOf(',');

  String rollAngleST = outputValuesOfARS.substring(1, firstComma);
  double rollAngle = rollAngleST.toInt() * 0.001;

  return rollAngle;
}

double getPitchAngle() {
  String outputValuesOfARS = getARSresultAtOnece();

  int firstComma = outputValuesOfARS.indexOf(',');
  int secondComma = outputValuesOfARS.indexOf(',', firstComma+1);

  String pithchAngleST = outputValuesOfARS.substring(firstComma+1, secondComma);
  double pitchAngle = pithchAngleST.toInt() * 0.001;

  return pitchAngle;
}

double getRollAngVel() {
  String outputValuesOfARS = getARSresultAtOnece();

  int firstComma = outputValuesOfARS.indexOf(',');
  int secondComma = outputValuesOfARS.indexOf(',', firstComma+1);
  int thirdComma = outputValuesOfARS.indexOf(',', secondComma+1);

  String rollAngVelST = outputValuesOfARS.substring(secondComma+1, thirdComma);
  double rollAngVel = rollAngVelST.toInt() * 0.001;

  return rollAngVel;
}

double getPitchAngVel() {
  String outputValuesOfARS = getARSresultAtOnece();

  int firstComma = outputValuesOfARS.indexOf(',');
  int secondComma = outputValuesOfARS.indexOf(',', firstComma+1);
  int thirdComma = outputValuesOfARS.indexOf(',', secondComma+1);

  String pithchAngVelST = outputValuesOfARS.substring(thirdComma+1, outputValuesOfARS.length() - 3);
  double pithchAngVel = pithchAngVelST.toInt() * 0.001;

  return pithchAngVel;
}</pre><p>
38번행 이후는 위에서 쭈욱 설명드린 그대로 입니다. 다시 한번 말씀드리지만 NT-ARSv1을 아두이노에서 사용하기 위한 하나의 예제로 발생할 수 있는 에러나 예외상황에 대한 대비는 없습니다.^^.</p>
<p>그리고, 11번부터 36번행은 이렇게 추출된 데이터를 사용한 것일 뿐입니다. 이 예제는 [<a href="http://www.ntrexgo.com/archives/17654" target="_blank">바로가기</a>]와 같은 하드웨어적인 연결을 가지기 때문에 ADK MEGA 보드를 사용했습니다. 그래서 ARS와의 연결은 Serial1에 PC와는 Serial에 연결되어 있으며 두 통신 속도는 모두 115200으로 세팅되어 있습니다. 출력되는 각도는 함수를 설명드릴때 했지만 라디안(radian)단위이기 때문에 눈으로 쉽게 확인하게 하기위해 degree로 변환해서 보여줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/09/001.jpg" rel="lightbox[18397]"><img class="aligncenter size-full wp-image-18402" alt="001" src="http://www.ntrexgo.com/wp-content/uploads/2013/09/001.jpg" width="530" height="406" /></a></p>
<p>이렇게 해서 시리얼 모니터로 출력하면 위 그림과 같은 결과를 얻을 수 있습니다. 이제 NT-ARSv1을 아두이노에서 핸들링하고자 하시는 분들께 하나의 예제를 보여드린듯 합니다.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/18397/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>아두이노에서 NT-ARSv1의 데이터 받기</title>
		<link>http://www.ntrexgo.com/archives/17654</link>
		<comments>http://www.ntrexgo.com/archives/17654#comments</comments>
		<pubDate>Fri, 30 Aug 2013 07:10:33 +0000</pubDate>
		<dc:creator>NTRexLAB</dc:creator>
				<category><![CDATA[--응용예제]]></category>
		<category><![CDATA[blog-posts]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[ARS]]></category>
		<category><![CDATA[NT-ARSv1]]></category>
		<category><![CDATA[아두이노]]></category>
		<category><![CDATA[예제]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=17654</guid>
		<description><![CDATA[아두이노 Arduino MEGA ADK에서 NT-ARSv1데이터를 받아서 각도(degree)로 환산하는 예제 코드입니다. 아두이노로 저희 NT-ARSv1를 다룰려고 하시는 분들께 도움이 될 수 있으면 좋겠습니다.
우리 연구소에서는 아주 예전에 Pitch와 Roll각도를 받을 수 있는 NT-ARSv1[바로가기]이라는 저가의 ARS 모듈을 출시했었습니다.

&#160;
오늘은 여러 유저들께서 자주 요청하시던 아두이노에서 이 ARS의 데이터를 받는 예제를 공개할려고 합니다. 일단, 이 글에서 테스트 되는 아두이노 보드는 Arduino MEGA ADK[판매 페이지 바로가기]입니다.  왜 MEGA ADK 버젼을 사용했냐면, 저는 PC에서 데이터를 확인하고 싶었기 때문에 ARS와 시리얼 통신으로 연결될 여분의 시리얼 포트가 더 필요했기 때문입니다. Arduino MEGA ADK는 총 4개의 시리얼 포트를 가지고 있어서 선정했구요.
그런데 연결하다보니 약간의 문제를 만났네요. 어떤 문제냐면, NT-ARSv1의 시리얼통신 출력은 RS232신호로 나온다는...]]></description>
				<content:encoded><![CDATA[<p>아두이노 Arduino MEGA ADK에서 NT-ARSv1데이터를 받아서 각도(degree)로 환산하는 예제 코드입니다. 아두이노로 저희 NT-ARSv1를 다룰려고 하시는 분들께 도움이 될 수 있으면 좋겠습니다.</p>
<p>우리 연구소에서는 아주 예전에 Pitch와 Roll각도를 받을 수 있는 NT-ARSv1[<a href="http://www.ntrexgo.com/archives/1611" target="_blank">바로가기</a>]이라는 저가의 ARS 모듈을 출시했었습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/08/0021.jpg" rel="lightbox[17654]"><img class="aligncenter size-full wp-image-17656" alt="002" src="http://www.ntrexgo.com/wp-content/uploads/2013/08/0021.jpg" width="228" height="215" /></a></p>
<p>&nbsp;</p>
<p>오늘은 여러 유저들께서 자주 요청하시던 아두이노에서 이 ARS의 데이터를 받는 예제를 공개할려고 합니다. 일단, 이 글에서 테스트 되는 아두이노 보드는 Arduino MEGA ADK[<a href="http://devicemart.co.kr/goods/view.php?seq=34406" target="_blank">판매 페이지 바로가기</a>]입니다.  왜 MEGA ADK 버젼을 사용했냐면, 저는 PC에서 데이터를 확인하고 싶었기 때문에 ARS와 시리얼 통신으로 연결될 여분의 시리얼 포트가 더 필요했기 때문입니다. Arduino MEGA ADK는 총 4개의 시리얼 포트를 가지고 있어서 선정했구요.</p>
<p>그런데 연결하다보니 약간의 문제를 만났네요. 어떤 문제냐면, NT-ARSv1의 시리얼통신 출력은 RS232신호로 나온다는 겁니다. 만약 UNO나 MEGA ADK의 기본 시리얼 포트에 연결한다면 문제가 없는데, 이 시리얼포트는 PC와의 연결및 모니터링으로 남겨두면, MEGA ADK의 나머지 시리얼포트는 UART신호로, 즉 TTL 레벨의 신호를 받는 포트들입니다. 그래서 할 수 없이 ILX232칩 처럼 RS232신호와 UART 신호를 변환하는 기능이 부가적으로 필요합니다. 직접 구현해도 되지만, LK EMBEDDED라는 회사의 변환모듈 URS232라는 모델[<a href="http://devicemart.co.kr/goods/view.php?seq=1075379" target="_blank">판매페이지 바로가기</a>]을 그냥 사용했습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/08/0041.jpg" rel="lightbox[17654]"><img class="aligncenter size-large wp-image-17658" alt="004" src="http://www.ntrexgo.com/wp-content/uploads/2013/08/0041-620x427.jpg" width="620" height="427" /></a></p>
<p>그러나 이 아이도 약간 이상합니다. 판매페이지에서 이 회사가 제시하는 연결 포트들의 핀맵은 약간 혼돈이 올 수 있습니다. 일단</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/08/0031.jpg" rel="lightbox[17654]"><img class="aligncenter size-full wp-image-17657" alt="003" src="http://www.ntrexgo.com/wp-content/uploads/2013/08/0031.jpg" width="396" height="201" /></a></p>
<p>NT-ARSv1의 핀맵을 보면, 2번 3번의 TX, RX가 있습니다. 이걸 URS232라는 모듈의 RS의 RX, TX단자에 연결합니다. 이건 정상^^. 아래 연결도를 보시면</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/08/0011.jpg" rel="lightbox[17654]"><img class="aligncenter size-large wp-image-17655" alt="001" src="http://www.ntrexgo.com/wp-content/uploads/2013/08/0011-620x527.jpg" width="620" height="527" /></a></p>
<p>왜 Fritzing에서 사용자 지정 부품 만들기가 이리도 잘 안되는 걸까요..ㅠㅠ 그래서 그냥 메모지로 URS232와 NT-ARSv1을 표현했습니다. 제가 위에서 혼돈이 있을 수 있다는 것은 URS232의 TTL측 TX는 아두이노 ADK의 TX1에, URS232의 TTL측 RX는 ADK의 RX1에 연결해야합니다. 약간 혼돈스러워서 URS232모듈에서 사용하고 있는 ILX232N이라는 칩의 데이터시트와 비교해 보니, 이 모듈의 TTL측 핀맵에서 TTL_RX라고 표기되어 있는 부분은 실제로 output of recieve data 단자였습니다. 아무튼 어떤 이윤지는 몰라도 모듈 제조사는 이렇게 표현했네요. 그래서 위 그림처럼 결선하시면 아두이노 ADK 보드와 NT-ARSv1과의 연결을 위해 URS232를 사용할 수 있습니다. 이제 준비는 되었구요.</p>
<p>오늘의 목적인 NT-ARSv1의 데이터를 Arduino에서 읽기 위해 Arduino IDE에서 작성한 예제 코드를 보여드리면</p><pre class="crayon-plain-tag">// initialize each variables
char incomingByte = 0;
int resultValues = 0;
int consideringMinusSign = 1;
int selectingValuesFromARS = 0;

// The output values of NT-ARSv1 are 1000 times in radians
float scaleFactorOfARS = 0.001;
float rad2degree = 180 / 3.141592;

float rollAngle = 0;
float pitchAngle = 0;
float rollVel = 0;
float pitchVel = 0;

void setup() {
  // initialize serial and serial1 communications at 115200 bps:
  Serial.begin(115200); 
  Serial1.begin(115200);
}

void loop() {
  // Command to ARS for getting result via serial communication
  // ex) &lt;CAO&gt; : to get values one time.
  // ex) &lt;CAH&gt; : to get values continuesly.
  // ex) &lt;CAE&gt; : to stop getting values.
  Serial1.write(Serial.read());

  if (Serial1.available() &gt; 0) {
    incomingByte = Serial1.read();

    // Operation minus sign.
    if (incomingByte == '-') {
      consideringMinusSign = -1;
    }

    if (incomingByte &gt;= '0' &amp;&amp; incomingByte &lt;= '9') {
      resultValues = resultValues*10 + incomingByte - '0';
    }
    if (incomingByte == ',' || incomingByte == '&gt;') {
      //Serial.println("Your Command is : " + userCommander);

      resultValues = resultValues * consideringMinusSign;
      consideringMinusSign = 1;
      selectingValuesFromARS += 1;

      switch(selectingValuesFromARS) {
        case 1 :
          // getting roll angle as degree
          rollAngle = resultValues * scaleFactorOfARS * rad2degree;
          Serial.println(" ========================= ");
          Serial.print(" Roll Degree = ");
          Serial.println(rollAngle);
          break;
        case 2 :
          // getting pitch angle as degree
          pitchAngle = resultValues * scaleFactorOfARS * rad2degree;
          Serial.print(" Pitch Degree = ");
          Serial.println(pitchAngle);
          break;
        case 3 :
          // getting roll anglular velocity as degree
          rollVel = resultValues * scaleFactorOfARS * rad2degree;
          Serial.print(" Roll Vel. Degree = ");
          Serial.println(rollVel);
          break;
        case 4 :
          // getting pitch anglular velocity as degree
          pitchVel = resultValues * scaleFactorOfARS * rad2degree;
          Serial.print(" Pitch Vel. Degree = ");
          Serial.println(pitchVel);
          Serial.println(" ========================= ");      
          break;
      }
      resultValues = 0;
    }
    if (incomingByte == '&gt;') {
      selectingValuesFromARS = 0;
    }
  }
}</pre><p>
입니다.</p>
<p>해당 코드에 대한 설명을 잠시 드리면, 먼저 사용자가 Arduino IDE의 시리얼모니터링을 켜서 테스트한다면, ARS의 명령을 입력하도록 하고 있습니다. 23번부터 26번행까지 설명되어 있지만, &lt;CAO&gt;라고 입력하면 데이터를 한 번 출력해 줍니다.</p>
<p>NT-ARSv1은 출력되는 데이터의 형식이 괄호로 쌓여서 &lt;roll 각, pitch 각, roll 각속도, pitch 각속도&gt;의 형태로 됩니다. 거기다 시리얼 통신으로 텍스트로 날라왔으니 문자입니다. 또 자릿수도 생각하고 부호도 생각해야합니다. 그 부분을 고려하는 코드들입니다. 그리고, 확인을 위해 각각 해당값을 출력하고 있구요. 이미 아두이노를 사용하고 계신 분들이라면 손쉽게 NT-ARSv1을 아두이노에서 사용하실 수 있을 것입니다.</p>
<p>위 코드를 실행하고,</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/08/0051.jpg" rel="lightbox[17654]"><img class="aligncenter size-large wp-image-17659" alt="005" src="http://www.ntrexgo.com/wp-content/uploads/2013/08/0051-620x557.jpg" width="620" height="557" /></a></p>
<p>시리얼모니터도구에서 &lt;CAO&gt; 라고 괄호포함해서 입력하면, 위 그림과 같은 출력을 볼 수 있습니다. 아두이노 예제는 앞으로도 많이 다뤄서 도움이 되도록 하겠습니다.^^</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/17654/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
