OnCommイベントで受信方法

解決


Toney  2004-03-19 20:49:01  No: 82638  IP: [192.*.*.*]

MSCommコントロールのOnCommイベントでデータを受信しようとしていますが、
受信バイト数が可変長な為、どうやって受信して良いか分かりません。何か
良い方法はないでしょうか?
ちなみに受信バイト数が固定値の時は以下のような命令で受信しています。
この場合は受信バイト数が3バイトの時です。

Do
   DoEvents
Loop Until MSComm1.InBufferCount >= 3

編集 削除
やくも  2004-03-19 23:41:58  No: 82639  IP: [192.*.*.*]

ここに書いてある、イベントトリブン方式
で、受信すればいいんじゃないでしょうか?
http://support.microsoft.com/default.aspx?scid=kb;ja;411403&Product=vbJPN

編集 削除
ぴろあき  2004-03-22 09:56:10  No: 82640  IP: [192.*.*.*]

可変長とはいっても最小単位が1バイトなので、
1バイトずつ受信イベントを発生させてやればいいと思います。

そして受信した1バイトデータを結合すれば、
可変長データも何ら問題ありません。
ちなみに、ポーリングでも1バイトずつ受信→結合すれば問題ありませんよ。

編集 削除
Toney  2004-03-23 11:29:54  No: 82641  IP: [192.*.*.*]

回答ありがとうございます。
以下の命令で1バイトずつBufferに受信し、テキストボックスに表示
させて行く様にプログラムしているつもりなんですが、これでは1バイト
以上のバイトを受信してしまいます。何か足りないんでしょうか…

MSComm1.RThreshold = 1
MSComm1.SThreshold = 1
MSComm1.InputLen = 1

MSComm1.InputMode = 1
Buffer = MSComm1.Input

Text1.Text = Text1.Text & Buffer

編集 削除
ぴろあき  2004-03-23 16:02:16  No: 82642  IP: [192.*.*.*]

そんなハズはないですよ。
その設定で1バイトずつ受信できるハズです。

考えられる事は、
1)InputLen等の設定をする場所が間違っている(設定されてない)
2)Buffer変数が文字列型(最小単位=2バイト)になっているために勘違いしている。
以上を確認してみてください。

編集 削除
しゅう  2004-03-23 23:56:14  No: 82643  IP: [192.*.*.*]

MSComm1.RThreshold = 1  とすると、
1バイト受信以上受信でOnCommイベントが発生します。
つまり、MSComm1.Inputには1バイト以上のデータが入力されます。
これを考慮して作成しないといけないですね。

受信データが可変長であると書かれていますが、
終了コードはないのでしょうか?
あるならば、OnCommイベントと同時に(又はある時間後に)、
Buffer = MSComm1.Inputを行い、終了コードをチェックする。
そこで、終了コードがあったら受信を終了する。
なければ、再度受信をする。

といった感じで良いと思います。(エラー処理は別途必要)

終了コードがない場合は、考えた事がありません。
何らかの終了を判断できるもの(終了コードやデータ長)がなければ、
シリアル通信はうまくできない様な感じもしますが。。。

編集 削除
punto  2004-03-24 01:04:22  No: 82644  IP: [192.*.*.*]

If MSComm1.InBufferCount > 0 Then
    Buffer = MSComm1.Input
Else
    Buffer = ""
End If
Text1.Text = Text1.Text & Buffer

ですかね.

編集 削除
Toney  2004-03-24 10:06:21  No: 82645  IP: [192.*.*.*]

受信バッファのデータを1バイトずつテキストボックスに表示させることは出来
ました。しかし、新たな問題が…途中まで1バイトずつデータを読み込んで表示
するんですが、受信バッファ内に1バイト以上データが残っているにもかかわら
ずOnCommイベントを実行してくれません。自分で回帰的にOnCommイベントを読
み込むと全てのデータを表示出来たんですが…

編集 削除
しゅう  2004-03-24 12:18:46  No: 82646  IP: [192.*.*.*]

MSComm1.InputLen = 0(デフォルト)として、
受信バッファの内容全体を読み取るべきです。

そうすると、受信バッファに引き続きデータが入力された場合、
再度OnCommイベントが発生します。

1バイトずつ処理するという考えを、
一度リセットした方が良いと思います。

編集 削除
punto  2004-03-24 15:23:43  No: 82647  IP: [192.*.*.*]

あ,ホンとだ
    MSComm1.InputLen = 1
になってる...そりゃいかんね.

編集 削除
Toney  2004-03-24 16:49:07  No: 82648  IP: [192.*.*.*]

MSComm1.InputLen = 0にしてバッファ全体を読み取ろうとしたんですが
やはり途中までしかデータを受信しませんでした。OnComm内でSleep関数
で300ミリ秒ほど止めてみたら全てのデータを受信することが出来ましたが…

編集 削除
しゅう  2004-03-24 17:10:27  No: 82649  IP: [192.*.*.*]

例えば、データが"ABCDEFGH"であった場合に、
始めのOnCommイベントで"ABCD"をInputしたとします。
その時点では、相手機器はまだデータを送信している途中です。
そのため、再度OnCommイベントが発生します。
ここで、"EFGH"をInputできたとすれば、
前回の"ABCD"と、今回の"EFGH"を連結する事により、
"ABCDEFGH"というデータが出来上がります。
データ通信とはそんなものです。

編集 削除
Toney  2004-03-24 18:51:25  No: 82650  IP: [192.*.*.*]

そういう仕組みになっていたんですね…その仕組みを考慮してもう1度
プログラムを考えてみます。何度も回答していただきありがとうござい
ました。またどうしても分からなかったらその時は宜しくお願い致します。

編集 削除
ゆうき  2005-05-06 23:46:58  No: 82651  IP: [192.*.*.*]

私も最近この問題と酷似した現象に直面し、解決できずに困っております。

解決済みの問題に対して、このように再定義して申し訳ありませんが、
私としましては何としてでも解決したいので、皆様何卒ご助力の程よろしくお願いいたします。

また、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

データ受信と共に全てのデータをバッファから読出し、
表示させるためにはどのような作りにすればよろしいの
でしょうか?
どうかご指導の程、よろしくお願いいたします。

編集 削除
ぶぶ  2005-05-07 11:42:03  No: 82652  IP: [192.*.*.*]

一度解決がたっているので、別に立てたほうがいいような気がします。

編集 削除