こんばんは。
ターゲット機器とRS232で接続し、この機器の制御プログラムをVB6で作成しています。ターゲット機器とは、バイナリでの通信で、簡単なプロトコルを使います。
PCに標準で実装されているCOM1を使って問題なく通信できて(ターゲット機器の制御が希望通りできて)います。
PCには、COMポートが1つしかないため、複数のターゲットを制御しなければならない理由から、USBからRS232に変換するケーブル(ELECOMのもの)を使っています。
この変換ケーブルを使うと、
"実行時エラー'9':
インデックスが有効範囲にありません"
というエラーが出てしまいます。
エラーの出る場所は、
RxBuff = MSComm1.Input
If Len(Hex$(CStr(RxBuff(1)))) = 1 And Len(Hex$(CStr(RxBuff(2)))) = 1 Then
RxBuffData = "0" + Hex$(CStr(RxBuff(1))) + "0" + Hex$(CStr(RxBuff(2)))
ElseIf Len(Hex$(CStr(RxBuff(1)))) = 1 And Len(Hex$(CStr(RxBuff(2)))) = 2 Then
RxBuffData = "0" + Hex$(CStr(RxBuff(1))) + Hex$(CStr(RxBuff(2)))
ElseIf Len(Hex$(CStr(RxBuff(1)))) = 2 And Len(Hex$(CStr(RxBuff(2)))) = 1 Then
RxBuffData = Hex$(CStr(RxBuff(1))) + "0" + Hex$(CStr(RxBuff(2)))
Else
RxBuffData = Hex$(CStr(RxBuff(1))) + Hex$(CStr(RxBuff(2)))
End If
で、Len(Hex$(CStr(RxBuff(1)))) = 1 And Len(Hex$(CStr(RxBuff(2)))) = 1 Then
の部分です。(COM1を使うと、問題なく実行されているようです)
ここでやりたいことは
・受信したバイナリデータを、
・4文字の文字列にする
です。
RxBuffDataはString型の変数で、RxBuffは、Byte型の変数です。
これはターゲット機器のレジスタをリードしているコードの一部です。
ターゲット機器は、
ACK + Data_H + Data_L
の3バイトを返してきます。
この2バイト目、3バイト目を、16進表記の文字列としてフォームに表示したいために、
このようなコードを入れてあります。
USBからRS232へ変換するケーブルを使うと、このようなエラー発生は既知の問題なのでしょうか?
回避する方法はあるでしょうか?
以上、アドバイス頂ければ幸いです。
>RxBuff = MSComm1.Input
ここにブレークポイントいれて本当にRxBuffが配列になったかを確かめた?
単に受信できていないのに次の処理をしようとしているだけのような気がしますが。
拡張したんだったらCOMポートも当然変わるでしょうから、その辺の設定とか
もちゃんとしました?
恐らく、Inputが空の配列を返しているのではないでしょうか。
空の配列だったらそのままイベント処理を終わるようにすればOKでしょう。
MsCommは実際の挙動のかなりの部分がドライバとハードに依存しています。そのため、細かな挙動が増設と内蔵で異なることはよくあります。
原因はすでに回答のある通りでしょうね。
受信バッファがまだ空なのにInputしているので、
そのような現象になってしまうのでしょう。
ちゃんと受信バッファにデータが溜まるのを待って、
それからInputすれば問題ないと思います。
イベントドリブンならRThreshold = 3に、
ポーリングならInBufferCount < 3の間はループするようにするといいでしょう。
それと、掲載されたコードですが、CStrは必要ないですよ。
あと、個人的には↓のようにした方がわかり易いかな。
RxBuff = MSComm1.Input
RxBuffData = Format$(Hex$(RxBuff(1)), "00") & Format$(Hex$(RxBuff(2)), "00")
Formatじゃだめじゃないかな?(Aは数値ではない。)
代わりに↓
Right$("00" & Hex$(RxBuff(1)), 2) & Right$("00" & Hex$(RxBuff(2)), 2)
>Formatじゃだめじゃないかな?(Aは数値ではない。)
Formatじゃだめじゃないかな?(A〜Fは数値ではない。)
みなさん、ありがとうございます。
ひろあきさんがおっしゃっているように、
>ポーリングならInBufferCount < 3の間はループするようにするといいでしょう。
としていますが、USBから変換するとNGです。
>ここにブレークポイントいれて本当にRxBuffが配列になったかを確かめた?
と言われ、きちんとデバッグしていないことに気づき、今日ブレークポイントを入れてデバッグしてみました。
すると、ステップで実行するとエラーが出ませんでした。
確認すると、InbufferCount < 2 としていました。
念のため、InbufferCount < 3 でループを抜けた後、RxBuff = MSComm1.Inputの直前に、For〜Nextを入れてウエイトさせました。
ところが、"11001010"/"xxxxxxxx"/"xxxxxxxx"と3バイトを返して来るはずなんですが、
"00000000"/"11001010"/"xxxxxxxx"/"xxxxxxxx"と、4バイトがRxBuffに入っていました。
COM1ではこんな現象は起こっていませんでした。
そこで、COM1の場合とCOM3以降の場合で、RxBuffの配列を変えるようにして、
COM3以降の場合はRxBuff(0)を捨てるようにしました。
一応、これで希望の動作をさせることが出来ました。
途中で送信してしまいました。
皆さんありがとうございました。
>RxBuff = MSComm1.Input
>RxBuffData = Format$(Hex$(RxBuff(1)), "00") & Format$(Hex$(RxBuff(2)), "00")
>Right$("00" & Hex$(RxBuff(1)), 2) & Right$("00" & Hex$(RxBuff(2)), 2)
このへんの事も、非常に参考になりました。
VBは、ここ1ヶ月で始めたところなので、非常にいいアドバイスに感謝しています。
ツイート | ![]() |