아두이노에서 NT-ARSv1의 데이터 받기
아두이노 Arduino MEGA ADK에서 NT-ARSv1데이터를 받아서 각도(degree)로 환산하는 예제 코드입니다. 아두이노로 저희 NT-ARSv1를 다룰려고 하시는 분들께 도움이 될 수 있으면 좋겠습니다.
우리 연구소에서는 아주 예전에 Pitch와 Roll각도를 받을 수 있는 NT-ARSv1[바로가기]이라는 저가의 ARS 모듈을 출시했었습니다.
오늘은 여러 유저들께서 자주 요청하시던 아두이노에서 이 ARS의 데이터를 받는 예제를 공개할려고 합니다. 일단, 이 글에서 테스트 되는 아두이노 보드는 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에서 작성한 예제 코드를 보여드리면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
// 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> 라고 괄호포함해서 입력하면, 위 그림과 같은 출력을 볼 수 있습니다. 아두이노 예제는 앞으로도 많이 다뤄서 도움이 되도록 하겠습니다.^^