シリアル通信のデータ欠けについて

このQ&Aのポイント
  • WindowsXP上でシリアル通信「115200bps、8、None(ODD、EVEN)、1」の設定で、1ms毎に12バイトの送受信を行っているのですが、1分ほど受信すると、データ欠けが発生します。
  • 受信プログラムはこの問題が発覚してから、受信したデータを変数にバッファリングし、保存ボタンを押してから、ログファイルへ保存するシンプルなプログラムを作成し、確認しています。
  • 一般的にWindowsでシリアルの高速受信を行うと、データ欠けが発生するのが当たり前なのでしょうか?
回答を見る
  • ベストアンサー

シリアル通信のデータ欠けについて

シリアル通信のデータ欠けについて教えてください。 WindowsXP上でシリアル通信「115200bps、8、None(ODD、EVEN)、1」の設定で、1ms毎に12バイトの送受信を行っているのですが、1分ほど受信すると、データ欠けが発生します。 受信プログラムはこの問題が発覚してから、受信したデータを変数にバッファリングし、保存ボタンを押してから、ログファイルへ保存するシンプルなプログラムを作成し、確認しています。 「切り分けた内容」 1、57600bpsでも発生する 2、VB6、VisualStudio2008 C#で作成したツール及びフリーソフト(SerialDebugger)でも、データ欠けが発生する 3、RS232Cラインモニタ(キャロちゃん)で確認すると、データ欠けは発生していないので、受信側の問題と判断しています。 4、送信間隔を50msと遅くしても発生する 5、RS232C及び、USB変換したものどちらでも発生する 6、9600bpsでは、発生しない(同じデータ数での判断) 7、ケーブル長は1mほど ちなみに通信時間に余裕が無い為、チェックサムやハンドシェイクなどの機能は、入れられません。 一般的にWindowsでシリアルの高速受信を行うと、データ欠けが発生するのが当たり前なのでしょうか?

  • tad_
  • お礼率100% (7/7)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>VC++6.0では、文字抜けは無いとのことですが、通信速度はいくらだったで >しょうか?  はっきり記憶にあるのは19200bps,100ms間隔で数10バイト受信です。  受信スレッドを起動した場合38400までは実験したように記憶があります。  115200bpsならCOMタイムアウトの設定もそれなりの値を設定してやる 必要が有るかと思います。 //------------- タイムアウト値設定 100ms 間隔 ::GetCommTimeouts(hSerialPort, &CommTimeouts); // 受信文字間タイムアウト[ms] CommTimeouts.ReadIntervalTimeout= 20;大きすぎ以下同じ // 受信文字数比例タイムアウト [ms] * 文字数 CommTimeouts.ReadTotalTimeoutMultiplier = 5; // 受信基底タイムアウト値 CommTimeouts.ReadTotalTimeoutConstant = 20; // 送信文字数比例タイムアウト値[ms] * 文字数 CommTimeouts.WriteTotalTimeoutMultiplier= 2; // 送信基底タイムアウト値[ms] CommTimeouts.WriteTotalTimeoutConstant = 50;大きすぎ ::SetCommTimeouts(hSerialPort, &CommTimeouts);  後、115200bps,1ms間隔,12バイトだと1msを超えるので、 10ms間隔ぐらいでないとうまくいかないと思います。  それか送受信フロー制御で送信側を待たせるかです。

tad_
質問者

お礼

何度もご回答ありがとうございます。 また、サンプルまで紹介頂き、ありがとうございます。 > 後、115200bps,1ms間隔,12バイトだと1msを超えるので、 >10ms間隔ぐらいでないとうまくいかないと思います。 上記の件ですが、 12バイト = 8bit * 12 = 96bit 1秒間送信データ数 = 96bit * 1000ms = 96000bps で、間に合うのでは無いのでしょうか? 送受信フロー制御については、検討してみます。 アドバイスありがとうございます。

その他の回答 (3)

