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も使用していません。
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イベントで
データ取得した方がいいのですが・・・
大分,返事が遅れまして申し訳ありませんでした。
また,御助言ありがとうございました。
御助言の通り,Timer controlを使ってTimer Eventを発生させ,Timer1.Interval = 適当な値(実験では,50 msecくらいが適当)で機器からデータを取得するとうまく行きました。
参考までに記すと,氏の最後の助言をヒントにして,さらに次のようにすると完全にデータを取得できました。1データ(@ & VbCr)を取得したところでTimer1.Enabled = Falseにして,Handshakingをするようにコードすると,以後は一定長のデータが送信されてくるので,OnComm Eventを発生させてデータを取得することができました。
大分苦労しましたが,氏の助言,たいへん参考になりました。ありがとうございました。
No.5
- 回答日時:
ANo.#3の訂正です。
もしかするとInputLen=0で一行(つまりCRまで読み込むのかもしれない)と書きましたが、
InputLenで指定したサイズまで一度に取り出しせました。
InBufferSizeが十分なサイズで、コマンドを送ってから
Inputまで十分な時間を確保しているのであれば測定器側から
データが来ていない可能性があります。
または、コマンド送信からInputまでの時間が短く、@C/R
を受信したタイミングでInBufferからデータを読んでしまっているとか。
再度の御助言ありがとうございます。
実を申しますと,現段階での「結論」はponntaさんご指摘のことを考えています。とはいうものの使っているノートがたびたびハングしているうちに「ハードディスクがクラッシュ」したようで,修理に1週間程度かかるはめに陥りました(心境は(;;)です)。
使っている機器の測定値を「瞬時」呼び出すコマンドがあって,コマンドボタンに連動させて呼び出しプログラムを書くと,最初のクリックでは最初の2文字しかバッファーに入りませんが,次のクリック以降はちゃんとデータがすべてバッファーに収まり,ちゃんと数値を呼び出すことができます(これ自身不思議な現象ですが)。
データは,
@ C/R
5文字の数値データ C/R です。
従って,inputまで若干時間を開けるようなコードを記載してタイミングを計るか,ボーレイトを変えてテストするようなことを現在考えています。
「結果」は若干間が開きますが,後日報告します。
また,何か御助言等,思い付きましたらお知らせください。
No.4
- 回答日時:
私が作った受信プログラムでですが、InputModeはバイナリにしていました。
Sub MSComm1_OnCommで、MSComm1.CommEvent が comEvReceive のときに
MSComm1.Input していますが、バッファに入っているものを受け取ると、
CR で切れているわけではないので、Inputを繰り返して、前の文字列と
連結して、通信が終わったところで、文字列処理でCRのところまでを1行
として分割していました。なお、InBufferSizeは2048にしています。
もっといい別の方法があるのかもしれませんが。
N88からの移植は、何かと相違点があって大変ですね。
では
No.3
- 回答日時:
INPUTを繰り返しても次のデータが読めませんか?
私見ではありますが。
bufferはリングバッファになっていてInBufferSizeでしていしたバイト数だけ、受信したデータが格納できる。
inputで読み込まなければInBufferSize以上受信したものは取りこぼしが起きる。(後からきたのが格納できずに捨てられる)
inputでInBufferのデータが読み込まれる。読み込まれるのはInputLenで指定したバイト数(バイナリ時)、
このとき読み込んだバイト分、バッファの空きが増える。
(テキストは使ったことがなので良くわからないが、もしかするとInputLen=0で一行(つまりCRまで読み込むのかもしれない))
InBuffrtCountを使うとInBufferに格納されているデータのサイズを取得できるのでこれが2以上なら数値データも格納されているはずです。
たとえばInBuffrtCountが0になるまでInputを繰り返してみるとか・・・
CRはコントロールコードなので取得できると思います
この回答への補足
御示唆,ありがとうございます。
バッファーの特徴がおぼろげながら理解できるようになりました。
これまでのところ,いろいろ条件を変えて(例えば,MSComm1.InputLen = いろいろな値)トライアンドエラーを繰り返していますが,うまくいきません。共通している事実は,MSComm1.InBufferCount = 4が最高値です。つまり,データの最初の1行しか読みこまないということです。
以前まで,この計器からのデータを取り込むために,N88-Basicでコードしたプログラムを使っていました。従って,一応 @ & chr(13) の後のデータもパソコンには送られているはずと思っています。
多分,「単純なミス」に起因してうまくいっていないような気がするので,現在は,初心に帰って,データが送信されているかどうか?からチェックしているところです。
No.2
- 回答日時:
うんざっくりしたプログラムは書いていただいた方がいいのですが
気になるのは.InputLen = 0で0にせずに処理しているのでは?
あとバイナリモードでないとCrは取れないと思うのだけど
.InputBufferLenの値を考慮してないとか
非常に簡単なプログラムになるとは思うのですが受信のみならば
という事で補足願います。
この回答への補足
御示唆ありがとうございます。
InputLen に関してはどんな値でも同じ結果でした。つまり,データの最初の1行,@ C/Rしか表示できませんでした。
また,InputBufferLenの値も今度の問題には関係ないようです。
No.1
- 回答日時:
測定器の制御をされているのですね。
私もそうです。MSCommコントロールの使い方については、資料や例が少ないので、
大変です。がんばってください。
さて、測定器に命令を与えてからリターンが返ってくるまでの大体の時間は
把握されていますか?大体の時間がわかるなら、命令を発してからその時間
だけ待って(ポーズをかける)、MSComm1.Inputすると読めるでしょう。
この時測定器からのリターン文字列の長さが想定できるなら、
それだけ分のバッファをとっておけば1回で読めます。
リターン文字列の長さがわからないからといって、極端に長めに取ることは
メモリを食いすぎるので、適当な長さ分を取って何回かに分けて読むことに
なります。何回かに分けて読んだ文字列を&でつなぎ合わせるとよい。
MSCommコントロールは使いにくいといっても、フロー制御さえ間違わなけれ
ば取りこぼしはありません。ただ測定器が命令に関係なくデータを垂れ流す
仕様であれば、取りこぼしもやむを得ませんが。
この回答への補足
さっそくの御示唆,ありがとうございます。若干,補足します。
TXT1.text = MSComm1.Input の形で読み出せるのは最初の1行だけです。つまり,"@"だけです。質問に書いたのですが,「BUFFER」がどのようなものなのか?が理解できていません。最初のC/Rが来るとBUFFERはデータの取得を止めてしまうようです。従って,BUFFER SIZEを大きくとっても結果は同じです。
今度試してみようと思うことは,promeさんのヒントを基にして,1行読んで,表示し,bufferを空にし,1行読む・・・というような繰り返しが可能かどうか?です。
何かヒントがありましたらお教えください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(Microsoft Office) マクロVBAについて 1 2022/09/06 18:12
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Visual Basic(VBA) 【VBA】データを入力後に,同一シート内に履歴として転記するVBAコードを教えていただきたいです。 3 2022/11/16 01:37
- Visual Basic(VBA) 【困っています2】VBA 追加処理の記述を教えてください。 2 2022/08/26 11:42
- Excel(エクセル) Excelで、別シートの表のステータスに伴った動的な自動転記をしたいです。 2 2023/06/14 15:56
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- その他(コンピューター・テクノロジー) 50台の織機から回転数を取得・集計しモニターに表示したい 2 2022/11/05 15:48
- Visual Basic(VBA) VBAで大量データの処理 3 2022/11/15 21:53
- Ruby 初心者プログラミング 3 2022/10/12 11:31
- システム CSVファイルのマッピング処理の省力化 1 2022/11/24 00:01
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
教えて下さい
-
配列でデータが入っている要素...
-
VBA 空白セルを削除ではない方...
-
【エクセル】測定時間がバラバ...
-
メモ帳(テキストデータ)をExc...
-
多量のSUMIF式を軽くしたい
-
ActiveReportについて
-
データ取得時のエラーに関して
-
この行は既に別のテーブルに属...
-
VBAで「"」[']をエスケープする...
-
VisualBasicでデータ検索プログ...
-
CString型の文字列連結について
-
ACCESSからEXCELに出力する際、...
-
VB6のListの使い方
-
EXCELVBAでSQLserverからデータ...
-
エクセル マクロの組み方について
-
ポケコン PC-E650 の...
-
COBOL数値転記をCOPY句内での仕様
-
LoadPictureしたイメージデータ...
-
Web画面を遷移してもデータを保...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
教えて下さい
-
配列でデータが入っている要素...
-
【エクセル】測定時間がバラバ...
-
メモ帳(テキストデータ)をExc...
-
VBA 空白セルを削除ではない方...
-
多量のSUMIF式を軽くしたい
-
この行は既に別のテーブルに属...
-
S9タイプからXタイプにデータ...
-
Excelのマクロでワードのテキス...
-
エクセルで2つの時系列のデー...
-
Accessで該当データにフラグを...
-
ユーザーフォームのテキストボ...
-
シーケンサにパソコンからアク...
-
EXCELVBAでSQLserverからデータ...
-
[C言語] コメント文字列を無視...
-
VBAを使ってOutlookメール本文...
-
プログラミング python pandas ...
-
VBA 毎日取得するデータを順番...
-
<VB>String→Object
-
カンマからスラッシュに
おすすめ情報