04. 시리얼 통신: 컴퓨터와 대화하기

아두이노가 센서로 느낀 온도, 빛의 밝기를 우리에게 문자로 알려주는 통신 기술을 배웁니다.

1. 시리얼 통신(Serial Communication)이란?

시리얼(Serial)은 '직렬'이라는 뜻입니다. 데이터를 한 번에 하나씩 줄을 세워 전송하는 방식이죠. 우리가 아두이노와 컴퓨터를 연결할 때 쓰는 파란색 USB 케이블이 바로 이 시리얼 통신을 위한 튼튼한 다리 역할을 합니다.

Computer Arduino TX (송신) ➡ RX (수신) RX (수신) ⬅ TX (송신)
▲ 통신의 핵심: 말하는 입(TX, Transmit)과 듣는 귀(RX, Receive)가 서로 엇갈려 연결되어야 합니다.

💡 디지털 0번, 1번 핀의 비밀

아두이노 보드의 디지털 0번(RX)과 1번(TX) 핀은 컴퓨터와의 USB 시리얼 통신을 위해 예약된 핀입니다. 따라서 컴퓨터와 데이터를 주고받을 때는 가급적 0번과 1번 핀에 다른 부품(LED, 버튼 등)을 연결하지 않는 것이 좋습니다!

2. 대화의 첫걸음: 통신 속도(Baud Rate) 맞추기

외국인과 대화할 때 말하는 속도가 너무 빠르면 알아듣기 힘들죠? 컴퓨터와 아두이노도 대화를 시작하기 전에 1초에 몇 개의 신호를 주고받을지 속도를 맞춰야 합니다. 이를 '보드레이트(Baud Rate)'라고 합니다.

아두이노에서는 주로 9600 bps (1초에 9600비트 전송)를 표준 속도로 사용합니다.

⚠️ 외계어가 출력되나요?

시리얼 모니터 창을 띄웠는데 %#@ 같은 이상한 문자가 깨져서 나온다면, 아두이노 코드의 속도(예: 9600)와 시리얼 모니터 프로그램 우측 하단의 속도가 서로 다르게 설정되어 있기 때문입니다. 이 두 숫자를 똑같이 맞춰주세요!

3. 💡 실습: 컴퓨터로 메시지 보내기

아두이노가 컴퓨터(시리얼 모니터) 쪽으로 텍스트와 숫자를 전송하는 기초 코드를 작성해 봅시다.

void setup() {
    // 1. 대화 시작 선언! "컴퓨터야, 9600 속도로 통신하자!"
    Serial.begin(9600); 
    
    // 2. 전원이 켜졌을 때 딱 한 번 인사하기
    Serial.println("Hello, Arduino! 시리얼 통신 시작!");
}

void loop() {
    int timeSec = millis() / 1000; // 켜진 후 흐른 시간(초) 계산
    
    Serial.print("아두이노가 켜진 지 ");
    Serial.print(timeSec);
    Serial.println("초 지났습니다.");
    
    delay(1000); // 1초마다 출력
}

🔍 핵심 함수 분석

함수명 설명
Serial.begin(9600); 통신 속도를 9600으로 설정하고 통신을 시작합니다. (setup에 필수)
Serial.print("내용"); 내용을 출력합니다. (출력 후 줄을 바꾸지 않고 이어서 씁니다.)
Serial.println("내용"); 내용을 출력한 뒤 엔터(줄바꿈)를 쳐서 다음 줄로 넘어갑니다. (가장 많이 씀!)
🔍 COM3 (Arduino Uno) Hello, Arduino! 시리얼 통신 시작! 아두이노가 켜진 지 1초 지났습니다. 아두이노가 켜진 지 2초 지났습니다. 아두이노가 켜진 지 3초 지났습니다. 9600 보드 레이트 ▼
▲ 아두이노 IDE 우측 상단의 돋보기 아이콘을 누르면 나오는 시리얼 모니터 창의 모습

4. 🎯 심화 미션: 컴퓨터로 아두이노 명령하기

이번에는 반대로, 컴퓨터 키보드로 숫자를 입력해서 아두이노의 LED를 켜고 끄는 마법을 부려보겠습니다. 키보드로 '1'을 전송하면 LED가 켜지고, '0'을 전송하면 LED가 꺼집니다.

void setup() {
    Serial.begin(9600);
    pinMode(13, OUTPUT); // 내장 LED 핀
    Serial.println("1을 입력하면 켜지고, 0을 입력하면 꺼집니다.");
}

void loop() {
    // Serial.available() : 아두이노의 수신함(RX)에 도착한 문자가 있는지 확인합니다.
    if (Serial.available() > 0) {
        
        // Serial.read() : 도착한 문자를 1개 읽어옵니다.
        char command = Serial.read(); 
        
        if (command == '1') {
            digitalWrite(13, HIGH);
            Serial.println("LED가 켜졌습니다!");
        } 
        else if (command == '0') {
            digitalWrite(13, LOW);
            Serial.println("LED가 꺼졌습니다!");
        }
    }
}

💡 '1'1은 완전히 다릅니다!

C언어 과정에서 배웠듯이 작은따옴표로 감싼 '1'은 수학적인 숫자 1이 아니라 "문자 1(아스키코드 값 49)"을 의미합니다. 시리얼 모니터로 우리가 키보드를 쳐서 보내는 것은 모두 '문자' 데이터이므로, 조건문에서 반드시 작은따옴표를 붙여서 command == '1' 처럼 비교해야 합니다.