tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^2: シリアル通信で異常に時間がかかってしまう
投稿日: 2010/01/26(Tue) 17:36
投稿者ぽると
GODさん
アドバイスありがとうございます。

> とりあえずDoEventsは使用しない方が良いですよ。

ご指摘のとおり、Unload 後に勝手にロードされる問題はありました。
強引ですが、全ての内部タイマーやオブジェクトを解放後に End で終了するようにしています。

> PC1側のプログラムにはコマンドのリトライ制限はないのですか?また、リトライ処理があるなら正しく動作していますか?(コマンド送出タイミングと回数)
> PC2側がわざと応答を返さない時(全コマンドで実験?)は正しく動作してるかな?

PC1とPC2の通信は  TCP/IP  による通信のみで、特にリトライ制限等は設けていません。
PC2側がなんらかの原因でPC1側に応答を返さない場合、PC1側で、異常と判断して知らせる形になっています。

システム構成について、もう少し全体の構成を説明しますと、
PC1を統括用として、そこから命令を受け取り、各装置に命令を送信するPCが複数あります。
PC1と各制御用PCは  TCP/IP  にて装置状態やコマンドをやりとりして、
制御用PCと装置は  シリアル通信  にて通信しています。

(図)
統括用PC        装置用PC
PC1      ⇔  PC2      ⇔ 装置2
            ⇔  PCX      ⇔ 装置X
            ⇔  PCY      ⇔ 装置Y
            ⇔  PCZ      ⇔ 装置Z
            ↑              ↑
        TCP/IP通信      シリアル通信

追記になってしまい恐縮ですが、通信関係のイベントの一覧をまとめました。
通信部分のみを抜粋しています。

'// ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆
'//     PC1( TCP通信タイマー と TCPコントロール )
'// ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆
'// --------------------------------------------------
'//     TCP通信タイマー
'// --------------------------------------------------
Private Sub timerTcp_Timer()
    ' .Interval は 100ms
    timerTcp.Enabled = False         ' タイマー停止
    
    With tcpControl                  ' TCP/IP 通信
        .Timeout = 3000
        
        ' 切断されている時は再接続処理
        If (.State <> tcpConnected) And (.State <> tcpConnecting) Then
            Call .Connect( <PC2>, <通信ポート> )
        End If
        
        Select Case .State
            Case tcpConnected       ' 接続状態ならコマンド送信
                Call .Send( <コマンド文字列> )
            Case tcpClosed, tcpClosing
            Case tcpConnecting
        End Select
    End With
    
    timerTcp.Enabled = True          ' タイマー再開
End Sub

'// --------------------------------------------------
'//     TCP コントロール処理
'// --------------------------------------------------
Private Sub tcpControl_State()
    <接続状態の表示を更新するだけなので省略>
End Sub

Private Sub tcpControl_Receive()
    With tcpControl
        .Timeout = 0
        Call .Receive(mstrBuffer)   ' mstrBuffer は Public 変数
                                    ' 状態判定等の処理は別関数で処理
        .Timeout = 3000
    End With
End Sub

Private Sub tcpControl_Error(ByVal Number As DartSockCtl.ErrorConstants, ByVal Description As String)
    With tcpControl
        .Timeout = 0
        
        If (.State <> tcpClosed) And (.State <> tcpClosing) Then
            Call .Close
        End If
    End With
End Sub

'// ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆
'//     PC2( シリアル通信タイマーと MsComm、Winsock )
'// ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆
Private Sub timerComm_Timer()
    ' .Interval は 100ms
    <前述したシリアル通信処理>
End Sub

Private Sub winsockDaemon_ConnectionRequest(ByVal requestID As Long)
    With winsockClient
        If .State <> sckClosed Then .Close
        .LocalPort = 0
        .Accept requestID
    End With
End Sub

Private Sub winsockClient_DataArrival(ByVal bytesTotal As Long)
    Dim lstrBuffer              As String
    
    winsockClient.GetData lstrBuffer
    
    If (winsockDaemon.State <> sckListening) And (winsockDaemon.State <> sckClosed) Then
        winsockDaemon.Close
    End If
    winsockDaemon.Listen
    
    If (winsockClient.State <> sckConnected) And (winsockClient.State <> sckClosed) Then
        .Close
    End If
End Sub

Private Sub winsockDaemon_Error( <省略> )
    If WinsockDaemon.State <> sckClosed Then .Close
End Sub

Private Sub winsockClient_Error( <省略> )
    If winsockClient.State <> sckClosed Then .Close
End Sub

以上のようなつくりになっています。
DoEvents 方式を排除してしまうのが一番だとは思うのですが、
装置毎に個別のPGがあり、Comm用クラスも個別にカスタマイズが入っているようで、
なんとか最小の変更で対応できないものかと苦心しています。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。