티스토리 뷰
목차
시리얼 통신 개요, 구현, 포트 버퍼 설정 (C# SERIAL)
시리얼 통신 개요
시리얼은 거의 모든 PC에서 표준으로 사용되는 디바이스 통신 프로토콜이다. 시리얼의 개념을 USB의 개념과 잘 구분해야 한다. 대부분 컴퓨터에는 2개의 RS232 기반 시리얼 포트가 있다.
시리얼은 또한 여러 가지 디바이스에서 계측을 위한 일반 통신 프로토콜이며, 여러 GPIB 호환 디바이스에는 RS232 포트가 장착되어 있다. 그뿐만 아니라, 원격 샘플링 디바이스로 데이터 수집을 하는 경우에도 시리얼 통신을 사용할 수 있다(IEEE 참조).
시리얼 통신의 개념
시리얼 포트는 정보의 바이트를 한 번에 한 비트씩 순차적으로 송수신한다. 한 번에 전체 바이트를 동시에 전달하는 병렬 통신과 비교하면 시리얼 통신은 속도가 느리지만, 훨씬 간단하며 장거리에도 사용할 수 있다.
예를 들어, 병렬 통신용 IEEE 488 스펙을 보면 기기 간 케이블링은 총 20m 미만이어야 하며, 두 개의 디바이스 간은 2m 미만이어야 한다. 반면 시리얼 통신은 최대 1.2Km의 통신 거리를 보장한다.
통상 엔지니어들은 ASCII 데이터를 전송할 때 시리얼 통신을 사용한다. 이때 송신용(Tx), 수신용(Rx), 그라운드용(GND)의 세 가지의 전송 라인을 사용하여 통신한다. 시리얼은 비동기식이므로 포트는 한 라인에서 데이터를 전송하고 다른 라인에서 데이터를 수신한다. 핸드쉐이킹용 라인도 사용 할 수 있지만, 필수 요구사항은 아니다.
시리얼 통신의 가장 중요한 특징에는 보드 속도(baud rate), 데이터 비트, 정지 비트, 패리티가 있다. 두 개의 포트가 통신하기 위해서는 이러한 파라미터가 반드시 적절하게 맞춰져야 한다.
보드 속도는 통신의 속도를 측정하는 수치이며 초당 비트 전송 숫자로 표시된다. 예를 들어 300 보드 속도는 초당 300비트를 의미한다. 엔지니어들이 흔히 말하는 클럭 주기는 보드 속도를 의미한다. 따라서 프로토콜에 4800 보드 속도라고 나오는 경우 클럭이 4800Hz로 작동한다는 뜻이다.
즉, 시리얼 포트는 4800Hz로 데이터 라인을 샘플링한다.
전화선의 일반적인 보드 속도는 14400, 28800, 또는 33600이다. 더욱 높은 속도도 가능하지만, 그 경우 디바이스를 분리할 수 있는 거리가 줄어들게 된다.
따라서 엔지니어들은 디바이스가 같은 장소에 있는 디바이스 통신에 높은 보드 속도를 사용하게 되며, 그 예로 GPIB 디바이스를 들 수 있다. 데이터 비트는 전송되는 실제 데이터 비트의 측정값을 의미한다.
.NET C#을 이용한 시리얼 통신 구현
닷넷 프레임 워크에서는 System.IO.Port라는 시리얼 IO를 위한 네임스페이스를 제공한다(참조 - 다른 예제). 이 네임스페이스에서 제공하는 다양한 클래스들을 사용하여 시리얼 포트를 제어할 수 있으며 아래와 같은 방법으로 네임스페이스를 프로젝트에 추가해 준다.
1 | using System.IO.Port; | cs |
System.IO.Port 네임스페이스에는 SerialPort라는 클래스가 있으며 이 클래스를 통해 시리얼 포트에 대해 제어를 할 수 있다. 먼저 아래와 같은 방식으로 시리얼 포트 객체를 선언한다.
1 | SerialPort SP = new SerialPort(); | cs |
Baud rate, Stop bits, Data bit 등 시리얼 통신을 위한 여러 설정은 아래와 같은 방법으로 정의할 수 있다.
아래에 예에서 적용된 설정들은 이 설정들을 적용하지 않았을 경우 default 값으로 적용되는 값이다.
1 2 3 4 5 6 7 | SP.PortName = "COM1"; SP.BaudRate = (int)38400; SP.DataBits = (int)8; SP.Parity = Parity.None; SP.StopBits = StopBits.One; SP.ReadTimeout = (int)500; SP.WriteTimeout = (int)500; | cs |
실제 사용 가능한 시리얼 포트는 SerialPort.GetPortNames() 메소드로 얻어 올 수 있다.
foreach 문을 사용하면 모든 사용 가능한(물리적으로) 시리얼 포트를 찾을 수 있다.
1 2 3 4 | foreach(string comport in SerialPort.GetPortNames()) { } | cs |
Parity로 사용할 수 있는 값은 EVEN, MARK, NONE, ODD, SPACE이다. Stop Bits로 사용할 수 있는 값은 None, One, OnePointFive, Two이다.
여기까지 설정이 끝났다면 단순히 Open() 메소드를 사용하여 적용된 설정과 함께 포트를 열 수 있으며 IsOpen을 이용하여 포트가 정상적으로 열렸는지 확인할 수 있다.
필요한 Exception에 대한 핸들링도 주로 이곳에서 하게 된다.
1 2 3 4 5 6 7 8 9 10 | //Open() 메소드 SP.Open(); if(SP.IsOpen) // 포트 오픈 성공 { } else // 포트 오픈 실패 { } | cs |
정상적으로 시리얼 통신 포트가 열렸다면 Read/Write 작업에 대해 정리해 본다.
1 2 | SP.WriteLine("It's a Test."); SP.ReadLine(); | cs |
Read 작업의 경우 ReadByte, ReadChar, ReadExisting, ReadLine 중 필요한 메소드를 골라서 사용한다.
Win32에서 Read 작업의 경우 쓰레드를 만들고 이벤트를 감시하여 해당 이벤트(시리얼로 데이터가 들어오는)가 발생하면 특정 루틴으로 넘겨주는 방법을 사용하는데 닷넷에서도 마찬가지의 방법을 사용한다.
1 2 3 4 5 6 7 8 | //사용 예 void SP_DataRecieved(Object sender, SerialDataReceivedEventArgs e) { SP.ReadLine(); } SP.DataReceived += new SerialDataReceivedEventHandler(SP_DataRecieved); | cs |
시리얼 통신 개요, 구현, 포트 버퍼 설정 (C# SERIAL)