[아두이노] [강좌] 15. Serial 통신(1) - 시리얼 통신이란 무엇인가
* 주의! 이번 강좌는 Serial 통신에 대한 이해를 위해 조금 자세하게 설명한 부분이 없잖아 있으므로, 시간이 없다거나 어려운 내용은 알고 싶지 않다거나 Serial 통신을 사용하는 방법만 알고 싶다, 하는 분들은 다음 강좌 "Serial 통신 사용하기"부터 봐도 됩니당. |
우리는 이미 Serial(시리얼)을 사용해 본 적이 있다. 앞서 digitalRead() 함수를 설명할 때도 사용했었고, analogRead() 함수를 설명할 때도 사용했었다.
다음은 ‘AnalogReadSerial’ 예제.
AnalogReadSerial.ino |
void setup() { Serial.begin(9600); }
void loop() { int sensorValue = analogRead(A0);
Serial.println(sensorValue); delay(100); } |
저렇게 써준 후 아두이노 스케치의 시리얼 모니터를 실행하면 화면에 읽어 들인 센서의 측정 값이 숫자로 나타나는 것을 볼 수 있었다. 시리얼 통신을 사용하여 PC로 데이터를 전송하고 PC는 수신된 데이터를 시리얼 모니터 화면에 출력한 것이다.
자, 그럼 시리얼 통신이 뭐야?
시리얼(Serial)의 뜻은 ‘직렬’이다. 직렬? 그럼 병렬도 있나? 있다, ‘Parallel(패러럴)’. 직렬 통신과 병렬 통신. 두 가지 모두 하나의 기기가 다른 기기와 데이터를 주고 받기 위해 만들어진 통신 방법이다.
8비트(한 비트는 하나의 0 또는 1) 데이터를 하나 보낸다고 할 때, 8개의 데이터 선을 사용해서 각각의 선에 비트 하나씩 한 번 보내는 방법이 병렬 통신이고, 하나의 데이터 선을 사용해서 8개의 비트를 하나씩 차례로 보내는 방법이 직렬 통신이다. 다음 그림은 ‘100(십진수)’이라는 값을 병렬 통신과 직렬 통신 방법으로 전송하는 것을 그림으로 나타낸 것이다.

그림에서 나타나있다시피 병렬이든 직렬이든 LOW, HIGH 신호를 이용해 0과 1의 데이터만을 보낼 수 있기 때문에 데이터는 2진수 값으로 변환하여 전송된다.
사실 시리얼 통신이라는 말은 직렬 방식으로 데이터를 주고 받는 모든 통신을 통틀어 말하는 것이고, 여기서 설명하려는 방식은 그 중에 하나인 UART(Universal Asynchrounous serial Receiver and Transmitter) 통신 방식이긴 하지만 아두이노에서는 UART 통신을 “Serial”이라는 객체로 정의해뒀기 때문에 그냥 시리얼 통신이라고 설명하겠다.
시리얼 통신 방식의 종류에 대한 설명은 이 글 마지막에 "*참고"로 접어 뒀으니 궁금하면 참조.
시리얼 통신은 데이터 전송을 위한 선(TX) 하나와 수신을 위한 선(RX) 하나로 이루어진다. 대부분의 아두이노 보드에서는 0번과 1번 핀을 시리얼 통신을 위한 핀으로 사용하며, 메가(Mega 2560/ADK)의 경우에는 여기에 3쌍의 핀(14~19번 핀)이 추가되어 총 4쌍의 시리얼 통신 핀을 가지고 있다.

