• ベストアンサー

RS-232Cでバイナリデータを受信する方法

2台のPCを使用しバイナリファイルをRS232Cを使用し1台目のPCは送信専用、2台目のPCは受信専用で、送信側のPCから出したデータを受信側PCでデータの内容を判断し集計するプログラムを作ろうとしています。 送信側のPCでは、"AAB9AAC2AACC01D8AAE2・・・”といった内容のバイナリファイルの内容を1バイトずつ読み込み、それをMsCommを用いてバイナリモードで送信させて、EOFになるまで永遠とそれを繰り返します。 問題は受信側で、たとえば上記のデータの中の"AAB9"ならばカウントを1つ上げる、"AACC01D8"ならばカウントを1つ下げ、それを表示するといったような処理をリアルタイムで行いたいのですが、どうしてもデータの取りこぼしが発生します。 また、データの意味合いとしては、必ず"AA"という1バイトのデータから始まり、それに1バイトから5バイトまでのデータが可変長で付いてきて次の"AA"までが1つの意味となります。 通信パラメータは9600、8ビット、ストップビット1、パリティなしで、その他の制御線は一切使用しないという条件です(要するにRxD、GND線のみの最低限の条件) 受信側のバッファは1024バイトで、MSComm1.RThreshold = 1でOnCommを発生させています。また、送信側のファイルの大きさは1kバイトほどです 正直なところ、このようなことが可能なのかどうかもわからない状況なのですが、現状ではデータを数バイト取りこぼしているだけのようなのでできないことはないのではないか?と考えています。 どなたか、参考文献、ホームページ、プログラム、考え方等を何でもかまいませんん!ぜひ、ご教授願います!!また、現在はVBにて開発中ですが、最悪、言語は問いません。よろしくお願いいたします。

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

  • ベストアンサー
noname#21649
noname#21649
回答No.3

たしか.1秒に1回100msほど.タイマー関連の処理に取られて.結構速度を落とさないと.取りこぼしが発生するようです。 私の関係した対応では. バッファを巨大にする 転送速度を4800に落とす 受信ソフトの実行速度をあげるため.受信中は他の仕事をさせない の3店でした。

kouichi125
質問者

お礼

お礼が遅れて申し訳ございませんでした。 ここ2,3日たてこんでたもので・・・ 具体的な数値を頂き、非常に参考になります。 ありがとうございました。

その他の回答 (2)

  • yanmaa
  • ベストアンサー率45% (207/457)
回答No.2

過去質問を検索して下さい。キーワードは「MSComm」で十分でしょう。 参考までに該当しそうな過去質問を参考URLにつけておきます。

参考URL:
http://www.okweb.ne.jp/kotaeru.php3?q=135370
kouichi125
質問者

お礼

ご回答ありがとうございます。 教えていただいたホームページを拝見させていただきました。 早速ポーリングによる方法を試してみます。

回答No.1

バイナリデータの送受信ですと、Xon/Xoffを使ったフロー制御ができないので、基本的にハードウェアハンドシェークをするしかありませんが、制御線が結線されていないので、これもだめ。ということなら、データ受信中には何の制御もしてはだめで、受信に専念してバッファに貯める。貯めたあとで、処理をおこなうしかないと思います。

kouichi125
質問者

お礼

早速の回答ありがとうございます。 素人考えで非常に申し訳ないのですが、 >データ受信中には何の制御もしてはだめで、受信に専念してバッファに貯める。>貯めたあとで、処理をおこなうしかないと・・・ と、ありますが、たとえばハイパーターミナル等は、どのようにしているのでしょうか? 当然、ハイパーターミナルでは複雑な処理等は行っていないとは思うのですが、現状では、単に受けたデータを表示させるだけでも、データが落ちてしまっています。サンプルソースや、ホームページ等あれば、お教えください。

