RS-232C SerialPortクラス | |
|
SerialPortクラスとは
Microsoft .NET Framework のバージョン2.0からSystem.IO.Ports.SerialPortクラスと言うものが加わった、
これは、VB6のMSCommに相当するものである。 もちろんVB.NET上でVB6のMSCommを使用することも出来る、しかしそのためには、 VB6を開発マシンにインストールする必要が有たりライセンスの問題も有る。 またAPIを使ってもシリアル通信は可能であるが、Pinvokeを使うわずらわしさが付きまとう。 ようやくここに来てSystem.IO.Ports.SerialPortクラスが出来、VB6からの乗り換えに弾みがつくであろう。 SerialPortクラスの使い勝手はほぼMSCommコントロールと同じである、ただし私が使ってみたところ、 2つの大きな違いが有っので、ここではその違いについて述べる。
受信
MSComm コントロールは 受信処理として Input プロパティ持っていた、
SerialPortクラスは6つの読み込み手段をもっている。
今回はReadだけ使用します。 Readは2つのオーバーロードを持っていて、バイト配列と、文字配列の引数を取ります。 ・SerialPort.Read (Byte[], Int32, Int32) ・SerialPort.Read (Char[], Int32, Int32) 今回はこのSerialPort.Read (Byte[], Int32, Int32) を使った受信方法を説明する。 なぜバイト配列かと言うと、コードをなるべく汎用の物にしたい為です。 バイト配列を使えば、文字列とバイト送信の両方に対応出来ます。 ReadByte、ReadCharはそれぞれ入力バッファから1Byteと1文字を取得しますが、 よほど短い受信データで無い限り処理が間に合わなくなる可能性が有りますので、 使用しない方が良いと思います。 ReadExistingですが、説明で「エンコーディングに基づいて、即座に使用できるすべてのバイト」とは 何でしょうか? MSDNの解説には このメソッドは、ストリームと SerialPort オブジェクトの入力バッファの内容を文字列として返します。 このメソッドでは、タイムアウトは使用しません。このメソッドは、内部バッファに後続の 先行バイトを残すことができるため、BytesToRead 値は 0 より大きくなります。 となっています。 多分エンコードクラスの文字列で文字に変換出来るバイトだけを取得し、文字を表すバイトが泣き別れ になった場合は、其のバイトを読み取らずにバッファに残す為読み込んだ後に、BytesToRead が0 にならないことが有るとの事なのでしょう。 先の説明で「即座に使用できる」とは文字に変換できると言うことだと思います。 ReadLineこれも一癖有ります。 これで読み込む文字列の改行はserialPort1.NewLineで設定した改行文字で、 デフォルト(何も設定しないと)では"\n"(VBではchr(10))です。 しかもこれは読み込まれずに捨てられるのです。
送信
さて書き込みであるが、「Write」メソドは送信のバッファへの書き込みは3つの異なった 引数の関数が用意されている。 又、「WriteLine」メソドは 「serialPort1.NewLine」プロパティで設定された改行文字を 末尾に付けて文字列を送信します。 送信でも書きましたが、ここで注意することは、serialPort1.NewLineはデフォルト(何も設定しないと)では "\n"(VBではchr(10))を改行文字として付加します。 これはFrameworkのstreamはデフォルトではUTF-8のコードを吐き出す為で有ると考えられます。 つまり送信文字がアルファベットと数字だけであっても「WriteLine」を使用する場合は 改行文字には十分の注意が必要で有ることを意味します。
今回は受信もバイト配列だけで行います。 送信側と受信側を同じ読み込み方法で合わせる必要が有ると思われるかも知れませんが、 其の必要は有りません。 ただし文字列の送受信はどのエンコードクラス(Sift-jisやUnicode)で送受するかあらかじめ 決めておかないと文字化けを起こす可能性が有ります。 SerialPortクラスを使うと、今まで馴染んできたMSCommコントロールとほぼ同じ処理が可能となり、 ただしこれから述べる2つの点について十分注意する必要がある。 さてその2つの中の、1つ目は、Unicode対応で、2つめはマルチスレッドです。 これらの点を踏まえた送受信コードは、下記を御覧下さい。 |