ここから本文です

VB2008でWin32API関数を用いてシリアル通信を行いたいのですが...

hmw********さん

2010/2/322:43:07

VB2008でWin32API関数を用いてシリアル通信を行いたいのですが...

上記の質問ですが、
PCと通信機器をRS232Cケーブルでつなぎ、
VB2008からWinAPI関数をたたき、命令コマンドを通信機器に入力すると、応答コマンドが返る構成を造りたいと考えています。
★問題として、命令コマンドを通信機器に入力すると、動作するのですが、応答コマンドが返ってくる時と来ないときがあります。
また、文字化けするときがたまにあります。
何が原因か見当がつきません。アドバイス願います。 (因みに、ハイパータミナルで問題なく応答コマンドが受信できました。)

プログラムの一部(送受信の部分)を以下に示します。


'データの送信
Dim wData As String
Dim wLen, dLen As Integer
wData = "H:1" & vbCrLf
dLen = Len(wData) '引数が半角文字の場合

Dim dummyBoo as boolean
dummyBoo = ClearCommBreak(hComm)
dummyBoo = WriteFile(hComm, wData, dLen, wLen, 0)

'データの受信
Dim rData As String
Dim rLen, cnt As Integer
rData = Space(100)
dummyBoo = ReadFile(hComm, rData, 100, rLen, 0)
Do While rLen < 1 And cnt < 10
dummyBoo = ReadFile(hComm, rData, 100, rLen, 0)
cnt = cnt + 1
Application.DoEvents()
Loop

補足pottonvenjoさんへ
アドバイスありがとうございます。
今回はどうしてもWinAPIを使わないといけないのっぴきならない事情があります。
面倒くさい事情ではありますが、ご容赦願います。

早速、DoEvents()は取り除きました。

また、文字化けについても文字コードを変換することで解決しました。

★問題は、受信コマンドが常に返って来ないことです。
データ受信の前に1秒待機させる命令文も追加したのですが、受信コマンドが不安定です。

閲覧数:
2,501
回答数:
1
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

pot********さん

編集あり2010/2/413:43:23

うーむ。

DoEventsはまずくないか。
メッセージループは正しく処理しないと。
DoEventsは確実にメッセージを無視していい場合、もしくは全てのパターンで正常に処理できるロジックが組める場合以外は、使っちゃまずい。

文字化けはエンコーディングが合ってないだけと思う。
.NetFrameworkの既定のエンコーディングはUTF-8なので、その辺りを確認した方がいい。

てか、せっかく.NetなんだからAPIではなく、SerialPortクラスを使った方が楽だし安定すると思うんだが。
複数エンコーディングにも対応してるし、必要ならエンコーディングも指定できる。
http://msdn.microsoft.com/ja-jp/library/system.io.ports.serialport(...

ソースを見た感じ、VB6以前のコードの流用ってことなんだろうけど。
それでも、ランタイムの仕組み自体が違うんだし、環境に合った適切な手法を選択することをお奨めする。

--------

①API関数の定義に問題ないかを確認する(Anyの代替、ByVal、ByRef等)
②適切なタイムアウトが設定されているかを確認する
参考)http://support.microsoft.com/kb/823179/ja

--------

追記漏れ。
ちょっと細かい点だけど。


>rData = Space(100)
>dummyBoo = ReadFile(hComm, rData, 100, rLen, 0)

2のべき乗値(256バイト、512バイトくらい)の方が効率がいい。
どうせKernel32としては読んでるので。
せっかく読んだ値をAPI関数が切り捨てていることになり、結果として部分的に二度読みすることになる(はず)。
それから、rDataはStringではなくByte配列が適切と思う。


>dummyBoo = ReadFile(hComm, rData, 100, rLen, 0)

最終パラメータはIntPtrのはず。
VBだと暗黙変換される・・・のかね?
暗黙変換の仕組みは詳しくないので分からんけど、ポインタの0と整数の0は別物なので、IntPtr.Zeroが安全。


ってことで、仮に指摘分を全て反映させるとしたらこんな感じかね。

Dim rData As Byte() = System.Text.Encoding.UTF8.GetBytes(Space(2 ^ 8)) ' 256Byte
Dim rLen, cnt As Integer

While rLen < 1 AndAlso cnt < 10
dummyBoo = ReadFile(hComm, rData, rData.Length, rLen, IntPtr.Zero)
cnt += 1
End While

Dim result As String
If rLen > 0 Then result = System.Text.Encoding.UTF8.GetString(rData)

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる