본문으로 바로가기

오늘은 아주 예전에 만들었던 ARS 모듈과 아두이노 이야기를 할려고합니다. 예전에 Pitch와 Roll각을 측정하는 모듈로 NT-ARSv1이라는 작품활동을 했던 적이 있는데요. 이 아이를 요즘 제가 관심을 가지는 아두이노에서 다루는 걸 보여드릴려구요.

예전에 몇몇 분들께서 아두이노에서의 예제를 요청하셨던 적이 있는데... 이제서야 올리게 되네요. (죄송합니다.ㅠㅠ) 일단, 이 글에서 테스트 되는 아두이노 보드는 Arduino MEGA ADK[판매 페이지 바로가기]입니다.  왜 MEGA ADK 버젼을 사용했냐면, 저는 PC에서 데이터를 확인하고 싶었기 때문에 ARS와 시리얼 통신으로 연결될 여분의 시리얼 포트가 더 필요했기 때문입니다. Arduino MEGA ADK는 총 4개의 시리얼 포트를 가지고 있어서 선정했구요.

그런데 연결하다보니 약간의 문제를 만났네요. 어떤 문제냐면, NT-ARSv1의 시리얼통신 출력은 RS232신호로 나온다는 겁니다. 만약 UNO나 MEGA ADK의 기본 시리얼 포트에 연결한다면 문제가 없는데, 이 시리얼포트는 PC와의 연결및 모니터링으로 남겨두면, MEGA ADK의 나머지 시리얼포트는 UART신호로, 즉 TTL 레벨의 신호를 받는 포트들입니다. 그래서 할 수 없이 ILX232칩 처럼 RS232신호와 UART 신호를 변환하는 기능이 부가적으로 필요합니다. 직접 구현해도 되지만, LK EMBEDDED라는 회사의 변환모듈 URS232라는 모델[판매페이지 바로가기]을 그냥 사용했습니다.

그러나 이 아이도 약간 이상합니다. 판매페이지에서 이 회사가 제시하는 연결 포트들의 핀맵은 약간 혼돈이 올 수 있습니다. 일단

NT-ARSv1의 핀맵을 보면, 2번 3번의 TX, RX가 있습니다. 이걸 URS232라는 모듈의 RS의 RX, TX단자에 연결합니다. 

아래 연결도를 보시면

왜.. 왜 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를 사용할 수 있습니다. 이제 준비는 되었구요.

오늘의 목적인 NT-ARSv1의 데이터를 Arduino에서 읽기 위해 Arduino IDE에서 작성한 예제 코드를 보여드리면

// 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) '<CAO> : to get values one time.
  // ex) '<CAH> : to get values continuesly.
  // ex) '<CAE> : to stop getting values.
  Serial1.write(Serial.read());
 
  if (Serial1.available() > 0) {
    incomingByte = Serial1.read();
 
    // Operation minus sign.
    if (incomingByte == '-') {
      consideringMinusSign = -1;
    }
 
    if (incomingByte >= '0' && incomingByte <= '9') {
      resultValues = resultValues*10 + incomingByte - '0';
    }
    if (incomingByte == ',' || incomingByte == '>') {
      //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 == '>') {
      selectingValuesFromARS = 0;
    }
  }
}

입니다.

해당 코드에 대한 설명을 잠시 드리면, 먼저 사용자가 Arduino IDE의 시리얼모니터링을 켜서 테스트한다면, ARS의 명령을 입력하도록 하고 있습니다. 23번부터 26번행까지 설명되어 있지만, <CAO>라고 입력하면 데이터를 한 번 출력해 줍니다.

NT-ARSv1은 출력되는 데이터의 형식이 괄호로 쌓여서 <roll 각, pitch 각, roll 각속도, pitch 각속도>의 형태로 됩니다. 거기다 시리얼 통신으로 텍스트로 날라왔으니 문자입니다. 또 자릿수도 생각하고 부호도 생각해야합니다. 그 부분을 고려하는 코드들입니다. 그리고, 확인을 위해 각각 해당값을 출력하고 있구요. 이미 아두이노를 사용하고 계신 분들이라면 손쉽게 NT-ARSv1을 아두이노에서 사용하실 수 있을 것입니다.

위 코드를 실행하고 난 결과는

입니다. 시리얼 모니터 도구에서 <CAO>라고 입력하고 SEND하시면 나타나는 결과입니다. 이 예제는 ARS를 대상으로 MATLAB[바로가기]과 Python[바로가기]에서 시리얼 통신을 하던 예제를 문법에 맞게 변환만 한 것입니다. (중간중간의 주석에 있는 영어 문법으로 태클걸기 없기...ㅠㅠ 이놈의 영어 울렁증이...ㅠㅠ) 마지막으로 이 글은 ntrexgo.com에도 동시 기고 되었습니다.^^



댓글을 달아 주세요

  1. BlogIcon 핑구야 날자 2013.08.31 08:06 신고

    즐거운 주말 보내시구요.,. 코딩은 읽겠는데.. 의미는 잘 모른다는...ㅋㅋ

  2. BlogIcon 치아 2013.09.01 12:12 신고

    잘 보고 갑니다.
    행복한 주말 되시기 바랍니다.

  3. BlogIcon 핑구야 날자 2013.09.01 20:59 신고

    가끔 보면 하드웨어와 연동되는 코딩을 보면 정말 재미있을 것 같더라구요

  4. BlogIcon 자전거타는남자 2013.09.02 07:07 신고

    새로운 한달 활기차게 보내시기 바랍니다

  5. BlogIcon S매니저 2013.09.02 13:12 신고

    덕분에 잘 보고 간답니다~
    행복한 하루 되시길 바래요~

  6. BlogIcon 캐치파이어 2013.09.02 14:52 신고

    잘보고 갑니다. 풍요로운 9월 되세요 ^^

  7. BlogIcon 별이 2013.09.04 00:57 신고

    좋은 포스팅 잘보고갑니다^^
    하루 마무리 잘하시고, 좋은꿈 꾸세요^^

  8. 심심 2014.07.17 17:39 신고

    <CAH> 해서 데이터값을 보네고 평면상에서 센서값을 받아 들여 보면 각도 변환시 초기값이 0도가 아닌 10~20 사이를 평면상에서 왔다갔다 합니다. 원래 그런건가요/?

  9. 신은총 2015.04.18 16:38 신고

    nt-ars-v2 관련 질문있습니다.
    저는 현재 센서와 마이크로프로세서로 mbed를 사용하여 자세를 제어하는 밸런싱로봇을 제작중에 있는데요, 문제는 센서와 mbed의 통신을 할 수가 없다는 것입니다(센서에 ss=1 신호를 mbed에 줄 수 가 없고, 각도값을 mbed를 통해 띄울 수 없다던지).
    알아본바로는 위 포스트처럼 mbed의 uart방식과 센서의 rs232 의 차이인 것 같은데..그럼 저도 게시물과 같이 uart - rs232 와 같은 통신 모듈을 사용하여야 하는 걸까요? 통신모듈을 이용하여 mbed에서 센서로, 센서에서 mbed로 값을 입출력 가능할까요? mbed도 아두이노와 마찬가지로 uart 포트만 있습니다...
    학교프로젝트로 진행하는데 어려움이 많습니다..도움부탁드립니다.

    • BlogIcon PinkWink 2015.04.19 16:50 신고

      네.. 중간에 위 글에서 이야기한데로 컨버터 역할을 하는 아이가 하나 필요합니다. 몇 천원하지는 않습니다만.ㅠㅠ
      그나저나 제조 및 판매사에서 대응을 안해주나 보군요... 쯧쯧..ㅠㅠ

  10. 남재욱 2015.06.15 16:52 신고

    아두이노 소스로 예제소스 치고 확인하면
    'Serial1' was not declared in this scope 에러가 뜨는데 뭐가문제인건가요..?

    • BlogIcon PinkWink 2015.06.15 18:10 신고

      그렇다면.. 가지고 계신 아두이노 보드가 시리얼 통신 포트가 몇 개인지 보셔야합니다. 혹시 시리얼 포트가 하나뿐이라면 Serial1은 없는 거라서 에러가 날겁니다.