‘TX’라고 표시된 핀이 아두이노 보드에서 데이터를 전송할 때 사용하는 핀이며, ‘RX’라고 표시된 핀이 아두이노 보드가 데이터를 수신할 때 사용하는 핀이다. 뒤에 붙어 있는 숫자는 시리얼 포트의 번호이고, 메가(Mega 2560/ADK)일 경우에 0~3번까지 총 4개의 포트가 있다. 우노(Uno)의 경우에는 0번밖에 없다.
0, 1번 핀은 USB to Serial 기능을 하는 칩과 연결되어 있어서 USB 케이블을 통해 아두이노에서 PC로 데이터를 전송, 수신할 수 있으며, USB 케이블을 PC와 연결하지 않았을 경우에 0, 1번 핀을 다른 기기의 시리얼 통신 포트와 연결하여 데이터를 주고 받을 수도 있다.
시리얼 통신을 사용하기 위해서는 시리얼 통신 포트를 초기화 해줘야 하는데, 이 기능을 하는 함수가 바로 "Serial.begin()" 함수이다. 이번 강좌에서 초기화 부분만 살펴보고 넘어가자. 시리얼 통신을 위한 함수는 “Serial” 객체에 정의되어 있어서 함수를 사용할 때는 “Serial.”을 앞에 꼭 붙여줘야 한다는 거.
Serial.begin(speed)
Serial.begin(speed, config)
begin() 함수는 시리얼 통신을 사용하기 위해 핀을 초기화 시켜준다. 메가 외의 다른 보드에는 시리얼 통신 핀은 0번, 1번뿐이므로 이 함수를 사용하면 0번 핀과 1번 핀을 더 이상 디지털 핀으로 사용할 수 없다. 매개 변수로 통신 속도 값을 전달하며, 통신 설정 정보를 함께 전달할 수도 있다.
매개 변수 speed : 시리얼 통신 속도. Baud Rate(보레이트)라고 하며 초당 전송되는 비트 수를 말한다. 단위는 bps(Bit Per Second). 당연히 숫자가 높을수록 속도가 빠르다. 반드시 다음 값들 중 하나를 선택해서 설정해야 한다.
- 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200
config : 시리얼 통신 환경을 설정하며, 데이터 길이, 패리티 비트, 정지 비트를 설정한다. “SERIAL_” 뒤에 각각의 정보를 의미하는 문자를 붙인다. 문자 종류는 다음과 같다.
- 데이터 길이 : 8 – 8 비트 데이터 7 – 7 비트 데이터 6 – 6 비트 데이터 5 – 5 비트 데이터 - 패리티 비트 : N – 패리티 비트 사용 안 함 E – Even(짝수) 패리티 비트 사용 O – Odd(홀수) 패리티 비트 사용 - 정지 비트 : 1 – 1개의 정지 비트 사용 2 - 2개의 정지 비트 사용
config 값을 지정하지 않으면 기본으로 “SERIAL_8N1”이 설정되며, 8비트 데이터에 패리티 비트는 사용하지 않고, 1개의 정지 비트를 사용한다는 의미이다. |
여기서 중요한 건 통신 속도 설정이다. 여러 종류의 시리얼 통신 중 지금 설명하는 UART 통신 방식은 비동기식(Asynchronous) 통신이라 다른 동기식 시리얼 통신 방식인 I2C나 SPI 통신 방식과 달리 데이터 수신 타이밍을 위해 Clock 라인을 사용하지 않는다. 그래서 미리 약속된 통신 속도로 데이터를 전송해야 받는 쪽에서 정확한 데이터를 읽을 수 있다.
무슨 말이냐.
다음 그림을 보자.

약간 감이 오는가? 한 라인으로 위와 같은 데이터를 전송했을 때, 읽는 속도에 따라 전혀 다른 데이터가 읽힐 수 있다는 것. 1번 타이밍으로 읽은 데이터와 2번 타이밍으로 읽은 데이터가 서로 다른 것이 보이지요?
그래서 1번 타이밍으로 읽을래, 2번 타이밍으로 읽을래 정하는 것을 보레이트(Baud Rate) 설정이라고 하며, 보레이트는 보내는 쪽과 받는 쪽에 반드시 같은 값이 설정되어 있어야 한다.
다시 한번 아까 그 예제를 살펴 볼까?
void setup() { Serial.begin(9600); } |
begin() 함수로 시리얼 통신을 초기화하며, 통신 속도로 9600bps를 사용하겠다고 설정하고 있다. 그럼 받는 쪽에도 설정해줘야겠지? 시리얼 모니터를 실행해보자.

빨간 색 네모 부분에 “9600 baud”라고 설정된 것이 보이는가? 만일 둘 중 하나의 설정을 다른 값으로 바꾼다면 시리얼 모니터 화면에 나타나는 값은 위의 숫자들이 아니라 이상한 다른 값들일 것이다. 제대로 읽지 못할 테니까.
이제 초기화를 했으니, 진짜 시리얼 통신을 사용해볼까?
는, 다음 시간에. 안녕~