こんばんは。
RThresholdを使うと、oncommイベントが発生します。
この度一つのシリアル回線で、1バイトと2バイトについて、
場合分けで受信したいと思っておりますが、可能なのでしょうか?
試しに、RThreshold=1に指定し、
oncomm内で、if inbufferCount=1の時と2の時で場合分けしてみたのですが、
全く効果なしでした。
何か秘策をお持ちの方がおりましたら、よろしくお願いします。
1バイトとか2バイトだけしか受信しないというのはどのような場合が
あるのでしょうか?
必要以上にデータを受信したくない場合、RS/CSなどのフロー制御を入れれ
ば受信側から送信側に通知することもできますが、送信側がこういった信号
を監視していなければデータの受信は止めることはできません。
常に2バイト受信すると仮定して、1バイトの時は2バイト目を捨てる
(無視する)というのなら可能だと思います。
最近、RS-232Cの通信の話題が多いですが・・・
今回のケースは、あくまで1バイトづつ取り込んで、それを、
一旦、バッファ(文字列)変数に蓄積し、その先頭から1バイ
トづつ切り出して、これは1バイトのデータ、これは2バイト
のデータ・・・と言う具合に判断していくしか無いはずです。
実際、プログラム書く側は、そのデータの素性が、1バイト系
データか、2バイト系データか知っているわけですから、その
非同期・同期化のバッファリングとデータ切り出し部分での、
本来のプログラミングと言うか、アルゴリズムの作成が醍醐味
のはずです。
おおまかに・・・
Option Explicit
' 通信用受信バッファ
Private gBuffer As String
Private Sub Form_Load()
' バッファクリア
gBuffer = ""
' RS=232C初期化・オープン
MSComm1.CommPort = 1
MSComm1.Handshaking = comRTS
MSComm1.InputMode = comInputModeBinary
MSComm1.Settings = "9600,n,8,1"
MSComm1.RThreshold = 1
MSComm1.SThreshold = 1
MSComm1.PortOpen = True
' RTSの制御有りでオープンしているので
' 一応、制御信号をON
MSComm1.DTREnable = True
MSComm1.RTSEnable = True
End Sub
Private Sub Form_Unload(Cancel As Integer)
' 制御信号をOFF
MSComm1.DTREnable = False
MSComm1.RTSEnable = False
' RS-232Cクローズ
MSComm1.PortOpen = False
End Sub
Private Sub MSComm1_OnComm()
Dim sz As String
' 受信イベントを判定
If (MSComm1.CommEvent And comEvReceive) <> 0 Then
' 受信データの存在を確認
If MSComm1.InBufferCount > 0 Then
' 受信バッファのデータ数分を取得対象とする
MSComm1.InputLen = MSComm1.InBufferCount
' 受信
sz = MSComm1.Input
' バッファに蓄積
' UNICODE系の場合、データ変換を追加しないと
' 正しいデータにならない・・・要注意
gBuffer = gBuffer & sz
End If
End If
' データ判定・処理
Call CheckData
End Sub
Private Sub CheckData()
Dim sz As String
' バッファにデータがあるか判定
If Len(gBuffer) = 0 Then
' 無ければ終了
Exit Sub
End If
' バッファにデータが無くなるまで処理
While Len(gBuffer) > 0
' まずバッファから1バイト切り出し
sz = Left$(gBuffer, 1)
' データの判別:1バイト系か2バイト系か?
' 単純な判断ですが、最終的にはもっと複雑になる
' はずですが・・・
If sz = xxx Then
' 1バイト系データ処理
' (ここに、1バイト系データ処理を書く)
' 処理済みのデータを、バッファから削除
gBuffer = Right$(gBuffer, Len(gBuffer) - 1)
Else
' 取得済みのデータを、バッファから削除
gBuffer = Right$(gBuffer, Len(gBuffer) - 1)
' 2バイト目データ取得
sz = sz & Left$(gBuffer, 1)
' 2バイト系データ処理
' (ここに、2バイト系データ処理を書く)
' 処理済みのデータを、バッファから削除
gBuffer = Right$(gBuffer, Len(gBuffer) - 1)
End If
Wend
End Sub
※ あくまでアルゴリズムですから・・・
参考までに・・・
以上。
ももんがさん、岡田 之仁さん、情報ありがとうございます。
(特に岡田さんには丁寧に書いていただきまして、恐縮です)。
計測器から1バイトの時と、2バイトのデータを取り出したいと思ってました。
1バイトずつ振り分けるというヒントをいただきまして、無事動作することが出来ました。
助けていただいて大変助かりました。
まだ未熟者でして、いずれ情報お返しできるように精進いたします。
ありがとうございました。
アルゴリズムを簡単の表現する意味でソースを掲載しましたが、
この状態では、まれにバグと言うか、問題が出ます。
2バイト系データの1バイト目を受信した折に、たまたまイベン
トが間に合い、OnComm処理が開始されてしまった場合、2バイト
目を受信していないので、データの切れ目の処理が無い為、ある
はずの2バイト目が無い為、おかしなことになります。
2バイト目を1バイトとして受信した場合、つじつまが合わなく
なりますので、2バイト系データの処理部分に、2バイト目が無
い場合の処理と、1バイト系データの処理部分に、2バイト系の
2バイト目のデータを、1バイト系として受け取ってしまった場
合の処理を追加しないと・・・折角受信したのに、読みほかして
しまうようなことが発生します。
非常にマレなことですが、あり得ますので・・・
以上。