MSCommコントロールのOnCommイベントでデータを受信しようとしていますが、
受信バイト数が可変長な為、どうやって受信して良いか分かりません。何か
良い方法はないでしょうか?
ちなみに受信バイト数が固定値の時は以下のような命令で受信しています。
この場合は受信バイト数が3バイトの時です。
Do
DoEvents
Loop Until MSComm1.InBufferCount >= 3
ここに書いてある、イベントトリブン方式
で、受信すればいいんじゃないでしょうか?
http://support.microsoft.com/default.aspx?scid=kb;ja;411403&Product=vbJPN
可変長とはいっても最小単位が1バイトなので、
1バイトずつ受信イベントを発生させてやればいいと思います。
そして受信した1バイトデータを結合すれば、
可変長データも何ら問題ありません。
ちなみに、ポーリングでも1バイトずつ受信→結合すれば問題ありませんよ。
回答ありがとうございます。
以下の命令で1バイトずつBufferに受信し、テキストボックスに表示
させて行く様にプログラムしているつもりなんですが、これでは1バイト
以上のバイトを受信してしまいます。何か足りないんでしょうか…
MSComm1.RThreshold = 1
MSComm1.SThreshold = 1
MSComm1.InputLen = 1
MSComm1.InputMode = 1
Buffer = MSComm1.Input
Text1.Text = Text1.Text & Buffer
そんなハズはないですよ。
その設定で1バイトずつ受信できるハズです。
考えられる事は、
1)InputLen等の設定をする場所が間違っている(設定されてない)
2)Buffer変数が文字列型(最小単位=2バイト)になっているために勘違いしている。
以上を確認してみてください。
MSComm1.RThreshold = 1 とすると、
1バイト受信以上受信でOnCommイベントが発生します。
つまり、MSComm1.Inputには1バイト以上のデータが入力されます。
これを考慮して作成しないといけないですね。
受信データが可変長であると書かれていますが、
終了コードはないのでしょうか?
あるならば、OnCommイベントと同時に(又はある時間後に)、
Buffer = MSComm1.Inputを行い、終了コードをチェックする。
そこで、終了コードがあったら受信を終了する。
なければ、再度受信をする。
といった感じで良いと思います。(エラー処理は別途必要)
終了コードがない場合は、考えた事がありません。
何らかの終了を判断できるもの(終了コードやデータ長)がなければ、
シリアル通信はうまくできない様な感じもしますが。。。
If MSComm1.InBufferCount > 0 Then
Buffer = MSComm1.Input
Else
Buffer = ""
End If
Text1.Text = Text1.Text & Buffer
ですかね.
受信バッファのデータを1バイトずつテキストボックスに表示させることは出来
ました。しかし、新たな問題が…途中まで1バイトずつデータを読み込んで表示
するんですが、受信バッファ内に1バイト以上データが残っているにもかかわら
ずOnCommイベントを実行してくれません。自分で回帰的にOnCommイベントを読
み込むと全てのデータを表示出来たんですが…
MSComm1.InputLen = 0(デフォルト)として、
受信バッファの内容全体を読み取るべきです。
そうすると、受信バッファに引き続きデータが入力された場合、
再度OnCommイベントが発生します。
1バイトずつ処理するという考えを、
一度リセットした方が良いと思います。
あ,ホンとだ
MSComm1.InputLen = 1
になってる...そりゃいかんね.
MSComm1.InputLen = 0にしてバッファ全体を読み取ろうとしたんですが
やはり途中までしかデータを受信しませんでした。OnComm内でSleep関数
で300ミリ秒ほど止めてみたら全てのデータを受信することが出来ましたが…
例えば、データが"ABCDEFGH"であった場合に、
始めのOnCommイベントで"ABCD"をInputしたとします。
その時点では、相手機器はまだデータを送信している途中です。
そのため、再度OnCommイベントが発生します。
ここで、"EFGH"をInputできたとすれば、
前回の"ABCD"と、今回の"EFGH"を連結する事により、
"ABCDEFGH"というデータが出来上がります。
データ通信とはそんなものです。
そういう仕組みになっていたんですね…その仕組みを考慮してもう1度
プログラムを考えてみます。何度も回答していただきありがとうござい
ました。またどうしても分からなかったらその時は宜しくお願い致します。
私も最近この問題と酷似した現象に直面し、解決できずに困っております。
解決済みの問題に対して、このように再定義して申し訳ありませんが、
私としましては何としてでも解決したいので、皆様何卒ご助力の程よろしくお願いいたします。
また、Toney様、その後この件に関して解決策を見出されたのであれば、
是非、ご教授いただきたくお願い申し上げます。
以下私の現状を記述させていただきます。
環境は、WinNT4.0(SP6),VB6(SP6)です。
ソフト作成の主旨としましては、Mscommを使用し、RS-232Cにより、
とあるデバイス(カードリーダ系)との通信を行うというものです。
◆Mscommの設定
伝送速度 :9600
データ長 :8bit+1parity
使用コード :ASCII 8 bit code
Handshaking :comNone
InBufferSize :1024
RThreshold :1
InputLen :1
(InputLen :0 ダメでした。2バイトしか受信できません)
この設定でカードリーダからのデータ(可変長1バイト〜数百バイト)を
受信し、イミディエントウィンドに表示させているのですが、10バイト
以上のデータを受信した時に最初の4バイトを表示して終了してしまいます。
(10バイトより短いデータは1バイトデータのみです)
Debug.Printで確認すると、InBufferCountが0でないのにバッファからの読出しをやめてしまっているのがわかるのですが、なぜそうなるのかがわかりません。
'受信データ処理
Private Sub MScomm1_OnComm()
Dim bytDat() As Byte
Dim RDat As Variant
Dim St As String
bytDat() = MSComm1.Input
St = ""
For Each RDat In bytDat
St = Right$("00" & Hex$(RDat), 2)
Next
Debug.Print MSComm1.InBufferCount; " "; St
End Sub
イミディエントウィンドに表示される内容
7 FF
6 11
7 22
6 33
↑
InBufferCountが6であるのにバッファから読み出してくれません。
OnCommイベントは1バイト受信するたびに発生すると認識しているのですが、
これはイベントが4回しか発生していないということなのでしょうか?
補足としまして、上記状態で以下のコードによる手動での読込みを行うと、バッファ内のデータを全て読み出してくれますが、手動での読込みでは実用
に耐えられません。
'バッファ読込
Private Sub Cmd_BufferRead_Click()
Dim bytDat() As Byte
Dim RDat As Variant
Dim St As String
If MSComm1.InBufferCount <> 0 Then
Do Until MSComm1.InBufferCount = 0
bytDat() = MSComm1.Input
St = ""
For Each RDat In bytDat
St = Right$("00" & Hex$(RDat), 2)
Next
Debug.Print MSComm1.InBufferCount; " "; St
Loop
End If
End Sub
データ受信と共に全てのデータをバッファから読出し、
表示させるためにはどのような作りにすればよろしいの
でしょうか?
どうかご指導の程、よろしくお願いいたします。
一度解決がたっているので、別に立てたほうがいいような気がします。
編集 削除