こんばんは、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
ちょっと長くなりましたが、以上です。
アドバイスお待ちしております。
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
こんばんは、えーじです。
>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として配列型の変数は定義できないのでしょうか?
分かりづらくて申し訳ありません。これが私の質問の趣旨でした。
>Public AAA() As Byte
>は、エラーになりますよね。
プロシージャ内でPublic宣言するとエラーになりますが
モジュールレベル変数でPublicはエラーになりません。
本当にエラーになりましたか?
確認してみてください。
> Public AAA() As Byte
> は、エラーになりますよね。
『フォームモジュール』などでは確かにエラーになりますが、Privateスコープでの定義ならば可能です。
あるいは『標準モジュール』で定義すれば、Publicスコープでも定義できます。
まず、「本当にPublicでなければいけないのか?」を、よく検討してみてください。
カプセル化の面から言えば、可能な限り、変数のスコープは狭くした方が
良いので、まずはPrivateにする事を検討してください。
もし、モジュールの外部からアクセスできるよう、公開メンバにしたいなら、
Private変数を直接Publicにするのではなく、Friend Property や
Public Property などを経由させるよう、コーディングを見直してみましょう。
魔界の仮面弁士さん、abuさん、ありがとうございます。
>プロシージャ内でPublic宣言するとエラーになりますが
>モジュールレベル変数でPublicはエラーになりません。
Formのコード内で、Public AAA() As Byte とすると、エラーになりました。
なるべく見通しが良いように、MSCommに対するアクセスをプロシジャーにして、
ターゲットに対する"コマンド"、"アドレス"、"データ"を引数で渡したかったんです。
>『フォームモジュール』などでは確かにエラーになりますが、Privateスコープでの定義ならば可能です。
>あるいは『標準モジュール』で定義すれば、Publicスコープでも定義できます。
済みません、まだ駆け出しなので、意味が分からない部分が多いです。
勉強します。
一応やりたいことは出来たので、さらに勉強を続けさせてもらいます。
ありがとうございました。