• ベストアンサー

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

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

  • ベストアンサー
  • osaosa42
  • ベストアンサー率60% (20/33)
回答No.6

こんばんは。 これで、試してみてください。 '<<送信側>> Private Sub Command1_Click() MSComm1.InputLen = 0 MSComm1.PortOpen = True MSComm1.Output = Text1.Text + Chr(13) MSComm1.PortOpen = False End Sub '<<受信側>> '起動時にポートを開いておきます。 'Timer1を貼り付けてIntervalを100程度に。 Private Sub Timer1_Timer() Dim strBuf As String strBuf = MSComm1.Input If Len(strBuf) <> 0 Then List1.AddItem strBuf End If End Sub もし、受信データ長が同じ長さなら、OnCommイベントで データ取得した方がいいのですが・・・

cholerae
質問者

お礼

大分,返事が遅れまして申し訳ありませんでした。 また,御助言ありがとうございました。 御助言の通り,Timer controlを使ってTimer Eventを発生させ,Timer1.Interval = 適当な値(実験では,50 msecくらいが適当)で機器からデータを取得するとうまく行きました。 参考までに記すと,氏の最後の助言をヒントにして,さらに次のようにすると完全にデータを取得できました。1データ(@ & VbCr)を取得したところでTimer1.Enabled = Falseにして,Handshakingをするようにコードすると,以後は一定長のデータが送信されてくるので,OnComm Eventを発生させてデータを取得することができました。 大分苦労しましたが,氏の助言,たいへん参考になりました。ありがとうございました。

その他の回答 (5)

  • ponnta
  • ベストアンサー率17% (31/179)
回答No.5

ANo.#3の訂正です。 もしかするとInputLen=0で一行(つまりCRまで読み込むのかもしれない)と書きましたが、 InputLenで指定したサイズまで一度に取り出しせました。 InBufferSizeが十分なサイズで、コマンドを送ってから Inputまで十分な時間を確保しているのであれば測定器側から データが来ていない可能性があります。 または、コマンド送信からInputまでの時間が短く、@C/R を受信したタイミングでInBufferからデータを読んでしまっているとか。

cholerae
質問者

お礼

再度の御助言ありがとうございます。 実を申しますと,現段階での「結論」はponntaさんご指摘のことを考えています。とはいうものの使っているノートがたびたびハングしているうちに「ハードディスクがクラッシュ」したようで,修理に1週間程度かかるはめに陥りました(心境は(;;)です)。 使っている機器の測定値を「瞬時」呼び出すコマンドがあって,コマンドボタンに連動させて呼び出しプログラムを書くと,最初のクリックでは最初の2文字しかバッファーに入りませんが,次のクリック以降はちゃんとデータがすべてバッファーに収まり,ちゃんと数値を呼び出すことができます(これ自身不思議な現象ですが)。 データは, @ C/R 5文字の数値データ C/R です。 従って,inputまで若干時間を開けるようなコードを記載してタイミングを計るか,ボーレイトを変えてテストするようなことを現在考えています。 「結果」は若干間が開きますが,後日報告します。 また,何か御助言等,思い付きましたらお知らせください。

  • i-touch
  • ベストアンサー率40% (170/415)
回答No.4

私が作った受信プログラムでですが、InputModeはバイナリにしていました。 Sub MSComm1_OnCommで、MSComm1.CommEvent が comEvReceive のときに MSComm1.Input していますが、バッファに入っているものを受け取ると、 CR で切れているわけではないので、Inputを繰り返して、前の文字列と 連結して、通信が終わったところで、文字列処理でCRのところまでを1行 として分割していました。なお、InBufferSizeは2048にしています。 もっといい別の方法があるのかもしれませんが。 N88からの移植は、何かと相違点があって大変ですね。 では

  • ponnta
  • ベストアンサー率17% (31/179)
回答No.3

