• 締切済み

高速シリアル通信での大容量のデータ転送について(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 'あとはバイトデータを結合させて                    'おります。 データの送信や受信について教えていただきたいのですが特に受信側で 私が思うのでは送信データが早すぎて受信側が追いついていない状態 と思うのですが・・・ なにかいい方法や参考になるホームページ等がありましたら伝授お願いします。

みんなの回答

  • ykkw_2001
  • ベストアンサー率26% (267/1014)
回答No.3

再度 ykkw_2001 です。 きょうび、プロトコルを組んでみようかなというお考えに 「これでも、わし、昔は女にモテたんじゃ」と自慢話をするジジィのような心境で、再度お送りします。 結局、ブロック(パケット)サイズの決めかたは、経験です。(^^) 「ヲイヲイ、のっけからアんだよ」と思うでしょうが、 影響する因子が多くて、キチッと最適値を出すための苦労より、適当に2~3種類試して、エイッと決めてしまうほうが効率的です。 通信に使用しているものすべての応答・動作速度やバッファ・キャッシュサイズが影響します。 通信頻度、標準的な転送サイズ、伝送線、プロトコル(物理層)、CPU+メモリ+HDD+SIOのチップ etc... しかも、転送サイズ・内容がかわっても、常時最高速度で、最高信頼性を確保するのはとても難しいです。 私がお勧めする実践的な目安は、 SIOのバッファサイズ(USART)の10%以下で、 ただ、デバッグや、ラインモニタの性能を考慮して数百バイトでいいと思います。 # それを早く言えよ。 >データを送信したときに受信側から・・送信データがOKでしたよといった返答 >が帰ってくるのを待つということですね そのとーりっ (アタック25児玉清風) さらに、高速化のためには、ブロック数通知後、受信側では、データ要求をガンガン出す。 送信側から要求されたブロックをガンガン送る。 という荒技手順もありえます。(全2重で) # 割り込み(マルチスレッド)使いますので、VBではムリか・・ >高速化の手法ってどんな方法なのでしょうか!  上記以外には、データ圧縮もあります。 たとえば、 >10000バイトぐらい を >38400 or 19200bps のシリアルで、メモリ上のデータを転送するなら、1秒位かけて、送受信のCPUで圧縮・伸長してもシリアルを通るサイズがそれ以上に減れば高速化できます。 # こんなのを確認しつつ考えるのが、すんごく楽しいわけで・・・・ # 状態遷移図やら、マトリクスになると快感アルファ波でまくります。・・・(変?) # 最近、プロトコル組んでないので、思い出してムラムラしてきました。・・・(やっぱ変・・態・・) # ファイル転送のフリーウェアでもアップしようかな・・・なんて。 で、思い出しましたが、ベクタあたりにZモデムとかXモデムのライブラリ(DLL)があれば、 それを使う手もありますね。 # 先に言え

toshi0304
質問者

お礼

いろいろとご指導ありがとうございます。 >結局、ブロック(パケット)サイズの決めかたは、経験です。(^^) 私もWAIT掛けたりサイズを変更したりいろいろと試してみました。 タイミングによってデータの取りこぼしが減ったりいろいと変わり ましたので・・・いろんなパターンで試しています。 一度プログラムを白紙に戻し、現在チャックサムを加えたパケットデータ での通信に切り替えて作り変えております。 こういうときは・・・位置から作る方がいいですねぇ~(頭がすっきりして) >ベクタあたりにZモデムとかXモデムのライブラリ(DLL) 一度探してみます。 toshi0304でした。

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.2

>フロー制御:XonXoffRTSCTSあり データはバイナリィ転送です。 確認ですが、フロー制御はハードウェア(RTS/CTS)ありで、 ソフトフロー制御(Xon/Xoff)は使っていないですよね。 同時に使うと言う設定は通常無いと思いますし, バイナリィではXon/Xoffは使えません。 あと、接続に使っているケーブルの結線は把握していますか。 クロスケーブルでの接続だと物によるとハードフロー制御が利きませんので, データの取りこぼしがでます。 また、送信,受信に使っているマシンのOSやCPU、メモリ等はどの程度でしょうか。 非力な環境だと処理が間に合わない可能性もありえるかと思います。VBAお使いのようですし。 そういえば、昔はシリアル制御CHIPの問題で、 MS-DOS標準のドライバだと取りこぼして使い物にならないって話があったりしました(^^;

toshi0304
質問者

補足

VB側のプログラム側で設定すれば使えると思っていました。 すいません私の勉強不足で(とほほほぉ~) >あと、接続に使っているケーブルの結線は把握していますか。 >クロスケーブルでの接続だと物によるとハードフロー制御が利きませんので, >データの取りこぼしがでます。 現在はクロスケーブルでやっています。知りませんでした。 これも初めて勉強になりました。 開発環境:1、VB6 SP3 WIN2000 SP2 P(3) 1000MHz 256MB      2、VB6 SP3 WINME P(3) 800MHz 192MB です。 VBのMSCOMMを使っていたんですが現在はBOCのACTIVECOMで 作り直しています。 シリアルでのファイル転送プログラムを作成しています。 あつかましいのですがソースオープンしているサイトなど あればまた教えていただけないでしょうか

  • ykkw_2001
  • ベストアンサー率26% (267/1014)
回答No.1

定石なのですが・・・・ データチェック文字(チェックディジット、BCC、CRCetc..)を入れて見てはいかがでしょう。 たとえば・・・ 分割単位(ブロック)ごとに全文字のビット毎にXOR演算した結果を最後の文字として、データにくっつけて送るのです。受信側も同じ演算をして、最後の文字と比較、違っていれば、NGとして再度送信するように要求します。 大まかに流れを書くと・・ 送信側は、実際のデータを送る前に、ブロック数をカウントし、受信側に送ります。 受信側は、受け取ったら、実際のデータを受付可能という意味で「第1ブロックの要求」を送信側に送ります。送信側は、第1ブロックをデータチェック文字とともに送ります。受信側は、第一ブロックが間違っていれば、再度要求、あっていれば、第2ブロック要求を送信側に送ります。これを最終ブロックまで繰り返します。 (いわゆるアプリケーション層のプロトコルという事になります) データ文字数の情報も付けて確認すると、データの誤り率は、激減するはずです。速度は少々低下しますし、高速化の手法もいろいろあります。 TCP/IP全盛になる以前は、これ(プロトコルとデータ誤りの低減)を考えるのが仕事だった時期もあり、仕事上では、一番楽しい時間でした。(^^)/

toshi0304
質問者

お礼

ykkw2001さん ご回答ありがとうございます。 ここ1週間毎日悩んでいて。ちょっと兆しが見えてきました。 そこでちょっと質問なのですが、 送信側で実際のデータを送る前にブロック数をカウントして受信とありますが 分割単位(ブロック)は最適なブロック単位はどれぐらいがいいのでしょうか データを送信したときに受信側から・・送信データがOKでしたよといった返答 が帰ってくるのを待つということですね 高速化の手法ってどんな方法なのでしょうか! それと記述する欄を間違えてすいません。

toshi0304
質問者

補足

ykkw2001さん ご回答ありがとうございます。 ここ1週間毎日悩んでいて。ちょっと兆しが見えてきました。 そこでちょっと質問なのですが、 送信側で実際のデータを送る前にブロック数をカウントして受信とありますが 分割単位(ブロック)は最適なブロック単位はどれぐらいがいいのでしょうか データを送信したときに受信側から・・送信データがOKでしたよといった返答 が帰ってくるのを待つということですね 高速化の手法ってどんな方法なのでしょうか!

関連するQ&A

  • 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も使用していません。

  • VBのMSCommコントロールを使ってシリアル通信をしています。

    VBのMSCommコントロールを使ってシリアル通信をしています。 データ受信時、90byteを超えたあたりで"??"(ASCIIコードで0x3Fが2回)が 挿入されたように受信されてしまいます。 前後のデータ関係をみると、2byteがデータ化けを起こしているわけでは なく、"??"が間に挿入されたような形です。 "??"が挿入される位置も受信の度に違います。 もしこのような現象の理由がわかる方がいらっしゃいましたら 回避策をお教えください。 <詳細設定> 38.4kbps、データ長:7、パリティ:Even、Stop bit :1 の設定。 http://www.compass-lab.com/STK_CAN/USB_Serial/USB_COMi.htm にあるUSB-comiでシリアルポートを追加してRS422変換しています。 データ長129byteのデータが250ms周期で送られてくるのを 読み取ろうとしています。

  • 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バイトづづ格納していくなどというようにできたらよいのですが、、、 他にも簡単な方法があったらよいのですが、、、 よろしくお願いいたします。

  • シリアル通信のデータ受信について質問です

    PCからマイコン(H8/3664)に文字を送信したいのですが、受信のしかたがわかりません。PC側のプログラムはC#を使っていて、8bit送信しています。マイコン側はC言語で、8bitで送られた文字を、C言語でどういう風に受信したらいいかわかりません。受信する関数があるのでしょうか?ちなみに割り込みは使いません。

  • MSCommのデータ送信

    申し訳ございません。 質問させていただいていた内容が解りにくいので再度、質問させてください。 接続しているデバイスがいないときのデータ送信の処理時間について質問がございます。 Dim Data$  Data$ = "Sample" MSComm1.Output = Data$ 'このステートメントを抜けるのに約10秒かかる。 RS-232C接続をしたデバイスにデータを送信します。 このとき、受信するデバイスが接続されいないときのデータ送信に時間が取られています。 通信デバイスのタイムアウトを設定するSetCommTimeouts関数は使用していません。 MSComm1.Outputのタイムアウトはどこで設定されていますか? 設定されているタイムアウト値を確認する方法はございますか?

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

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

  • VB6.0のGPSシリアル通信について

    はじめまして。 VB6.0で、GPSシリアル通信を行っています。 シリアル設定は、MSComm1.Settings = "4800,n,8,1" にしています。 1秒毎にGPSデータは受信でき、すべて受信できています。 ただし、このGPSデータは、1秒間に下記のように6行分受信されます。 $GPRMC,131850,A,3603.5404,N,14008.5746, $GPGGA,131850,3603.5404,N,14008.5746, $GPGSA,A,3,27,09,02,05,21,29,10,15,,,, $GPGSV,3,1,11,27,27,193,33,09,13,199, $GPGSV,3,2,11,21,18,317,23,29,14,259,22, $GPGSV,3,3,11,07,01,033,00,18,00,295,00,28 そこで、上記6行分のデータのうち、初めの2行分だけを取り出したいと思っていますが、どうもうまくいきません。 どのようにすれば、初めの2行分だけを取り出すことができるでしょうか? 下記がソースです。 Private Sub MSComm1_OnComm() Dim Buffer1 As Variant Select Case MSComm1.CommEvent Case comEvReceive Buffer1 = MSComm2.Input If (InStr(Buffer1, "GPRMC")) Then Debug.Print Buffer1; Else (InStr(Buffer1, "GPGGA")) Then Debug.Print Buffer1; End If End Sub どなたか教えてください。 よろしくお願いします。

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

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

  • シリアル通信(タブレット、シーケンサー)

    現在、WindowsXP + VB6 + MSComm <ー> FXn2-16MR(RS232Cユニット)を シリアル通信で制御しています。これをWindows8.1(タブレット) + VB2013で全面的に 書き換えを行っています。テスト用のパソコンとは何の問題間無く通信は通りますが、 対シーケンサーだと送信はしているようだが、受信が全くできない状態です。 制御パラメータは、SerialPort1.Handshake=None, DtrEnable=True, RtsEnable=True 送信時のプロトコルは、<ENQ> + データ(ASCコード) 受信時のプロトコルは、<STX> + データ(ASCコード)+ <ETX> VB6は、この設定で動作しています。 VB2013では、制御パラメータは同じし送受信では普通に SerialPort1.Write、SerialPort1.ReadLineを使っています。 宜しくお願いします。

  • シリアル通信のイベント受信について

    現在VB6.0を使用してシリアル通信のプログラムを MsCommを使用せず、CreateFileを使用して行っておりますが、 データの受信を受信したタイミングでテキストボックスに表示したいのですが どの様にすると受信したタイミングでデータを取得できるのかわからず困っております。

専門家に質問してみよう