아두이노 시리얼 통신(UART) 마스터: 기초부터 트러블슈팅까지
아두이노 시리얼 통신: UART/RS232 기초와 실전 프로그래밍
시리얼 통신 배경: 병렬에서 시리얼로
마이컴이 외부와 8비트 병렬로 통신하려면 8선 케이블 필요 → 장거리 신호 왜곡, 비용 상승 문제. 이를 해결하려고 시리얼 프로토콜(3선: TX, RX, GND)이 등장했습니다.
- 송신 측: 병렬 8비트 → 시리얼 비트 스트림 변환 (PISO 시프트 레지스터)
- 수신 측: 시리얼 → 병렬 8비트 복원 (SIPO 시프트 레지스터)
동기식(블록 단위)/비동기식(바이트 단위) 중 비동기식(UART)이 주류.
시리얼 통신 모드 3가지
- 심플렉스(Simplex): 송신만 가능
- 하프 듀플렉스(Half Duplex): 송수신 가능하나 동시 불가
- 풀 듀플렉스(Full Duplex): 송수신 동시 가능 (일반적)
RS232 표준과 TTL 레벨 변환
RS232는 초기 PC 표준으로, 로직 High = -1~-25V, Low = +3~+25V (TTL과 극성/레벨 상이). TTL(0~5V)과 호환 위해 MAX232 같은 레벨 변환 IC 필수. 아두이노는 내장 USB-시리얼 컨버터로 TTL↔PC 포트 호환 처리되어 별도 변환기 불필요.
아두이노 시리얼 라이브러리 핵심 함수
| 함수 | 역할 | 비고 |
Serial.begin(baud) | 시리얼 통신 초기화, 보드레이트 설정 | setup()에서 호출, 보통 9600 |
Serial.available() | 수신 버퍼 데이터 존재 여부 확인 | 0=없음, >0=읽을 데이터 있음 |
Serial.read() | 수신 버퍼에서 1바이트 읽기 | 반환값: 문자 ASCII 코드값 (예: '1' → 49) |
Serial.print/println(val) | 시리얼 모니터/포트로 데이터 전송 | println은 개행 포함 |
Serial.flush() | 송신 버퍼 비우기 (전송 완료 대기) | 버퍼 잔여 데이터 제거 |
실전 예제: PC ↔ 아두이노 양방향 통신
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
char incoming = Serial.read(); // 수신 (ASCII 코드값)
Serial.print("Received: ");
Serial.println(incoming); // 에코 백
// 예: '1' 수신 시 LED ON, '0' 수신 시 OFF
if (incoming == '1') digitalWrite(13, HIGH);
else if (incoming == '0') digitalWrite(13, LOW);
}
}
시리얼 모니터(Tools → Serial Monitor)에서 '1'/'0' 입력해 LED 제어 테스트 가능.
자주 하는 실수와 해결법
- 보드레이트 불일치: 양측 보드레이트 동일해야 함 (9600, 115200 등)
- char vs int 혼동:
Serial.read()는 int 반환(-1=데이터 없음), 문자로 쓰려면 char c = Serial.read()
- ASCII 코드값 착각: 숫자 '1' 전송 시 49(0x31) 수신.
incoming - '0'으로 변환
- 버퍼 오버플로: 고속 수신 시
Serial.flush() 또는 수신 루프 최적화 필요
- 크로스 연결: TX↔RX, RX↔TX, GND↔GND 교차 연결 확인
확장: SoftwareSerial 라이브러리
하드웨어 시리얼 핀(0,1번) 외에 임의 디지털 핀으로 시리얼 구현 가능. 다중 센서/모듈 통신 시 유용.
함께 보면 좋은 글
- 아두이노 프로그래밍 입문 (첫 코드부터)
- PIC18 마이크로컨트롤러 C 프로그래밍
- MAX232 구조·동작·응용 상세
- 온라인 회로 설계·시뮬레이션 툴 10+
- 안드로이드 필수 앱 15선
- 555 타이머 박수 스위치 프로젝트