INPUTを繰り返しても次のデータが読めませんか? 私見ではありますが。 bufferはリングバッファになっていてInBufferSizeでしていしたバイト数だけ、受信したデータが格納できる。 inputで読み込まなければInBufferSize以上受信したものは取りこぼしが起きる。(後からきたのが格納できずに捨てられる) inputでInBufferのデータが読み込まれる。読み込まれるのはInputLenで指定したバイト数(バイナリ時)、 このとき読み込んだバイト分、バッファの空きが増える。 (テキストは使ったことがなので良くわからないが、もしかするとInputLen=0で一行(つまりCRまで読み込むのかもしれない)) InBuffrtCountを使うとInBufferに格納されているデータのサイズを取得できるのでこれが2以上なら数値データも格納されているはずです。 たとえばInBuffrtCountが0になるまでInputを繰り返してみるとか・・・ CRはコントロールコードなので取得できると思います

cholerae
質問者

補足

御示唆,ありがとうございます。 バッファーの特徴がおぼろげながら理解できるようになりました。 これまでのところ,いろいろ条件を変えて(例えば,MSComm1.InputLen = いろいろな値)トライアンドエラーを繰り返していますが,うまくいきません。共通している事実は,MSComm1.InBufferCount = 4が最高値です。つまり,データの最初の1行しか読みこまないということです。 以前まで,この計器からのデータを取り込むために,N88-Basicでコードしたプログラムを使っていました。従って,一応 @ & chr(13) の後のデータもパソコンには送られているはずと思っています。 多分,「単純なミス」に起因してうまくいっていないような気がするので,現在は,初心に帰って,データが送信されているかどうか?からチェックしているところです。

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

うんざっくりしたプログラムは書いていただいた方がいいのですが 気になるのは.InputLen = 0で0にせずに処理しているのでは? あとバイナリモードでないとCrは取れないと思うのだけど .InputBufferLenの値を考慮してないとか 非常に簡単なプログラムになるとは思うのですが受信のみならば という事で補足願います。

cholerae
質問者

補足

御示唆ありがとうございます。 InputLen に関してはどんな値でも同じ結果でした。つまり,データの最初の1行,@ C/Rしか表示できませんでした。 また,InputBufferLenの値も今度の問題には関係ないようです。

  • prome
  • ベストアンサー率32% (64/196)
回答No.1

測定器の制御をされているのですね。私もそうです。 MSCommコントロールの使い方については、資料や例が少ないので、 大変です。がんばってください。 さて、測定器に命令を与えてからリターンが返ってくるまでの大体の時間は 把握されていますか?大体の時間がわかるなら、命令を発してからその時間 だけ待って(ポーズをかける)、MSComm1.Inputすると読めるでしょう。 この時測定器からのリターン文字列の長さが想定できるなら、 それだけ分のバッファをとっておけば1回で読めます。 リターン文字列の長さがわからないからといって、極端に長めに取ることは メモリを食いすぎるので、適当な長さ分を取って何回かに分けて読むことに なります。何回かに分けて読んだ文字列を&でつなぎ合わせるとよい。 MSCommコントロールは使いにくいといっても、フロー制御さえ間違わなけれ ば取りこぼしはありません。ただ測定器が命令に関係なくデータを垂れ流す 仕様であれば、取りこぼしもやむを得ませんが。

cholerae
質問者

補足

さっそくの御示唆,ありがとうございます。若干,補足します。 TXT1.text = MSComm1.Input の形で読み出せるのは最初の1行だけです。つまり,"@"だけです。質問に書いたのですが,「BUFFER」がどのようなものなのか?が理解できていません。最初のC/Rが来るとBUFFERはデータの取得を止めてしまうようです。従って,BUFFER SIZEを大きくとっても結果は同じです。 今度試してみようと思うことは,promeさんのヒントを基にして,1行読んで,表示し,bufferを空にし,1行読む・・・というような繰り返しが可能かどうか?です。 何かヒントがありましたらお教えください。

関連するQ&A