플밍

아두이노 기초강좌 - 9. 시리얼 통신 본문

프로그래밍/아두이노

아두이노 기초강좌 - 9. 시리얼 통신

너구리안주 2015. 7. 23. 00:37


본 강좌는 지인의 사이트에서 허락받고 퍼온 강좌입니다.

다른곳으로 불펌하시면 곤란합니다.

그리고 제가 아두이노를 그리 잘 알지는 못합니다.

저한테 물어보시는것도 곤란.... ^^


#ads_1

강좌를 계획없이 생각나는대로 중구난방 적다보니 처음에 했어야할 시리얼 통신을 빼먹었더라구요

그래서 이제서야 들어가게 되었습니다.

 

시리얼 통신에 대해 자세히 살펴 봅시다.

 

시리얼통신이라는 건 말그대로 직렬통신입니다.  장비와 병렬로 통신하면 속도가 빠르지만 아두이노에는 핀 개수가 한정되어 있습니다.  장비별로 핀개수가 다르면 그에 다 맞춰야 하는 불편함이 있고 비용도 증가하겠죠? 또한 병렬통신은 원거리에는 약합니다.  그런 단점으로 인해 컴퓨터 내부와 같이 가까운 거리는 병렬통신을 많이 쓰고 원거리에는 직렬통신 즉, 시리얼 통신을 많이 씁니다.

 

시리얼 통신의 방법에는 여러가지가 있지만 보통 USART(Universal ASyncronous Receive and Transmit)방식이 주로 사용됩니다.  만약 컴퓨터에서 101101... 이런 값들이 병렬로 존재한다면 이걸 1,0,1,1,0,1... 이렇게 순차적으로 줄을 세워서 변환하고 전송합니다.  받는쪽에서는 반대로 하나씩 들어온 데이타를 다시 병렬로 변환해주는(byte로 변환) 기능을 합니다.  그 외에도 시작비트, 끝비트, 패리티비트 등을 관리합니다.

 

USART 통신은 노이즈에 약하고 통신거리에 제약이 있습니다.  이를 보강하기 위해 RS232, RS422 등의 인터페이스로 만들어진 IC를 사용합니다. 이 IC를 DRIVER IC 라 부릅니다.  즉, RS232는 USART 에서 나오는 데이타가 도착지까지 잘 전송되도록 하기 위한 방식의 하나이고 그 방식을 사용하기 위해 장착된 칩에 따라 포트의 모양이 달라집니다.

 

컴퓨터는 보통 이 RS232를 통하여 시리얼통신을 제공합니다.

근데 어이없게도 아두이노에는 이 RS232 <=> USART 변환기가 포함되어 있지 않습니다. (당연한가?)

그럼 어떻게 시리얼 통신을 할까요?

변환기를 사서 디지털 0번핀(RX), 1번핀(TX), GND 에 연결해서 할 수가 있습니다.

하지만 그것보다 더 간단한 방법이 있습니다.

그냥 간단하게 컴퓨터와 아두이노를 usb케이블로 연결하면 됩니다.

이게 어떻게 가능하냐면 아두이노 usb포트 바로 앞에 보시면 조그만 칩이 있습니다.

이녀석이 바로 USB <=> USART 변환칩입니다.

이 칩을 통해 컴퓨터에는 가상으로 아두이노가 COM포트로 잡히고 시리얼통신이 가능하게 되는 것입니다.

 

※ 잡설: 제가 실 업무에 아두이노를 써본결과 USB <=> USART 방식이 단점이 있긴 합니다.

컴퓨터에서 포트가 잘 떨어집니다.  안정적이지 못하다는 말입니다.  컴퓨터 소프트웨어에서 아두이노로 통신할때 포트가 떨어지면 PurgeComm 에러가 떠서 참 난감합니다.  실제 업무에서는 ComPort 쉴드를 사용하는게 좋을듯 합니다.

 

잡설이 길었네요.  (대충 아는대로 적었는데 맞는가 몰러~ 틀렸으면 바로 지적질 해주삼! )

 

 

자, 시리얼통신을 하기 위해서는 아두이노와 컴퓨터가 서로 약속을 정해야 합니다.

서로 주고받는 통신속도를 정해야 하는거죠.  이전강좌에서도 말씀드렸다시피 이 단위를 Baud rate(보율)이라 합니다.

 

Serial.begin(9600);  //9600 baud 로 약속을 정함

 

이렇게 하면 시리얼통신할 준비가 완료되었습니다.

#ads_2

 

