• 締切済み

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

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

みんなの回答

  • chie65535
  • ベストアンサー率43% (8521/19370)
回答No.1

シリアル通信は、基本「データの垂れ流し」ですから、どこかで「データを区切る」必要が出て来ます。 その為、送信側で「ここが区切りです」と言うデータを送信する必要があります。 例えば、データをテキスト(可読文字のみ)で送るなら、改行を「区切り」として送るとか。 例えば、データをバイナリで送るなら、レコードの初めにレコード長とマーカーを送って、レコードの最後にCRCとマーカーを送るとか。 このように、データに「区切り」を入れて「レコード単位」で送信するようにしないと、受信データを解析する事は出来ません。 受信ルーチンでは、垂れ流されてくるデータを受け取りつつ「データの区切りごと」に、解析スレッドに「1レコード分溜まったから解析しろ」と、シグナルを送ります。 解析ルーチンでは、シグナルを受け取ったら、受信ルーチンに対し「1レコード分くれ」と要求し、受け取ったレコードを解析します。 受信ルーチンでは「レコードの整合性」をチェックして、不整合があるなら「応答としてNAKを返す」などして、送信側に「受信失敗」を送り返します。 いずれにせよ「データ化け」や「データ欠落」に配慮したルーチンにしないと、解析は上手く行きません。

関連するQ&A

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

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

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

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

  • シリアル通信 大きいサイズの受信処理

    シリアル通信 大きいサイズの受信処理で質問があります OS:LINUX 開発環境 QT5.3 今 相手側機器から10秒ごとに190011Byteのデータくるようなしようとなっています そこで質問ですが 受信側ではどのような処理を組めば10秒ごとに来るデータをすべて受信できるのか よろしくお願いします open関数やread関数などを使用しています ボーレート値は230400bpsです 送受信バッファは1024byteとなっています

  • Arduino シリアル通信でのバイナリ受信

    詳しい方教えてください。 送信元のPCから、受信側のArduinoへ、シリアル通信によってバイナリデータを送ることで、Arduino側でのサーボモータのシリアル駆動を試みています。 PC側からのバイナリデータ送信はVB.NET側で作成済みで、USB-TTLコンバータ(FTDI Basic Breakout 5V)を使ってのサーボモータのシリアル駆動は問題ありません。 (http://micono.cocolog-nifty.com/blog/2011/04/arduino11-17d5.html と同じ処理と思ってください。) 同様な処理を、PC-Arduinoで駆動させようと思っていますが、 void loop() { int c; if (Serial.available() > 0){ c = Serial.read(); ・・・・ こちらでは、Cの値がint型の為かうまくいきません。(キャストも試しましたが・・) そもそも1バイトデータの受信Serial.read()が、int型(2バイト)なのか判りません。 方法はありますでしょうか。

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

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

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

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

    現在、シリアル通信をする(受信のみ)プログラムを作成しています。 接続先は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

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

    シリアル通信のデータ欠けについて教えてください。 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でシリアルの高速受信を行うと、データ欠けが発生するのが当たり前なのでしょうか?

  • シリアル通信について

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

  • C++マルチスレッド処理について

    こんにちは 現在スレッドを作成して,マルチスレッド処理をしようとしているのですが, 全然理解できないので皆様のお力をお貸し下さい。 やりたい事は, (1) メインスレッドからスレッド1を作成。 (2) スレッド1では,ひたすらファイルなどからデータを取得させる。(読み込めなくなるまで) (3) メインスレッドでは,時々スレッド1を止めて,再度処理を続行させたい。 class Sample { public: // Sampleオブジェクト作成,同時にスレッド1を作成 Sample* create(); // スレッド1を止めて,再度動かす void process(); private: // この関数をスレッド1で処理させる // 内部では,読み込めなくなるまで無限ループ? void get(); }; スレッドに関してはイメージが湧くのですが, mutex (必要ですか?) に関しては一向に理解できません。 何を排他制御するのでしょうか。オブジェクト? 関数? 複雑ではなさそうなのですが,今までシングルスレッドの処理のみ書いていたため ピンときません。 よろしくお願い致します。

専門家に質問してみよう