• 締切済み

シリアル受信の取りこぼし

C++で作成したシリアルの受信処理について 1.受信イベントを検知 2.ReadFileでデータ読み取り 3.データ解析 の動作をスレッドの中で行うようにしているのですが 大量のデータを受け取る時に、データの取りこぼしが発生します。 取りこぼしを防ぐ処理方法や設定などはないでしょうか

みんなの回答

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

2と3を同一スレッドで行ってるのならスレッドを分けましょう。 後は、処理が追いつかないときには送信側に待ってもらえる仕組みを用意するとか。

回答No.1

>取りこぼしを防ぐ処理方法や設定などはないでしょうか 全てのケースについて有効な手段は有りません。 データの来るタイミング、データ長、重要度など様々なファクターで対応方が違ってきます。 一般的にはデータが来たらデータの取り込みに専念し解析は後回しにするのですが、大量のデータが来ればオーバーフローは防げません。 最終的にはプロトコールを決めるか諦めるより有りません。

関連するQ&A

  • C++でシリアルの受信処理の作成

    C++でシリアルの受信処理を作成しようと思っているのですが データの受信とデータの解析を別スレッドに分けようと思っています。 データの受信スレッドでバッファにデータを受け取って行き、 データの解析スレッドでバッファのデータを解析しようと思っています。 データの受信スレッドについては作成できるのですが、解析について、受信スレッド側で データを受信しつつ、解析スレッドでデータの解析を行う解析スレッドはどのように 作れば良いでしょうか? もう少し具体的に、解析のスタート、解析するデータサイズ、解析のストップは どう指定すれば良いでしょうか

  • C++でシリアル受信処理を教えて

    表題のとおりC++でシリアルで受信処理を作成しようと思っています。 2つのスレッドで、片方のスレッドでデータを受信し、もう片方のスレッドでデータを解析、 という具合に受信と解析を同時並行して行うようなプログラムを組みたいのですがうまく いきません。 具体的なソースの書き方、またはそれらが記載されているサイトをご存知の方は 教えてください。

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

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

  • イベントの取りこぼしについて

    教えて下さい。 VBで構築したアプリケーションにおいて、無限ループ内で処理を判断し、実行するようなプログラム構築にしています。この無限ループ内に「DoEvents」をセットしています。これによりOSに溜まっている、各イベントを処理していると思うのですが、処理するイベントに取りこぼしは発生しないのでしょうか? 現在、A/Dボードを実装しており、2ms周期でVBのイベントが発生するようなソフトになっています。「DoEvents」実行時に、OS側が処理に要する時間は、キューに溜まっているイベント数×1回のイベント処理時間で単純に導けるものでしょうか? また、CPUのスペックを2倍にすると、単純に処理時間は半分と計算できるものでしょうか?

  • 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でもデータの取りこぼしがあります. 高速でシリアル通信を行う場合はどのように追プログラムを作成することが定石なのでしょうか?ドライバの開発などを行う必要があるのでしょうか?

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

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

  • シリアル通信について

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

  • シリアル通信時のデータ受信方法

    シリアル通信を実現しようとしていて、現在データ送信は完成しました。 しかし、データ受信方法が分かりません。 データはいつやってくるのかが分からないので、 「データ受信したら割り込み(イベント?)ルーチンに入る」という方法がいいかなあ、と考えています。 「データ受信したら割り込み(イベント?)ルーチンに入る」方法を教えてください。 もし他に方法があれば教えてください。 すみませんがよろしくご教授お願いいたします。

  • VB2005 シリアル通信のClose処理

    いつもお世話になっております。 表題の件につきまして、ご教示ください。 【処理内容】 メインフォームのボタンからポートをオープンし、 受信データ(1Byte)をテキストボックスに表示し続ける。 ※受信データは定期受信 通信をやめたいときにメインフォームのボタンから ポートをクローズする。 上記、クローズ時に、ほぼフリーズします。 原因はシリアル通信の受信イベントが別スレッドにて処理されているため、 Invoke()にてテキストボックスの更新をしており、 これが悪さをしているみたいです。 BeginInvoke()を使用するとフリーズは回避することができるのですが、 テキストボックスに表示される受信データの内容が激しく欠落してしまいます。 Invoke()を使いつつ、フリーズを回避する方法はないのでしょうか。 無知で大変申し訳ございませんが、よろしくお願いいたします。

  • シリアル通信プログラム(受信)について

    現在、シリアル通信をする(受信のみ)プログラムを作成しています。 接続先は1秒ごとに10バイトのデータを自動で送信してきます。 現段階でPC側でデータを受信できることは確認できました。 しかし、受信データが文字化け(出力結果が{や■などがでています)しており、その原因がわかりません。 どこが問題なのか教えていただけないでしょうか? また、接続先からは10バイトのうち最初の2バイトは固定の値(0x2b,0x22)がでてくるはずなのですが、それもでてきていません。これも文字化けで見えていないだけでしょうか? 文字化けしても周期的に固定の値に対応した文字がでてくるものだと思ったのですが、でてきていません。 (ソースで50バイトまでみているのはこの周期性を確認するためです) シリアル通信を初めてさわるので、考え方自体間違っているかもしれませんが 配列pszBufに1つずつ、受信された1バイトのデータが格納されていると思っています。 個人的にはprintfでの表記(%cがいけない?)に間違いがあるかと疑っています。 ご回答よろしくお願いいたします。 (環境) Visual C++ 2008 (C/C++) (シリアルポート設定) ボーレート 9600bps パリティ   なし ストップビット 1 データビット 8 (ソース) ※ポートの設定は省略。受信部のみ記述 HANDLE hComm; DWORD dwErrors; COMSTAT ComStat; char pszBuf[1024]; DWORD dwRead; ClearCommError(hComm, &dwErrors, &ComStat); ReadFile(hComm, pszBuf, 50, &dwRead, NULL);  //50バイトまでデータを取得 for(int i=0;i<50;i++){ printf("%c\n",pszBuf[i]); } (参考URL) http://www.geocities.jp/terukat/_geo_contents_/win/comm.html