소스를 보죠.  스케치에 들어 있는 샘플소스입니다.

 String inputString = "";                //문자열 클래스 하나를 준비하고 초기화 합니다.

 boolean stringComplete = false;  //문자열 수신 완료 했는지 여부를 저장하는 변수

 

 void setup() {

   Serial.begin(9600);                  //Baud rate 를 9600으로 정합니다

   inputString.reserve(200);          //문자열 공간 200byte를 확보합니다.

 }

 

 void loop() {

   if (stringComplete) {                //만약 문자열을 다 받았으면 (stringComplete 가 true이면)

     Serial.println(inputString);      //시리얼통신으로 문자열 inputString을 송신해라 (줄바꿈문자 붙여서)

     inputString = "";                    //문자열 다시 초기화

     stringComplete = false;          //문자열 수신완료 여부 초기화

   }

 }

 

 //위 loop() 함수가 종료될때마다 호출됨

 void serialEvent() {

   while (Serial.available()) {       //시리얼로 데이타가 수신된것이 있으면

     char inChar = (char)Serial.read();    //문자 하나를 읽어서 inChar 변수에 저장

     inputString += inChar;            // 문자열변수 inputString 에 추가해 준다

     if (inChar == '\n') {              // 만약 inChar문자가 줄바꿈 문자이면

       stringComplete = true;          // 문자 수신이 완료된것으로 표시함

     } 

   }

 }

 

 

조금 복잡하죠?

 

Serial.begin(9600);

setup함수에서는 위에서 말한대로 Baud rate 를 정합니다.  9600 으로 맞췄네요.

 

inputString.reserve(200);

그리고 문자열의 저장공간을 확보합니다.

(c언어 쬐끔 해본 경험으로 이놈이 뭔지 예상을 해보자면..​  이건 안해도 작동은 될겁니다.  하지만 짧게 잡았을경우 긴문자가 들어오면 메모리 재할당이 일어나 퍼포먼스에 안 좋습니다.  대충 예상하고 잡아주는게 좋죠. 뭐 별로 중요한건 아니니 넘어가고...)

 

그다음 먼저 serialEvent() 함수를 보도록 하죠

이 함수는 loop가 한번 끝날때마다 자동으로 호출이 됩니다.

 

while(Serial.available()){ ... }

Serial.available() 함수는 시리얼로 수신된 데이타가 있으면 true가 반환됩니다.

그니까네~ "시리얼로 수신된 데이타가 있을때까지 while 안의 코드를 반복해라" 라는 뜻이됩니다.

 

char inChar = (char)Serial.read();

read()는 시리얼 수신버퍼에서 ​한문자를 읽으라는 뜻입니다.

한문자를 읽어서 inChar에 저장을 하네요

 

inputString += inChar;

읽은 문자를 inputString에 누적을 시키고요

 

if (inChar == '\n'){ ... }

문자열 읽은게 줄바꿈 문자이면

 

stringComplete = true;

문자열 수신이 완료된것으로 표시함

 

전체 해석을 해봅시다.

수신버퍼에 문자가 있을때까지 뺑뺑이를 돕니다

돌때마다 한문자씩 읽어서 inputString 에 누적을 하여 문자열로 저장을 합니다.

계속 한 문자씩 읽다가 문자가 줄바꿈 문자(\n)이면 문자열을 다 받은것으로 표시를 합니다.

끝.

 

 

자 그럼 이제 loop함수를 볼까요?​

 

if (stringComplete){...}

문자열 수신이 완료되었으면 { ... }을 실행하라

 

Serial.println(inputString);

serialEvent 함수에서 읽은 문자들을 누적해서 저장한 문자열 inputString을 시리얼로 송신하라는 뜻입니다.

println() 함수는 인자+줄바꿈으로 송신합니다.  줄바꿈없이 하려면 print()함수를 쓰시면 됩니다.

 

inputString = "";

stringComplete​ = false;

다 보냈으니까 문자열 inputString을 초기화하고 stringComplete도 다시 초기화 합니다.

 

 

그냥 받은거 메아리처럼 다시 던져주는 프로그램이네요

그리 어렵지 않죠?

 

Serial 클래스에는 이밖에도 몇가지 함수들이 더 존재합니다.  자세한건 레퍼런스를 참조하시기 바랍니다.

 

 

이제 업로드하고 실행을 해봅시다.

시리얼모니터를 켜시고 아두이노와 약속한대로 9600 Baud 로 맞춰줍니다

그리고 문자열 끝을 줄바꿈으로 인식하게 코딩했으니까 하단에 콤보를 Newline으로 선택해 주세요

 

이제 입력칸에 문자열을 입력하고 엔터를 쳐보시면 아두이노가 앵무새처럼 다시 문자열을 보내주는게 보일겁니다.

 



 #ads_3

Comments