初めて質問させていただきます。
VB6.0を利用してRS232Cで通信しようとしているのですが、測定器からの受信
が思いどおりいきません。測定器から戻ってくるデータは16進数で&H10,&H06の2バイトが受信されるはずが、「?」がほとんどで「?・・」がたまに受信されます。プログラムは
Dim varBuffer As Variant
'CommEventプロパティに対する各処理
Select Case MSComm1.CommEvent
'イベントメッセージ
Case comEvCD 'CD ラインの状態が変化しました。
Case comEvCTS 'CTS ラインの状態が変化しました。
Case comEvDSR 'DSR ラインの状態が変化しました。
Case comEvRing 'リング インジケータの状態が変化しました。
Case comEvReceive
'受信データの取得
varBuffer = MSComm1.Input
Text2.Text = Text2.Text & varBuffer
・
・
・
です。
よろしくお願いいたします。
Case comEvReceive
'受信データの取得
varBuffer = MSComm1.Input
Text2.Text = Text2.Text & varBuffer
・
・
・
この・・・の部分の設定は正しいですか?(パリティなど)
受信できるか・・・と言う問題よりも・・・
&H10 &H06 と言うバイナリデータを受信するわけですので
それを・・・
Text2.Text = Text2.Text & varBuffer
では、表示できません。アスキーコードで&H20未満のコードです
ので、本当に『?』とか『・』と言う表示なります・・・
受信データを1バイトづつ切り出して、Hex$()で、文字にして
テキストボックスにでも表示させて下さい。
以上。
みなさん、ありがとうございます。
私の勉強不足で申し訳ありません。
受信データを1バイトづつ切り出していく方法のサンプルなどが
ありましたら教えていただけないでしょうか。
よろしくお願いいたします。
バイナリデータで受信するなら、
InputModeをcomInputModeBinaryにして、
Dim bytArray() as Byte
・
・
・
bytArray = MSComm1.Input
にしましょう。
そしてとりあえず作ってみたbatchman作の関数にデータを渡してみる。
Text2.Text = ByteArrayToHexDumpString(bytArray)
これで、バイナリデータをHexダンプ文字列で確認できるかな...
取り合えず作ってみたものなので、不具合あったら自分で直して下さい。
#このままでは受信するたびに、TextBoxの内容が書き換えられてしまうので、
#受信した内容をスクロールするならMSDNヘルプでTextBoxの
#SelLength、SelStart、SelText プロパティの使用例などを参考にしてみて下さい。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' '
' Byte型配列のデータからHexダンプ文字列を作成する '
' '
' 第1引数 Binaryデータ Byte型配列 '
' '
' 戻り値 String Hexダンプ文字列 '
' '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function ByteArrayToHexDumpString(bytArray() As Byte) As String
Dim i As Long
Dim Max As Long
Dim Min As Long
Dim lngSize As Long
Dim strBuff As String
'最初に決められたバッファを用意して、高速化する。
Max = UBound(bytArray)
Min = LBound(bytArray)
lngSize = Max + 1 - Min 'バッファサイズ計算
i = lngSize * 3 + Fix((lngSize + 15) / 16) - 2 'HEXダンプに必要なバッファサイズを計算
strBuff = Space$(i) 'あらかじめ必要なバッファを確保
For lngSize = 48 To i Step 49
Mid$(strBuff, lngSize, 2) = vbCrLf '所定の位置に改行コードをセット
Next
'1バイトずつHEXコードを確保されたバッファの所定の位置にセットする。
For i = Min To Max
lngSize = (i - Min) * 3 + Fix((i - Min) / 16) + 1 '書き込み位置を計算
Mid$(strBuff, lngSize, 2) = Right$("0" & Hex$(bytArray(i)), 2) '所定の位置にHEXコードをセット
Next
ByteArrayToHexDumpString = strBuff
End Function
batchmanさん、ありがとうございます。
batchmanさんのプログラムで操作を行うと
「プロシージャの呼び出し、または引数が不正です。」というエラーが出てしまいました。そこで、Max,Min,lngSize,iの値を調べるとMaxの値が「-1」,「1」と変化を繰り返しているため「-1」のときに「i」がマイナスとなりエラーが発生していました。そこで、iの値をそのままプラスの数字で入れてあげたら成功しました。しかし、Maxの値がマイナスになった場合は戻り値が表示されないので、試行錯誤中です。
また、今回は2バイトの場合でしたが10バイト、20バイトなど戻り値のバイトが多くなったらどのようにしたらよろしいでしょうか。
よろしくお願いします。
>「プロシージャの呼び出し、または引数が不正です。」というエラーが出てしまいました。そこで、Max,Min,lngSize,iの値を調べるとMaxの値が「-1」,「1」と変化を繰り返しているため「-1」のときに「i」がマイナスとなりエラーが発生していました。そこで、iの値をそのままプラスの数字で入れてあげたら成功しました。しかし、Maxの値がマイナスになった場合は戻り値が表示されないので、試行錯誤中です。
これはMsCommのInputが空の配列を返した場合の処理が抜けているために発生する問題ですね。関数の先頭に
If IsEmpty(bytArray) Then
'データが空なので処理打ち切り
ByteArrayToHexDumpString = ""
Exit Function
End If
が必要です。
> Dim bytArray() as Byte
として宣言されているのであれば、
> If IsEmpty(bytArray) Then
が True になる事は無いかと。>ひろさん
もし、データが空だった時の判定を加えるのであれば、
Max = UBound(bytArray)
Min = LBound(bytArray)
の後で、「Max が Min よりも小さければ、空の配列」というように
条件判定させてみては如何でしょう。
> Dim bytArray() as Byte
として宣言されているのであれば、
> If IsEmpty(bytArray) Then
が True になる事は無いかと。>ひろさん
そうですね。MsCommのInputプロパティをVariant型の変数に入れた時と混同していました。
ただし、配列が空であることの確認は必要です。これは推測ですが、Inputプロパティが受信バッファのみクリアし受信発生のイベントキューはクリアしない様に実装されているのではないかと考えています。
つまり、
受信その1発生
↓
受信その1によるイベントプロシージャ呼び出し
↓
受信その2発生
↓
Inputプロパティ参照
・受信バッファはクリアするがイベントキューはクリアされない
↓
受信その2によるイベントプロシージャ呼び出し
↓
Inputプロパティを参照しても中身は空
ということです。
引用符ミスしてますね。すいません。
横やりすみません。初心者その2です。
私も現在MSCommを使ったプログラムを作成しています。
16進数を受信して表示したいのですが、00Hだけどうしても表示できません(00H以外の16進数は表示できます)。ポーリングもイベントドリブンも試しましたがだめでした。ブレイクをかけても00Hのときだけ引っかからないので、イベント自体発生していないと思います。
auさんが本来聞きたいことと違ってきているかも知れず申し訳ありませんが、今の話の流れがちょうどこの方向に来たので便乗で質問させて下さい。
改めて、MSCommでバイナリの00Hを受信して表示する方法を教えて下さい。
よろしくお願いします。
しばらく見ていないうちに、不具合ありの修正案ありの、
便乗質問ありの状態ですね^^;
この関数は、バイトデータが存在することを前提に作っています。
受信データがひとつも無い状態で実行すると、言われている通りになりますね。
提示されているコードは、
MSCommのOnCommイベント内でのことだと思っているのですが違いますか?
Inputメソッドでなぜ1バイトもデータがないことになるのでしょうか...
関数内でエラーをなんとかしたいなら、
魔界の仮面弁士さんのアドバイスをコードにして下さい。
関数の外でエラーをなんとかするなら、
If MSComm.InBufferCount > 0 Then
bytArray = MSComm1.Input
Text2.Text = ByteArrayToHexDumpString(bytArray)
End If
というふうにして、
受信データが無ければ何もしないようにするとか...
>また、今回は2バイトの場合でしたが10バイト、20バイトなど戻り値のバイトが多くなったらどのようにしたらよろしいでしょうか。
意味が分かりません...
1バイトでも10バイトでも関数に渡せばHex文字列に変換して戻り値として返しますが?
>MSCommでバイナリの00Hを受信して表示する方法を教えて下さい。
NullDiscardプロパティがTrueになっているのではないですか?
デフォルトはたしかFalseだったはずですけども...
便乗質問した初心者その2です。
MSCommでバイナリの00Hを表示する方法を探してみましたが、とりあえず解決?しました。
結局MSCommの使用をあきらめ、VectorでフリーのActiveXコントロールを見つけて切り替えたところうまく動作しました。
NullDiscardプロパティは知りませんでした。いずれ試してみたいと思います。
batchmanさんありがとうございました。
横やり失礼しました_(__)_
>MSCommでバイナリの00Hを受信して表示する方法を教えて下さい。
Visual FoxPro 5.0付属のMsCommには00H以降を切り捨ててしまうバグがあったそうですが、VB6付属の物ではそのような話は聞いていません。やはりNullDiscardでは?
http://support.microsoft.com/default.aspx?scid=kb;ja;169502
> 提示されているコードは、
> MSCommのOnCommイベント内でのことだと思っているのですが違いますか?
> Inputメソッドでなぜ1バイトもデータがないことになるのでしょうか...
理由は知りませんが、実際にそうなる以上は対策が必要です。改めてマイクロソフトのサポート情報を探してみたらサンプルコードではInputBufferCountを確認するようになっていました。
(日本語版はまだ機械翻訳版なので英語版を読むことをお勧めします。)
英語版
http://support.microsoft.com/default.aspx?scid=kb;en-us;154741
日本語版(
http://support.microsoft.com/default.aspx?scid=kb;ja;154741
みなさんありがとうございます。
関数を修正したらできるようになりました。
多くのご教授ありがとうございましたm(__)m
ツイート | ![]() |