.NET Framework
シリアルポート
サーチ…
基本操作
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