回答No.4

>12バイト = 8bit * 12 = 96bit  シリアルインタフェース(RS-232-C)では、スタートビット ストップビットが付加されて1バイト10bitになります。  さらにパリティを有効にすると11 bitになってしまいます。

tad_
質問者

お礼

ご回答ありがとうございます。 確かに仰るとおりですね。 完全に抜けていました。 その後の仕様の変更で、10バイトですみそうです。 ただ10バイトでも、事象は同じなんですよね~。

回答No.3

 1分間は文字抜けしないなら、取り出すアプリ側で工夫すれば 10~50ms間隔なら文字抜けしないようにする事は出来るんではな いかと思います。  受信イベントを通知されたら ClearCommError()でCOMSTATを 取出し cbInQue の値だけCOMポートから取出してバッファに格納 すれば、取出しは間に合うんではないかと思います。  回答2の追補です。

tad_
質問者

お礼

アドバイスありがとうございます。 こちらも、参考にさせて頂きます。

回答No.1

>一般的にWindowsでシリアルの高速受信を行うと、データ欠けが発生 >するのが当たり前なのでしょうか? そんな事は有りません、VC++6.0で受信スレッドを起動した場合 文字抜けは経験しませんでした。  VBでスレッドが起こせるのか知りませんが受信スレッドを使えば 解決すると思います。

tad_
質問者

お礼

ご回答ありがとうございます。 VC++6.0では、文字抜けは無いとのことですが、通信速度はいくらだったでしょうか? VB6でも9600bpsでは、データ欠けは発生しませんでした。 VB6では、スレッドの作成はできませんが、受信イベントが発生します。データの送信間隔を遅らせても発生しますので、処理速度が間に合わなくて、発生してるわけでもなさそうなんですよね。 他にC#でも発生していますので、VB6だけの問題だとも考にくいのですが、他に情報はお持ちでは無いでしょうか?

