VB6にて、MSCommを使用して、サブルーチンを使ってバイナリデータを送信する方法は?

解決


えーじ  2005-01-20 22:42:24  No: 87952  IP: [192.*.*.*]

こんばんは、MSCommのエラー処理ではお世話になりました。
プログラムを作成していて、やり方が分からないのでご教授下さい。

ターゲット機器はマイコンで、バイナリで通信します。
例えば、マイコンが制御しているレジスタに書き込みを行う場合、以下のプロトコルになります。

&HA0_&H79_&H00_AddressH_AddressL_DataH_DataL

&HA0 + &H79 + &H00 : レジスタライトコマンド
AddressH           : アドレスHigh-Buye
AddressL           : アドレスLow-Byte 
DataH              : データHigh-Byte
DataL              : データLow-Byte

つまり、バイナリで7Byte送信します。
コマンドは常に同じで、アドレスとデータだけ違うので、実際の書き込みは
サブルーチン化しました。

Public TxBuff As String

Private Sub Command1_Click()
  TxBuff = ChrB$(&H5) + ChrB$(&H1) + ChrB$(&H0) + ChrB$(&H1) 
  ' Address 0501H, Write Data0001H
  Call WAcc
End Sub

Public Sub WAcc()
  TxBuff = ChrB$(&HA0) + ChrB$(&H79) +ChrB$(&H00) + TxBuff
  MSComm1.Output = TxBuff
End Sub

このように作ると、何も送信されません。
そこで、以下のような簡単なプログラムを書いてみました。

TxBuff = ChrB$(&HB0)
MSComm1.Output = TxBuff

これでは送信されませんでした。これを以下のようにすると、送信しました。

TxBuff = ChrB$(&HB0) + ChrB$(&H0)
MSComm1.Output = TxBuff

ちなみに、MSComm1.InputMode = comInputModeBinary  としています。
なお、VB5では問題ないようです(というのも、VB5で動いているコードを参照してコーディングしました)。

現在は、以下のようにしています(力ずくのコーディングですが。。。)

Public AdrH As Byte, AdrL As Byte
Public DataH As Byte, DataL As Byte

Public Sub Command1_Click()
    AdrH = &H5
    AdrL = &H1
    DataH = &H0
    If Option1.Value = True Then
        DataL = &H0
    ElseIf Option2.Value = True Then
        DataL = &H1
    ElseIf Option3.Value = True Then
        DataL = &H4
    End If
    Call WAcc

End Sun

Public Sub WAcc()
    Dim TxCommand(2) As Byte
    Dim TxAdrData(3) As Byte
    MSComm1.OutBufferCount = 0
    TxCommand(0) = &HA0
    TxCommand(1) = &H79
    TxCommand(2) = &H0
    TxAdrData(0) = AdrH
    TxAdrData(1) = AdrL
    TxAdrData(2) = DataH
    TxAdrData(3) = DataL
    MSComm1.Output = TxCommand
    MSComm1.Output = TxAdrData
End Sub

ちょっと長くなりましたが、以上です。
アドバイスお待ちしております。

編集 削除
魔界の仮面弁士  2005-01-20 23:29:48  No: 87953  IP: [192.*.*.*]

VB6でサブルーチンといった場合、「GoSubステートメント」を
用いた処理を意味する事が多いです。
今回の場合は、Subプロシージャでは無いですか?


> Public TxBuff As String
> Private Sub Command1_Click()
>   TxBuff = ChrB$(&H5) + ChrB$(&H1) + ChrB$(&H0) + ChrB$(&H1) 

String型は、文字列を格納するためのデータ型です。
この場合は使わないでください。

バイナリデータの取り扱いには、String型を用いるのではなく、
「Byte型の配列」を用いるようにしてみてください。
御自身で書かれた Sub WAcc() は、まさにByte配列を使っていますよね。

指定するデータ量が不定なら、ReDimステートメントを併用して、
動的配列にされても良いでしょう。


なお、MSCommの使い方に関しては、以下をご覧ください。
http://support.microsoft.com/kb/411403/ja

また、MSCommのトラブルシューティングが下記にあります。
http://support.microsoft.com/kb/192012/ja

編集 削除
えーじ  2005-01-22 00:12:00  No: 87954  IP: [192.*.*.*]

こんばんは、えーじです。

>String型は、文字列を格納するためのデータ型です。
>この場合は使わないでください。

>バイナリデータの取り扱いには、String型を用いるのではなく、
>「Byte型の配列」を用いるようにしてみてください。
>御自身で書かれた Sub WAcc() は、まさにByte配列を使っていますよね。

魔界の仮面弁士さんのおっしゃるように、MSのWEBには、バイナリ型は
Byteを使うように記述しています。
これは問題ないんですが、byteでは

Public AAA() As Byte

は、エラーになりますよね。
私は、
Public A1 As Byte, A2 As Byte, A3 As Byte
というように記述しましたが、今回のようにバイナリデータを送る場合は
Publicとして配列型の変数は定義できないのでしょうか?

分かりづらくて申し訳ありません。これが私の質問の趣旨でした。

編集 削除
abu  2005-01-22 00:22:11  No: 87955  IP: [192.*.*.*]

>Public AAA() As Byte
>は、エラーになりますよね。

プロシージャ内でPublic宣言するとエラーになりますが
モジュールレベル変数でPublicはエラーになりません。

本当にエラーになりましたか?
確認してみてください。

編集 削除
魔界の仮面弁士  2005-01-22 14:02:53  No: 87956  IP: [192.*.*.*]

> Public AAA() As Byte
> は、エラーになりますよね。

『フォームモジュール』などでは確かにエラーになりますが、Privateスコープでの定義ならば可能です。
あるいは『標準モジュール』で定義すれば、Publicスコープでも定義できます。


まず、「本当にPublicでなければいけないのか?」を、よく検討してみてください。
カプセル化の面から言えば、可能な限り、変数のスコープは狭くした方が
良いので、まずはPrivateにする事を検討してください。

もし、モジュールの外部からアクセスできるよう、公開メンバにしたいなら、
Private変数を直接Publicにするのではなく、Friend Property や
Public Property などを経由させるよう、コーディングを見直してみましょう。

編集 削除
えーじ  2005-01-22 14:13:00  No: 87957  IP: [192.*.*.*]

魔界の仮面弁士さん、abuさん、ありがとうございます。

>プロシージャ内でPublic宣言するとエラーになりますが
>モジュールレベル変数でPublicはエラーになりません。

Formのコード内で、Public AAA() As Byte とすると、エラーになりました。

なるべく見通しが良いように、MSCommに対するアクセスをプロシジャーにして、
ターゲットに対する"コマンド"、"アドレス"、"データ"を引数で渡したかったんです。

>『フォームモジュール』などでは確かにエラーになりますが、Privateスコープでの定義ならば可能です。
>あるいは『標準モジュール』で定義すれば、Publicスコープでも定義できます。

済みません、まだ駆け出しなので、意味が分からない部分が多いです。
勉強します。

一応やりたいことは出来たので、さらに勉強を続けさせてもらいます。
ありがとうございました。

編集 削除