C#의 직렬 포트에서 읽기 및 쓰기
이 자습서는 C# 언어의 직렬 포트 개념과 데이터 읽기 및 쓰기 용도를 이해하는 데 도움이 됩니다. 예제 프로젝트를 통해 C#으로 구현된 SerialPort
클래스를 시연합니다.
직렬 포트
당사의 컴퓨터 시스템에는 다양한 목적으로 데이터를 전송할 수 있는 여러 포트가 있습니다. 직렬 포트는 여러 비트를 병렬로 공유하는 것이 아니라 한 번에 한 비트의 데이터를 전송하여 데이터를 순차적으로 전송하는 인터페이스입니다.
C#
의 직렬 포트
C#은 프로그램에서 직렬 포트 기능을 구현하기 위한 기본 제공 클래스를 제공합니다. 시스템의 직렬 포트에 연결된 장치로 데이터를 주고받을 수 있습니다.
직렬 포트 클래스를 구현하는 네임스페이스는 System.IO.Ports
입니다.
프로그램에서 System.IO.Ports
네임스페이스를 가져오고 정적 클래스 SerialPort
의 개체를 생성해야 합니다.
SerialPort
클래스는 기본 생성자를 제공하며 생성자는 오버로드되어 다른 매개변수가 필요합니다. 다음은 기본값과 오버로드된 생성자 중 하나를 사용하여 개체를 초기화하는 예입니다.
다음 코드의 두 번째 줄은 오버로드된 생성자를 사용하여 PortName
, BaudRate
, Parity
, DataBits
및 StopBits
를 초기화합니다.
static SerialPort _serialPort = new SerialPort();
SerialPort _serialPort = new SerialPort("COM3", 9600, Parity.One, 8, StopBits.Two);
SerialPort
클래스에는 BaudRate
, BytesToWrite
, BytesToRead
, DataBits
, Encoding
, PortName
, Parity
등과 같은 속성이 포함되어 있습니다. 통신을 위한 완전한 기능을 제공하기 위해 수많은 공개 메서드가 구현되었습니다. 예: Close()
, GetPortNames()
, Open()
, Read()
, Write()
등
ReadTimeOut
및 WriteTimeOut
과 같은 속성도 다음과 같이 설정할 수 있습니다.
_serialPort.ReadTimeout = 1000;
_serialPort.WriteTimeout = 1000;
필요한 모든 매개변수 값을 설정한 후 Open()
메서드를 사용하여 통신용 포트를 열도록 컴파일러에 알려야 합니다.
_serialPort.Open();
ReadLine()
메서드는 직렬 포트를 통해 수신된 메시지를 읽을 수 있습니다.
string message = _serialPort.ReadLine();
C#
을 사용하는 직렬 포트 채팅 애플리케이션
이 섹션에서는 통신을 위해 직렬 포트를 사용하는 채팅 응용 프로그램을 위한 완전한 C# 프로그램을 제시합니다. 이 코드 스니펫은 데이터를 송수신하기 위해 연결된 두 시스템 모두에서 실행되어야 합니다.
참고:
null
모뎀 케이블을 사용하여 시스템을 연결하십시오.
Visual Studio에서 C# 프로젝트를 만들고 코드 스니펫을 Program.cs
파일에 붙여넣고 실행합니다.
using System;
using System.IO.Ports;
using System.Threading;
public class MyChatBot {
static bool _resume;
// Create a new SerialPort object
static SerialPort _serialPortObj = new SerialPort();
public static void Main() {
string userName;
string inputMessage;
Thread read_Thread = new Thread(Read);
StringComparer string_Comparer = StringComparer.OrdinalIgnoreCase;
// Set the required attributes.
_serialPortObj.PortName = SetPort(_serialPortObj.PortName);
_serialPortObj.Parity = SetParity(_serialPortObj.Parity);
_serialPortObj.StopBits = SetStopBits(_serialPortObj.StopBits);
_serialPortObj.Handshake = SetHandshake(_serialPortObj.Handshake);
// Set the read/write timeouts
_serialPortObj.ReadTimeout = 1000;
_serialPortObj.WriteTimeout = 1000;
_serialPortObj.Open();
_resume = true;
read_Thread.Start();
Console.Write("Enter Your Name: ");
userName = Console.ReadLine();
Console.WriteLine("Type Exit to exit");
while (_resume) {
inputMessage = Console.ReadLine();
if (string_Comparer.Equals("exit", inputMessage)) {
_resume = false;
} else {
_serialPortObj.WriteLine(String.Format("<{0}>: {1}", userName, inputMessage));
}
}
read_Thread.Join();
// Close the serial port
_serialPortObj.Close();
}
public static void Read() {
while (_resume) {
try {
// read the received message
string _recerivedMessage = _serialPortObj.ReadLine();
Console.WriteLine(_recerivedMessage);
}
catch (TimeoutException) {
}
}
}
// setters for attributes
public static string SetPort(string defaultPortName) {
string newPortName;
Console.WriteLine("Available Ports:");
foreach (string a in SerialPort.GetPortNames()) {
Console.WriteLine(" {0}", a);
}
Console.Write("Enter COM port value (Default: {0}): ", defaultPortName);
newPortName = Console.ReadLine();
if (newPortName == "" || !(newPortName.ToLower()).StartsWith("com")) {
newPortName = defaultPortName;
}
return newPortName;
}
public static Parity SetParity(Parity defaultParity) {
string parityValue;
Console.WriteLine("Available Parity Values:");
foreach (string a in Enum.GetNames(typeof(Parity))) {
Console.WriteLine(" {0}", a);
}
Console.Write("Enter Parity value (Default: {0}):", defaultParity.ToString(), true);
parityValue = Console.ReadLine();
if (parityValue == "") {
parityValue = defaultParity.ToString();
}
return (Parity)Enum.Parse(typeof(Parity), parityValue, true);
}
public static StopBits SetStopBits(StopBits defaultStopBits) {
string stopBitValue;
Console.WriteLine("Available StopBits Values:");
foreach (string a in Enum.GetNames(typeof(StopBits))) {
Console.WriteLine(" {0}", a);
}
Console.Write(
"Enter a StopBits value (ArgumentOutOfRangeException occurs for None value. Select another. \n (Default Value: {0}):",
defaultStopBits.ToString());
stopBitValue = Console.ReadLine();
if (stopBitValue == "") {
stopBitValue = defaultStopBits.ToString();
}
return (StopBits)Enum.Parse(typeof(StopBits), stopBitValue, true);
}
public static Handshake SetHandshake(Handshake defaultHandshake) {
string handshakeValue;
Console.WriteLine("Available Handshake Values:");
foreach (string a in Enum.GetNames(typeof(Handshake))) {
Console.WriteLine(" {0}", a);
}
Console.Write("Enter Handshake value (Default: {0}):", defaultHandshake.ToString());
handshakeValue = Console.ReadLine();
if (handshakeValue == "") {
handshakeValue = defaultHandshake.ToString();
}
return (Handshake)Enum.Parse(typeof(Handshake), handshakeValue, true);
}
}
위의 코드 스니펫은 먼저 SerialPort
객체를 생성하고 선택적 속성을 설정하기 위해 setter를 구현합니다. BaudRate
및 DataBits
의 기본값은 공통이므로 사용자가 설정할 필요가 없습니다.
Read()
함수는 직렬 포트에서 입력을 읽습니다. 프로그램은 사용자에게 입력 텍스트를 입력하라는 메시지를 표시하고 사용자가 exit
를 입력할 때까지 직렬 포트로 보냅니다.
SetPort()
, SetParity()
, SetStopBits()
및 SetHandshake()
는 속성 값을 설정하는 설정자입니다.
출력:
사용자는 사용 가능한 옵션을 선택하여 필요한 값을 설정하라는 메시지가 표시됩니다. 예를 들어 다음 출력에서 Com3
, Parity
값을 Odd
, StopBits
를 Two
로 선택했습니다. 핸드셰이크
값은 없음
입니다.
매개변수 값을 설정한 후 사용자가 exit
를 입력하여 프로그램을 종료할 때까지 직렬 포트를 사용하여 통신이 시작됩니다.