関連するQ&A

  • Mscomm を使用してバイナリでデータを受信したい

    Mscommを使用して、垂れ流しデーターをバイナリで受信(受信データ長さは変化する)するとき、このデーターをどうやって、配列に格納していけば良いのでしょうか? (垂れ流しデータ ⇒ < STX >nnn-nnn・・・・< ETX >< CHK >) また、配列に格納したデーターを文字に置き換えるにはどうすれば良いでしょうか? まず考え方として以下の流れでよいでしょうか? バイナリデータをバリアント型の変数に入れる。(受信する)      ↓ このデータを1バイトごとにバイト型変数の配列に入れていく。      ↓ 格納した配列の中の制御文字を取り除く。( ST、EX )      ↓ 配列に入っているデータを文字に変換する。      ↓ 変換した文字をつなぐ。 受信するデーターが制御文字を含んでいる為、テキストで受信するとおかしな動作をすることがあるので(150バイト程度のデーターを、バッファから変数に移すときに、0.5~2.5秒もかかってしまうし、文字化けも時々起こす。)バイナリで受信してその後文字に変換したいのですが・・・。 宜しくお願い致します。

  • RS-232C 2つのプログラム 受信 MSComm

    お世話になっております。 今現在VB6.0でMSCommを用いて通信系のプログラムを作成中です。 1台の重量計から、PCのCOM1にデータをと取り込んでいます。 取り込んだデータを解析するために、AというプログラムとBというプログラムを実行し、データがCOM1に受信されたら両方のプログラムにデータを受信させたいです。 しかし、COM1にデータが受信されるとどうしもAというプログラム側でのみ受信されてしまいます。プログラム的に不可能ではないと思うのですが。 そこで、重量計側のポートとCOM1,COM2をパラで繋いで2つに同じデータを受信させたいと考えております。1つのポートに対して、1つのPCを稼動させたいのです。 もし、このようなケーブルを知っておられる方いらっしゃいましたら、宜しくお願い致します。

  • RS-232Cで接続したPC間のファイル転送

    環境 [XP VB6.0] お世話になります。 RS-232Cのクロスケーブルで2台のPCを接続し、一方のPCにあるファイルをもう一方のPCに送信し、受信したファイルを保存するというプログラムを作成しないといけません。 現状、フォーム上でコモンダイアログによりファイルを選択し、選択したファイルが、フルパスでテキストボックスに表示されます。 送信ボタンをクリックするとファイルの送信処理を開始し、受信側は受け取ったファイルを保存するという流れを作りたいのです。 しばらく調べたのですが、なかなかクリティカルする回答を見つける事が出来なかったので質問させていただきます。 もうこのような転送手段は使わないと思いますが・・・。 MSCommコントロールを使用し、文字の送受信程度であればできたのですが、MSCommではファイル転送はできないのでしょうか? 送信側、受信側のプログラムをご教授いただければと思います。 つたない文章で申し訳ありません。 よろしくお願いします。

  • rs232cでの受信データ(mscomm)の受信方法VB6

    VB6で、シリアル通信プログラムを作っています。 機器からレスポンスが、02 00 44 03 61 62 63 03 72 0Dと9バイトくるのですが、 8バイト受信した後に、また、最後の0Dを1バイト目として受信しているので困っています。 on commイベントで以下のようにして受信データをテキストボックスに表示しているのですが、 Select Case MSComm1.CommEvent   Case comEvReceive       Dim Buffer() As Byte       Buffer() = MSComm1.Input       For t = 0 To 6 + Buffer(3)  ,BUffer(3)はデータ長です。       Text1.Text = Text1.Text & Hex$(Buffer(t)) & Chr(&H3A)       Next t 8バイト表示した後、1バイト受信が起こるので、Buffer(3)が範囲外となりエラーが起こります。 inputLenは0にしています。 この問題は解決するにはどうしたらよいでしょうか? 0Dは終了コードです。0Dを受信するまで、きちんと1バイトづづ格納していくなどというようにできたらよいのですが、、、 他にも簡単な方法があったらよいのですが、、、 よろしくお願いいたします。

  • 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バイト)なのか判りません。 方法はありますでしょうか。

  • 高速シリアル通信での大容量のデータ転送について(mscomm)

    現在高速シリアル通信のプログラムを作成しています。なかなか検索で いろいろと探しているのですがデータ容量が増えるとどうしてもサンプル プログラムで同じ結果になってしまいます。 どういう現象かといいますと10000バイトぐらいのデータを転送するとどう してもデータ上のかけ落ちが発生します。 ボーレート:38400 or 19200bps データビット:8Bit パリティ:なし ストップビット:1Bit フロー制御:XonXoffRTSCTSあり データはバイナリィ転送です。 ==>送信側のプログラムでは以下通りです。   'バイナリデータファイルを読み込み For i& = LBound(bytBuf) To UBound(bytBuf) bytedata(LineCnt) = bytBuf(i&) If (LineCnt < 255) Then '255バイトずつ分割して送信 bytedata(LineCnt) = bytBuf(i&) Else 'タイマー処理(wait制御) MSComm1.Output = bytedata LineCnt = 0 bytedata(LineCnt) = bytBuf(i&) End If LineCnt = LineCnt + 1 Next i& 'WAIT掛けたり分割してデータを転送したり一括でデータを転送したり 行っています。 ==>受信側では以下の通りとなっております。 Select Case MSComm1.CommEvent    Case comEvReceive '受信データの取得 Buffer = MSComm1.Input 'あとはバイトデータを結合させて                    'おります。 データの送信や受信について教えていただきたいのですが特に受信側で 私が思うのでは送信データが早すぎて受信側が追いついていない状態 と思うのですが・・・ なにかいい方法や参考になるホームページ等がありましたら伝授お願いします。

  • VB6.0でのバイナリデータの扱いについて

    現在ハンディターミナル(HT)とPCとの通信を行うプログラム(VB6.0)を作成しています。 このプログラムは元々VB2.0で作成されたものをベースとしてVB6.0で再作成しているものです。 プログラムの中でHTとPCとの通信エラーを防ぐため、データ行のBCCを計算しHTに送信している 部分があります。VB6.0ソースを下に表示します。 (実際は、計算したBCCをデータ(下のCheckString変数)の最終行にくっつけてHTに送信していますが、ここではBCCのみ送信しています) -------------------------------------------------○VB6.0 /* 最初にBCCを計算して返し、HT側へ送信している */ /* BCCはstring */ Dim i As Integer, aa As Integer,BCC as String aa = 0 For i = 1 To Len(CheckString) aa = aa Xor Asc(Mid(CheckString, i, 1)) Next BCC = Chr$(aa) frmMain.MSComm1.InBufferCount = 0 frmMain.MSComm1.Output = BCC ------------------------------------------------ VB2.0ではAscB,LenB,MidBのところをVB6.0ではAscB,LenB,MidBをAsc,Len,Midへ変更しています。通常はこれで問題ありませんでしたが、BCCの計算の結果aa = 226となった場合にBCCに文字化けした"r"のような文字がはいっていました。プログラムの中でBCC変数をテキストへ吐き出し、バイナリエディタで確認しましたが"E2"となるところに"00"と空白となっており、これが原因でHTとPC間での通信が完了しません。 (テキスト送信時にStringのため文字化けが原因?) 前回の質問でSTRING型を使用せずにバイナリ型配列で処理する事や、いままで暗黙のうちにUnicode⇔SJIS変換を行ってくれていた部分をStrconvを使用し自前で処理しなければいけないというご指摘を受けたのですが、上のプログラムではどのように修正が必要なのでしょうか?どなたかご教授の程宜しくお願い致します。

  • シリアル通信プログラミングでのバイナリデータ送信

    UNIX系環境(IRIX)でのシリアル通信プログラムを作成していて、 バイナリデータの送信方法がわからず困っています。 write関数を使い、テキストデータの送信は出来ます。 write(fd,"テキスト",byte)のように。 ただ、今回はバイナリデータ送信を考えており、 例えば1byteのデータ00000001(01H)を送りたいと思っています。 このデータを送る場合、write関数で実現出来るのでしょうか? write(fd,0x01,1)←イメージです。 色々ネットで調べても出てきません。 開発がWindows環境ではないので、API関数が使えない状況で困っています(MsComm等が使えない)。また、fwrite関数は使用してはいけないみたいです。教えてください。宜しくお願いします。

  • VB RS-232C 通信プログラム

    何度もお世話になっております。(VB6.0 MSCommを使用した通信プログラムを作成中です。)私は新卒で食品会社に入社したのですが,プログラムの分かる上司が身近では誰1人といない状況で困っています。 今作成しているのは,重量計に荷物が乗った段階で作業者がデータ転送ボタン(重量計についている)を押すと,重量計のデータ(500kgというデータ)をシリアルでCOM1に取り込み,フォームにエクセルのセルを作成し(OLEを用いて)保存できるようにしたいと考えています。 (重量計から送られてくるデータのフォーマット) 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 S T , N T , + 0 0 1 2 . 3 4 k g CR LF ST ; ヘッダ1 NT ; ヘッダ2  CRLF ; ターミネータ                   の18バイトのデータです。 ここで質問なのですが (1) 以下のプログラムで重量はバイト配列に受信できていますでしょうか?(実際に重量計とPCを接続できれば良いのですが工場の稼動状況が関わっておりすぐにはできません。) (2) 18バイトのデータを受信するからと言って RThreshold = 18 として良いのでしょうか? 普通,データは1バイトずつ送られてくると思うので RThreshold = 1としてイベントを発生させる必要があるのかとも思うんですが。 'MSComm1,2(COM1,2)コントロールの初期設定 Private Sub Form_Load() MSComm1.CommPort = 1 '通信ポートを設定 MSComm1.Settings = "9600,n,8,1" '通信条件の設定 MSComm1.RThreshold = 18 '固定長のデータ End Sub Private Sub Port1_Click() 'Port1_Clickのクリックイベントプロシージャ If MSComm1.PortOpen = False Then 'シリアルポートのオープン MSComm1.PortOpen = True End If LPort1.Text = "" 'テキストボックスのクリア受信 End Sub Private Sub MSComm1_OnComm() '受信のOnCommイベント Dim Buffer1(0 To 17) As Byte '受信バッファの変数宣言(18バイト) Select Case MSComm1.CommEvent 'CommEventプロパティに対する処理 Case comEvReceive '受信データ有り    Buffer1 = MSComm1.Input '受信データをバッファに格納 'これより下は受信した18バイトから必要なデータ8バイト目から4バイト分切り出し,dという配列(4バイト)に格納できないかと考えました。 Dim i As Integer Dim d(0 To 3) As Byte d = MidB(Buffer1, 8, 4) LPort1.Text = d 'LPort1.Text = Buffer1 '受信データをテキストボックスに表示 End Sub

  • MSCommを用いたRS-232-Cデータ転送

    Visual Basic ver.6を用いてRS-232-Cデータ転送のプログラムを書いています。 転送には,MSComm controlを用いています。 コンピューター側から命令コードを測定器側に送信すると(例えば,MSComm1.OutPut = "F,3,300," & Chr(13)のように),測定器側からは次のようなテキストデータの転送が指定された回数だけ起こります: @C/R 数値データC/R 数値データC/R ・・・・ ・・・・ (指定回数繰り返す) そこで,質問ですが,このデータをMSComm1.Inputを介してきちんと取得する方法をお教えください。私がよく理解できいない部分は,「どのような形でbufferにデータが落ちているのか?」という部分と「繰り返し処理をどう記述するのか?」という部分です。多分後者は配列型変数を用いて「指定回数」だけ繰り返すことになると思いますが・・・・。 なお,データ転送の制御フォーマットはデータのみの転送で,STXもETXも使用していません。

専門家に質問してみよう