2010-12-31 7 views
1

私はCOM2ポートでデータを受信するためのC#プログラムを作成しました。ボーレートは115200に設定されています。送信側は115200bpsでデータを送信しています。私のプログラムは、何バイトかを毎回失っています。私はcomポートからwhile(true)ループ内のデータを読み取るためにReadByteメソッドを呼び出しています。c#シリアルポートのデータ損失

私はいくつかの質問があります:

  • ボーレートが高く設定されている、私はデータを失うことを期待すべきか?はいの場合、なぜですか?
  • 私は100 * 1024 * 1024として、読み取りバッファサイズを設定しています。シリアルドライバのバッファサイズを100 * 1024 * 1024に設定していますか?

この問題のデバッグ方法について考えてみましょうか?

+2

whileループ内で 'ReadByte'以外に何をしますか?処理にはどのくらい時間がかかりますか? –

+0

シリアルポートからバイトを読み取った後、バッファが12バイトに達するまでバッファに格納されます。それが12バイトに達すると、それは非常に短い時間を要する定義されたコマンドと比較される。 – user209293

+1

まだフロー制御を使用していない場合は、フロー制御を使用していることを確認する必要があります。 –

答えて

3

ボーレートを高く設定すると、データが失われるはずですか?はいの場合、なぜですか?

必ずしもそうである必要はありません。物理的な接続が悪いために発生する可能性があります(長すぎます)。

私は十分より(道)よりべきである* 1024 * 1024 100

などのReadBufferサイズを設定しています。

1バイトのループと読み取りは、ポートを読み取る最も効率的な方法ではありません。

DataReceivedイベントに接続し、ReceivedBytesThreshold = 12に設定できます。あなたはいつでもただ読むことができます(バッファ、0,12)

4

受信バッファーのサイズは100 * 1024 * 1024は巨大です!私は真剣にあなたがこのサイズを必要としているかどうか、そして確かに実際のシリアルポートバッファではないと疑うだろう。

受信者の物理的な受信バッファがあふれている可能性があるので、フロー制御の使用を検討する必要があります。これは効果的にあなたのレシーバがあなたのトランスミッタに言うことができるようになります"ハングオン、しばらくの間、送信を停止して、私が最初に持っているものに対処しましょう。

ハードウェアフロー制御は、RTS(Request To Send)ピンとCTS(Clear To Send)ピンを介して(一般的に)使用されます。

詳しくはthisの記事をご覧ください。

シリアルポートのReceivedBytesThresholdプロパティをデフォルト値の1にしてから、DataReceivedイベントを処理することをお勧めします。誰かが知っている、おそらく明日あなたは20バイト、またはおそらく5バイトのメッセージを読む必要があります。将来的に可変長のメッセージを読む必要があるでしょうか?しきい値を1に設定すると、現在および将来受信されるすべてのバイトを処理できます。

このしきい値は、バッファ内に以上、少なくともがある場合にイベントが発生することを意味します。多分もっと多分、そしておそらくそうであろう。 NOTは、受け取った1バイトごとに必ず発生することを意味します。各イベントで、BytesToReadプロパティをチェックし、この多くを自分のバッファに読み込む必要があります。

イベントは、受け取った1バイトごとに必ずNOTになることを繰り返す価値があります。

また、DataReceivedイベントハンドラ内でできるだけ少なくすることをお勧めします。あなたのバッファに受け取った任意のバイトを読み込み、完了したメッセージをキューに追加して処理しますが、それ以外はほとんど行いません。

RS232標準最大仕様は19200ボーの速度と50フィートのケーブルの長さがあることに注意します。それ以上のものは定義されていません。高速化のためには、一般に、ケーブル(容量が小さい)とケーブル長が短くて済みます。モーター、モーターインバータ、ライブケーブルなどの他の「騒々しい」アイテムの近くでは遮蔽されていないことを確認してください。

+1

+1フロー制御の推奨 –

+0

データ受信イベントを追加し、受信バイトthresoldを1に設定しました。他のスレッドがこの受信イベントの影響を受けていることがわかりました。それは起こることができますか?タイマイベントを発生させる4つのtimers.timerが定義されています。シリアルポートが受信されると、タイマーイベントは定義された間隔で起動されません.1秒または2秒だけオフセットされます。 – user209293