アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB.netで、シリアル通信のタイムアウト処理について

http://msdn.microsoft.com/ja-jp/library/7ya7y41k …
このサイトのコードを、参考にしています。
------------------------------------ここから
Dim com1 As IO.Ports.SerialPort = Nothing
Try
com1 = My.Computer.Ports.OpenSerialPort("COM1")
com1.ReadTimeout = 10000

Catch ex As TimeoutException
returnStr = "Error: Serial Port read timed out."
Finally
If com1 IsNot Nothing Then com1.Close()
End Try

------------------------------------ここまで

この方法ですと、タイムアウトが発生したらポートを閉じるようですが、これを、送信したシリアルのデータを再度、送信させたいと思います。
そして、何度かリトライを掛けた後に、やっぱり駄目だったときに
ポートを閉じたいと思います。

どんな方法がありますか?

参考になりそうなサイトなどがありましたら、教えていただけませんか。
以上、よろしくお願いします。

A 回答 (3件)

タイムアウトはWrite/Read(送受信)系メソッドで


発生します。そのメソッドをTry~Catchブロックで
ハンドリングしないと意味ないでしょ。
掲題のプログラムはポートを開いて、タイムアウトの
時間を設定しただけですから、送受信していません。
    • good
    • 0
この回答へのお礼

ありがとうございます。

長らくお付き合いしていただきまして、感謝しております。
何とか解決できそうです。

お礼日時:2010/07/28 09:06

あぁ、そういうやり方ですか。


それだと、Private Sub ButtonRsStart_Clickでは
仕込みするだけですからタイムアウトになりません。
だって、Readしてませんからね。タイムアウトは読み
込みを始めてから完了するまでの制限時間です。
よって、このメソッドではOpenメソッドの失敗で例外が
発生するくらいでしょうか。

Private Sub SerialPort1_DataReceived
こちらの方でタイムアウト時の処理を記述すべきです。

それにしても、何所にも「送信」している箇所が無い
ように見えますが、大丈夫なんでしょうか?
    • good
    • 0
この回答へのお礼

ご返答、ありがとうございます。


>Private Sub SerialPort1_DataReceived
>こちらの方でタイムアウト時の処理を記述すべきです。

と、言う事は、タイムアウトが発生したら、Private Sub SerialPort1_DataReceivedの中で処理出来るのでしょうか?


>それにしても、何所にも「送信」している箇所が無い
>ように見えますが、大丈夫なんでしょうか?

これは、別口で「送信」ボタンを設けているからです。
つまり、仕込み部、送信部、受信部という構成にしています。

お礼日時:2010/07/23 14:38

次のように考えたら如何でしょう。


(1)ポートを開く。この時に例外が発生したら終了する。
(2)以下の(3)~(5)を既定の回数繰り返す。
(3)データを送信する。
(4)データを受信する。読み込めたらループを抜ける。
(5)タイムアウトなら(3)から繰り返す。
(6)ポートを閉じる。

Try
    com1 = My.Computer.Ports.OpenSerialPort("COM1")
    com1.ReadTimeout = 10000
    For I As Integer = 1 To 5
        Try
            returnStr = con1.ReadLine()
            Exit For
        Catch ex As TimeoutException
            returnStr = "Error: Serial Port read timed out."
        Catch ex As Exception
            returnStr = ex.Message
            Exit For
        End Try
    Next
    com1.Close()
Catch ex As Exception
    returnStr = "Error: Serial Port open failed."
End Try

この回答への補足

早速の御解答を戴きまして、ありがとうございます。

私の説明不足で申し訳ございませんが、私が書いたプログラム構造は次のようになっています。

'初期設定&ポートを開く
Private Sub ButtonRsStart_Click(ByVal sender ・・・) Handles ButtonRsStart.Click

With SerialPort1
Try '例外処理のはじまり
If .IsOpen = True Then 'ポートはオープン済み
MessageBox.Show("すでに" & .PortName & "は接続されています。", "エラー",
MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End If

.PortName = PORTNUM.Text 'オープンするポート名を格納
.Open() 'ポートオープン
.DiscardInBuffer() '入力バッファを、初期化する
.DiscardOutBuffer() '出力バッファを、初期化する
.ReadTimeout = 1000 'Time out (ms)


Catch ex As TimeoutException
'Timeout 例外処理
MessageBox.Show(ex.Message, "Error: Serial Port read timed out.", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End With
End Sub


'受信イベントが発生したときの処理を記述します
Private Sub SerialPort1_DataReceived(ByVal sender ・・・) Handles SerialPort1.DataReceived


Try

'1フレーム分を、読み出す。
ReceivedData = SerialPort1.ReadLine

'受信処理をする。

Catch ex As Exception
ReceivedData = ex.Message
End Try

End Sub
--------------------------- ここまで

このやり方ですと、タイムアウトのとき、
Handles SerialPort1.DataReceived の受信イベントが発生しなくて
SerialPort1_DataReceived の処理をしないのではないでしょうか?

もし、そうなら、次のように
Private Sub SerialPort1_ErrorReceived() Handles SerialPort1.ErrorReceived
(エラー処理)
End Sub
といった具合に、処理を分ければいいのでしょうか?

長くなりましたが、何卒、御教示ください。

補足日時:2010/07/21 17:21
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A