COMポート
最終更新:
atachi
.NET Frameworks2以降でシリアルポートがサポートされています。
SerialPortはSystem.IO.Portsに所属します。
WindowsFormプロジェクトでは、SerialPortコントロールがコンポーネントとして使用できます。
WPFではコントロールとしては存在しませんので、System.IO.Ports.SerialPortクラスのインスタンスをソースコード上で作成して使用します。
COMポートの制御方法一覧
ポートの列挙 | string[] ports = SerialPort.GetPortNames(); |
C#によるCOMポートの制御方法
US-ASCIIをポートの入出力にする場合、WriteLine/ReadLineを使用できます。
// 【ポートのオープン】
// 「COM1」というCOMポートがシステムに存在しているものとする
SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Open();
port.DtrEnable = true;
port.RtsEnable = true;
// 【ポートへの書き込み】
port.WriteLine("Hello"); // WriteLineでは、指定した文字列の末尾に
// 自動的に改行コード(※1)が追加される
// 【ポートからの読み込み】
string read = port.ReadLine(); // ReadLineでは、文字列をポートから読み込む。
// ポートからのデータに、改行コードを検出すると、
// 改行コード(※1)を削除したものを返値する。
// 【ポートのクローズ】
port.Close();
// ※1 改行コードは「CLRF = 0x0d 0x0a」(2バイト)
ちなみに、SerialPortクラスはIDisposableインターフェースを提供しているので、C#の流儀に従うなら次のように記述するほうが安全。
using(SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One) ) {
port.Open();
}// port.Close()は不要
バイナリデータの入出力
SerialPort.Read または SerialPort.Write を使用してバイナリデータの入出力ができます。
非同期通信
イベントを使うことでポートにデータが到達した場合にリスナーハンドラを呼び出すことができます。
// portはSerialPortオブジェクト
port.DataReceived += new SerialDataReceivedEventHandler(OnSerialDataReceived);
void OnSerialDataReceived(object sender,SerialDataReceivedEventArgs e) {
// 受信時の処理
SerialPort s = sender as SerialPort;
}
文字列エンコーディング
COMポートから日本語を受け取ることもできます。
C#では文字列をstring型として扱い、この型にはエンコード情報が含まれているため、C#では複数のエンコードを1つの型で表現できるのです。
COMポートから送られてくる日本語のエンコード形式を指定することで、SerialPort.ReadLine()は適切なエンコード処理を行い、string型を返すことができるのです。
// portはSerialPortオブジェクト
port.Encoding = Encoding.GetEncoding("Shift_JIS"); // ReadLineで取得する文字列のエンコード形式がShiftJISであることを指
送受信のタイミング
SerialPortのメソッドを使用している限り、そのメソッドを呼び出した直後にポートによりデータが送受信されます。
ただし、送受信に失敗するケースがあります。ハンドシェークを使用してCOMポートを制御している場合に、デバイスが準備できていないことを検出するなどの原因で直ちに送受信が行えないなどです。
このような場合、SerialPort.ReadやSerialPort.Writeは例外をスローします。