質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

解決済

複数のシリアルポートを使用した通信処理にて通信が不可能になる

backfever
backfever

総合スコア12

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

3回答

0評価

1クリップ

10483閲覧

投稿2019/01/26 01:33

編集2019/01/26 01:47

現状

2つのシリアルポート、2つのスレッドタイマを使用して2つのインジケータから値を取得する処理を行っています。
シリアルポート1はインジケータ1と通信
シリアルポート2はインジケータ2と通信
する仕様になっており、これが変わることはありません。
スレッドタイマで数分毎に通信し値を取得し、タイミングはバラバラでポート1と2がほぼ同時に通信することもありますし
個々に通信をすることもあります。
PCからはUSB変換器を使用してRS232Cと接続をしています。

問題点

通常は正常に通信を行っていて、値も正常に取得できるのですが、あるタイミングで通信タイムアウトが発生し、通信ポートの初期化やプログラム再起動をしても通信が復帰せず、結局PC再起動するまで、タイムアウトが発生し続けます。
PC再起動を行うと正常に通信できるようになります。

実現したいこと

通信タイムアウトが発生しないようにするか、発生した場合、状態をクリアしPC再起動せずに再度通信を再開したい。

ソースコード

vb.net

''' フォームロード時 Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'TimerCallbackデリゲート Dim fillTimerDelegate As Threading.TimerCallback = New Threading.TimerCallback(AddressOf FillTimerEvent) 'タイマの生成と開始(コールバック処理に時間がかかった場合でも処理を待機し順次処理ように最初は一度しか処理しないように0を設定する) FillTimer = New Threading.Timer(fillTimerDelegate, Nothing, 0, 0) 'TimerCallbackデリゲート Dim emptyTimerDelegate As Threading.TimerCallback = New Threading.TimerCallback(AddressOf EmptyTimerEvent) 'タイマの生成と開始(コールバック処理に時間がかかった場合でも処理を待機し順次処理ように最初は一度しか処理しないように0を設定する) EmptyTimer = New Threading.Timer(emptyTimerDelegate, Nothing, 0, 0) End Sub '''タイマ1 Public Sub FillTimerEvent(ByVal obj As Object) '通信処理 If Serial_One() = True Then '処理正常終了後、次のコールバックを設定 If FillTimer Is Nothing Then Else FillTimer.Change(1000, Timeout.Infinite) End If Else '異常時の処理 End If End Sub '''タイマ2 Public Sub EmptyTimerEvent(ByVal obj As Object) '通信処理 If Serial_Two() = True Then '処理正常終了後、次のコールバックを設定 If EmptyTimer Is Nothing Then Else EmptyTimer.Change(1000, Timeout.Infinite) End If Else '異常時の処理 End If End Sub 'ポート1 Private Function GetWeightInfo_Serial_JYU_Simple() As Boolean Dim Result As Boolean = False Dim ENQ As Integer = &H5 'ENQ Dim NAK As Integer = &H15 'NAK Dim 安定計量値 As String = "1" Dim 不安定 As String = "0" Dim 計量範囲外 As String = "OV" Dim NAKStr As String = "NAK" Dim wkStr As String = "" Dim recvWeight As Double = 0 Dim RecvData As String = "" Dim IsRecved As Boolean = False 'シリアルポート1 Dim SerialPort_Jyu As New SerialPort() Try Dim SerialPortIsOpen = False For recvTryCount As Integer = 1 To 5 Try 'シリアルポート SerialPort_Jyu = New SerialPort() '------------------------------------ 'シリアルポートの設定 '------------------------------------ 'ポートを一度閉じる If SerialPort_Jyu.IsOpen = True Then 'バッファのクリア SerialPort_Jyu.DiscardInBuffer() SerialPort_Jyu.DiscardOutBuffer() 'ポートが既に開かれている場合は閉じる SerialPort_Jyu.Close() SerialPort_Jyu = Nothing 'シリアルポート宣言 SerialPort_Jyu = New SerialPort() End If 'ポートのオープン処理 SerialPort_Jyu.PortName = "COM1" SerialPort_Jyu.BaudRate = 9600 SerialPort_Jyu.DataBits = 8 SerialPort_Jyu.Parity = IO.Ports.Parity.Even SerialPort_Jyu.StopBits = IO.Ports.StopBits.One 'タイムアウト値設定 SerialPort_Jyu.ReadTimeout = 10000 SerialPort_Jyu.WriteTimeout = 10000 'シリアルポートをオープンする. SerialPort_Jyu.Open() 'バッファのクリア SerialPort_Jyu.DiscardInBuffer() SerialPort_Jyu.DiscardOutBuffer() 'ポートフラグ設定 SerialPortIsOpen = True Dim _requestBytes As Byte() = Encoding.GetEncoding("shift-jis").GetBytes(Chr(ENQ)) 'シリアルポートから計量依頼を送信する.(ENQ送信) SerialPort_Jyu.Write(_requestBytes, 0, 1) '受信するまで待機する RecvData = "" RecvData = SerialPort_Jyu.ReadLine() '受信データ表示 Console.WriteLine(RecvData) Result = True Catch ex As Exception '例外発生時 Result = False Finally 'バッファのクリア If SerialPort_Jyu Is Nothing Then Else SerialPort_Jyu.DiscardInBuffer() SerialPort_Jyu.DiscardOutBuffer() 'ポートが既に開かれている場合は閉じる If SerialPort_Jyu.IsOpen = True Then SerialPort_Jyu.Close() End If SerialPort_Jyu = Nothing End If End Try Next Catch ex As Exception '例外発生時 Result = False End Try Return Result End Function 'ポート2 Private Function Serial_Two() As Boolean Dim Result As Boolean = False Dim ENQ As Integer = &H5 'ENQ Dim NAK As Integer = &H15 'NAK Dim 安定計量値 As String = "1" Dim 不安定 As String = "0" Dim 計量範囲外 As String = "OV" Dim NAKStr As String = "NAK" Dim wkStr As String = "" Dim recvWeight As Double = 0 Dim RecvData As String = "" Dim IsRecved As Boolean = False 'シリアルポート2 Dim SerialPort_EMP As New SerialPort() Try Dim SerialPortIsOpen = False For recvTryCount As Integer = 1 To 5 Try 'シリアルポート SerialPort_EMP = New SerialPort() '------------------------------------ 'シリアルポートの設定 '------------------------------------ 'ポートを一度閉じる If SerialPort_EMP.IsOpen = True Then 'バッファのクリア SerialPort_EMP.DiscardInBuffer() SerialPort_EMP.DiscardOutBuffer() 'ポートが既に開かれている場合は閉じる SerialPort_EMP.Close() SerialPort_EMP = Nothing 'シリアルポート宣言 SerialPort_EMP = New SerialPort() End If 'ポートのオープン処理 SerialPort_EMP.PortName = "COM2" SerialPort_EMP.BaudRate = 9600 SerialPort_EMP.DataBits = 8 SerialPort_EMP.Parity = IO.Ports.Parity.Even SerialPort_EMP.StopBits = IO.Ports.StopBits.One SerialPort_EMP.ReadTimeout = 10000 SerialPort_EMP.WriteTimeout = 10000 SerialPort_EMP.Open() 'バッファのクリア SerialPort_EMP.DiscardInBuffer() SerialPort_EMP.DiscardOutBuffer() 'ポートフラグ設定 SerialPortIsOpen = True Dim _requestBytes As Byte() = Encoding.GetEncoding("shift-jis").GetBytes(Chr(ENQ)) 'シリアルポートから計量依頼を送信する.(ENQ送信) SerialPort_EMP.Write(_requestBytes, 0, 1) '受信するまで待機する RecvData = "" RecvData = SerialPort_EMP.ReadLine() '受信データ表示 Console.WriteLine(RecvData) Result = True Catch ex As Exception '例外発生時 Result = False Finally 'バッファのクリア If SerialPort_EMP Is Nothing Then Else SerialPort_EMP.DiscardInBuffer() SerialPort_EMP.DiscardOutBuffer() 'ポートが既に開かれている場合は閉じる If SerialPort_EMP.IsOpen = True Then SerialPort_EMP.Close() End If SerialPort_EMP = Nothing End If End Try Next Catch ex As Exception '例外発生時 Result = False End Try Return Result End Function

補足

コードは不要部分は削除しております。長いコードですが宜しくお願い致します。
なにか解決につながるヒントでもいいので宜しくお願い致します。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。