関連するQ&A

  • シリアル通信 VB 受信したデータ

    初めまして。 今現在,RS-232Cのシリアル通信で,重量計で測定したデータ(990kg)をCOM1に取り込めるようにするプログラムを作成中です。 出力データのフォーマットは以下のようになっています。 ST   , GS   , +0012345  kg  CRLR  ヘッダ1  ヘッダ2   データ  単位  ターミネータ 18バイトのデータを受信していることになります。 ここで質問なのですが,プログラムでは1バイトずつイベントを発生させて1バイトずつ受信させているのですが,1バイト×18回 のデータをどのようにつなぎ合わせれば18バイトのデータとして扱えるようになるのですか? うまく説明できていないかも知れませんが,お分かりの方がいらっしゃいましたら宜しく御願いします。 VBではOnCommを使用しています。

  • シリアル通信の原理について

    シリアル通信の調歩同期式は、「伝送を開始する際にまずスタートビットを送り、続いて一文字分のデータ(7~8ビット)、パリティビット、最後にストップビットを送る。」と多くのウェブサイトで解説されていると思います。 またビットレートも1200bps/2400bps/4800bps/9600bps・・・など複数あると思います。 上記仕様については理解しているのですが、これらを実現する具体的な仕組みが分かりません。 具体的には、 1.受信側は送信側のビットレートをどのように知るのでしょうか? 2.同様にデータが7ビットと8ビットのどちらであるかをどうやって判断するのでしょうか? 3.受信側は送られてきたデータのビットを1バイト毎にレジスタやメモリに格納すると思うのですが、1つのプログラムにつきどこからどこまでが該当のデータであるかをどうやって判断するのでしょうか?(送られてくる全体のデータサイズをどうやって知るのでしょうか?) ググっても上記の具体的な解説が見つからず、理解できずにおります。 ご回答どうぞよろしくお願いします。

  • VBによるシリアルポート制御

    VB6でシリアルポートからデータを取り込むプログラムを作っています。 データは、バイナリモードで、合計26バイトあります。 これが、20ms間隔で送られてくるデータは、うまく取れたのですが、データを送る間隔を5msにしたところ、うまく受信できないようで、データが表示されなくなってしまいました。 ちなみに20ms間隔の時のシリアルポートのスピード設定が19200bpsで、5ms間隔の時には、115200bpsに変更しています。 VBで115200bpsのポート制御は難しいのでしょうか? それとも、小生のプログラムに問題があるのでしょうか?

  • シリアル通信でのデータ取りこぼし

    はじめまして。 現在、計測機器からシリアル通信で測定値を取得しています。 その測定機器は1秒間当たり、1000データ測定できるのですが、 プログラムで収集した際、取りこぼしが多く発生します。 取りこぼしがないよう収集するには どうすれば、いいのか、教えていただけないでしょうか? よろしくお願いします。 動作の流れは  (1)測定ボタンを押す  (2)1秒間測定する (1000データ) → 保存 ◆教えてほしい箇所  (3)1秒後自動的に終了する 環境  OS:Windows XP  プログラム:VB.NET 2008  通信:RS232C  測定データ1個当たり:X.XXXX (6桁)

  • C#のシリアル通信プログラムで文字化け

    Visual C#でRS-232のシリアル通信をするプログラムを作成しましたが、 受信データが文字化けを起こしてしまいます。 下のURLにソースを置いているので、どこが不味いのか教えてください。 http://www1.axfc.net/uploader/Sc/so/205741 よろしくお願いいたします。

  • シリアル通信について

    VB6にてシリアル通信プログラムを作成しましたが、データが受信できません。 ハイパーターミナルなら受信できて、一度ハイパーターミナルを使用すると、作成したプログラムでもデータが受信できるようになります。(再起動するとまたハイパーターミナルを使用するまで受信できません) 自作プログラムでなにか処理がたりないのでしょうか?

  • C#で仮想COMポートのシリアル通信

    Windows C#などを用いてマイコンボードとUARTで通信するアプリを作成しています. 従来は20bit程のデータを38400bpsで50回/sec程度受信して、グラフ表示していました. 今回新たに1000回/sec程受信したいと考えています. 高速シリアルで検索すると以下のような商品が見つかり、ハード的には高速で通信できるようでした. https://strawberry-linux.com/catalog/items?code=50028 C#ではserialPort_DataReceivedイベントでバッファーのデータを配列に取り込み、\r\nを受信した時点で処理-->グラフ表示を実行しています. 上記のプログラムでは50回/secでもデータの取りこぼしがあります. 高速でシリアル通信を行う場合はどのように追プログラムを作成することが定石なのでしょうか?ドライバの開発などを行う必要があるのでしょうか?

  • シリアル通信でのデータ分け

    プログラミングをしていて詰まったところがあるので教えていただけると幸いです。 開発環境はWindows XPでVisual C++ 2005 です。 シリアル通信において次々と送られてくるデータを1データずつ間違いがないように受信することを考えます。 例えば1つのデータが10バイトからなっていて、そのはじめが 0x10というものだったとすれば、 0x10を検出し、その10個分先の0x10の1つ前までが1データ分となると思います。 これを繰り返して全てのデータを正しく取得したいのですが、プログラムの方法が思い浮かびません。 こんなプログラムの方法はどうか、こんな関数を使ってみてはどうか、などありましたらご教授下さい。 よろしくお願いいたします。

  • シリアル通信

    プログラム初心者なんですけど、C++Builder4でシリアル通信(送信・受信)をおこないたいのですが、方法を教えて下さい。内容が複雑なようなら良い参考例や方法がのっている本やホームページを知っていたら教えて下さい。宜しくお願いします。

  • シリアル通信について教えてください

    VC6.0のRS-232Cでシリアル通信をするプログラミングについて説明してあるサイトやサンプルソースがあるサイトがあったら教えてください。