画像ファイル
画像ファイル RS-232C SerialPortクラス
RS-232C関係
1RS-232Cの基礎
2RS-232Cの何が変わった..
3SerialPortクラス
4Unicode(ユニコード)の壁
5マルチスレッドの壁
6RS-232C サンプルコード
7RS-232CのHEXモニタ
8RS-232C 送信モジュール
9RS-232Cのループテスト
10RS-232Cのピンチェンジ..

VB.NET C#全般
1羊の皮を着た狼 VB.NET
2Form1、Form2の相互参照
3Form1、Form2の相互参照 2
4VB.NET C# データ型の基本
5VB.NET C# 文字列
6VB.NET タイマー精度
7BackgroundWorkerの魅力1..
8BackgroundWorkerの魅力2..
9VB6のタイマー
10コントロールの配列をインデクサ..
11コントロールの配列はジェネリク..
12インデクサ(C#、VB.NET)
13インデクサでBit操作
14Unicode 入門
15デリゲート入門
16マルチスレッド入門
17イベント入門
18デリゲートとイベント
18インターフェースの基本

RichTextBox関係
1RichTextBoxの不思議
2テキスト色付け高速化計画
3VB.NET RichTextBox1
4VB.NET RichTextBox 2

Socket通信
1C#、VB2005 でSocket通信
2サーバー 複数接続

プロセス間通信
1プロセス間通信(送信側)
2プロセス間通信(受信側)


質問、意見はこちらに
画像ファイル


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 SerialPort の入力バッファから読み取ります
ReadByte SerialPort の入力バッファから、同期で 1 バイトを読み取ります
ReadChar SerialPort の入力バッファから、同期で 1 文字を読み取ります
ReadExisting ストリームと SerialPort オブジェクトの入力バッファの両方で、
エンコーディングに基づいて、即座に使用できるすべてのバイトを読み取ります
ReadLine 入力バッファ内の NewLine 値まで読み取ります
ReadTo 入力バッファ内の指定した value まで文字列を読み取ります

今回は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」を使用する場合は
改行文字には十分の注意が必要で有ることを意味します。
メソド 内容
Write (String) パラメータ文字列を出力バッファに書き込みます
Write (Byte[], Int32, Int32) 指定したバイト数を指定したオフセットで出力バッファに書き込みます
Write (Char[], Int32, Int32) 指定した文字数を指定したオフセットで出力バッファに書き込みます
   
WriteLine NewLineプロパティで設定された改行文字を末尾に付けて文字列を送信します

今回は受信もバイト配列だけで行います。
送信側と受信側を同じ読み込み方法で合わせる必要が有ると思われるかも知れませんが、
其の必要は有りません。
ただし文字列の送受信はどのエンコードクラス(Sift-jisやUnicode)で送受するかあらかじめ
決めておかないと文字化けを起こす可能性が有ります。

SerialPortクラスを使うと、今まで馴染んできたMSCommコントロールとほぼ同じ処理が可能となり、
ただしこれから述べる2つの点について十分注意する必要がある。
さてその2つの中の、1つ目は、Unicode対応で、2つめはマルチスレッドです。
これらの点を踏まえた送受信コードは、下記を御覧下さい。

画像ファイル