수색…
기본 기능
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
serialPort.WriteLine("Test data");
string response = serialPort.ReadLine();
Console.WriteLine(response);
serialPort.Close();
사용 가능한 포트 이름 나열
string[] portNames = SerialPort.GetPortNames();
비동기 읽기
void SetupAsyncRead(SerialPort serialPort)
{
serialPort.DataReceived += (sender, e) => {
byte[] buffer = new byte[4096];
switch (e.EventType)
{
case SerialData.Chars:
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
// Process the read buffer here
// ...
break;
case SerialData.Eof:
// Terminate the service here
// ...
break;
}
};
동기 텍스트 에코 서비스
using System.IO.Ports;
namespace TextEchoService
{
class Program
{
static void Main(string[] args)
{
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
string message = "";
while (message != "quit")
{
message = serialPort.ReadLine();
serialPort.WriteLine(message);
}
serialPort.Close();
}
}
}
비동기 메시지 수신자
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace AsyncReceiver
{
class Program
{
const byte STX = 0x02;
const byte ETX = 0x03;
const byte ACK = 0x06;
const byte NAK = 0x15;
static ManualResetEvent terminateService = new ManualResetEvent(false);
static readonly object eventLock = new object();
static List<byte> unprocessedBuffer = null;
static void Main(string[] args)
{
try
{
var serialPort = new SerialPort("COM11", 9600, Parity.Even, 8, StopBits.One);
serialPort.DataReceived += DataReceivedHandler;
serialPort.ErrorReceived += ErrorReceivedHandler;
serialPort.Open();
terminateService.WaitOne();
serialPort.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception occurred: {0}", e.Message);
}
Console.ReadKey();
}
static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
lock (eventLock)
{
byte[] buffer = new byte[4096];
switch (e.EventType)
{
case SerialData.Chars:
var port = (SerialPort)sender;
int bytesToRead = port.BytesToRead;
if (bytesToRead > buffer.Length)
Array.Resize(ref buffer, bytesToRead);
int bytesRead = port.Read(buffer, 0, bytesToRead);
ProcessBuffer(buffer, bytesRead);
break;
case SerialData.Eof:
terminateService.Set();
break;
}
}
}
static void ErrorReceivedHandler(object sender, SerialErrorReceivedEventArgs e)
{
lock (eventLock)
if (e.EventType == SerialError.TXFull)
{
Console.WriteLine("Error: TXFull. Can't handle this!");
terminateService.Set();
}
else
{
Console.WriteLine("Error: {0}. Resetting everything", e.EventType);
var port = (SerialPort)sender;
port.DiscardInBuffer();
port.DiscardOutBuffer();
unprocessedBuffer = null;
port.Write(new byte[] { NAK }, 0, 1);
}
}
static void ProcessBuffer(byte[] buffer, int length)
{
List<byte> message = unprocessedBuffer;
for (int i = 0; i < length; i++)
if (buffer[i] == ETX)
{
if (message != null)
{
Console.WriteLine("MessageReceived: {0}",
Encoding.ASCII.GetString(message.ToArray()));
message = null;
}
}
else if (buffer[i] == STX)
message = null;
else if (message != null)
message.Add(buffer[i]);
unprocessedBuffer = message;
}
}
}
이 프로그램은 STX
및 ETX
바이트로 묶인 메시지를 기다리고 그 사이에 오는 텍스트를 출력합니다. 나머지는 모두 버려집니다. 쓰기 버퍼 오버 플로우시 중지됩니다. 다른 오류에서 입력 및 출력 버퍼를 재설정하고 추가 메시지를 기다립니다.
코드는 다음과 같이 설명합니다.
- 비동기 직렬 포트 읽기 (
SerialPort.DataReceived
사용법 참조). - 직렬 포트 오류 처리 (
SerialPort.ErrorReceived
사용법 참조). - 비 텍스트 메시지 기반 프로토콜 구현.
- 부분적인 메시지 읽기.
-
SerialPort.DataReceived
이벤트는 전체 메시지 (ETX
까지)보다 먼저 발생할 수 있습니다. 전체 메시지는 입력 버퍼에서 사용할 수 없습니다 (SerialPort.Read (..., ..., port.BytesToRead)는 메시지의 일부만 읽음). 이 경우 수신 된 부분 (unprocessedBuffer
)을 숨기고 추가 데이터를 기다리는 동안 계속 수행합니다.
-
- 한 번에 여러 메시지를 처리합니다.
-
SerialPort.DataReceived
이벤트는 다른 쪽에서 여러 개의 메시지를 보낸 후에 만 발생할 수 있습니다.
-
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow