Menu

Problem with reconnect to Cp243-1

Help
2009-07-21
2013-05-09
  • Nobody/Anonymous

    Hello
    Thank for libnodave library.
    I've try to write program to connect to s7-200 wit CP243-1it thru ethernet with libnodave.
    I found example in VisualBasic 2005 how to use libnodave library.
    I use VisualaBasic 2008 Express.
    When there are no problem with communication everything works quick and fine.
    I have some problem:
    I have right communication with PLC and  I (for example) remove from PLC ethernet cable and connect cable again, then  I can't get response from PLC even more.
    I  use my disconnect function and then connect function as described above
    When I execute my connect function
    from
    dc.connectPLC()
    I got result
    -1.
    The same effect is when with starting connection I start Connect function again.
    When I wait some time I can connect again properly.
    Another problem is when there are problem with communication function
    this line of code
      fds.rfd = libnodave.openSocket(102, IP)
    execute very long.

    With this problem my system isn robust, so I need help how to surely and quick reconnect.
    Thank you.

    To connect I have:
    Public Sub ISO_TCP()
            Dim IP As String
            IP = cbxIP.Text
            If IP <> "" Then 'Kontrolliert, ob der Bediener eine Eingabe gemacht hat
                fds.rfd = libnodave.openSocket(102, IP) 'Portstatus - lesen
                fds.wfd = fds.rfd 'Portstatus schreiben = Portstatus - lesen
                di = New libnodave.daveInterface(fds, "IF1", localMPI, _
                libnodave.daveProtoISOTCP243, libnodave.daveSpeed187k)
                di.setTimeout(1000000)
                res = di.initAdapter
                'dc = New libnodave.daveConnection(di, plcMPI, 2, 2)
                'res = dc.disconnectPLC
                If res = 0 Then       'initAdapter OK
                    ' Rack und Slot spielen keine Rolle bei diesem Protokoll
                    dc = New libnodave.daveConnection(di, plcMPI, 2, 2)
                    res = dc.connectPLC()
                End If
            Else
                MsgBox("Bitte Comport angeben", MsgBoxStyle.Information, "Fehler")
            End If   
        End Sub
    And below function to disconnect:

    Private Sub btnAbbau_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnAbbau.Click
            dc.disconnectPLC()
            di.disconnectAdapter()
            libnodave.closePort(fds.rfd)
            fds.rfd = 0
            res = 1
            di = Nothing
        End Sub

     
    • Nobody/Anonymous

      One of the problems you have is that Ethernet has a timeout of 20 seconds
      So when you have problems it will take about 20 seconds before the "fds.rfd = libnodave.openSocket(102, IP) " will go on.

      To get you connection working again you need to initiate the whole connection.
      So call the ISO_TCP sub again.

      My code (for a S7-300):
      'try to read MB0, just to see if the connection works)
            res = dc.readBytes(libnodave.daveFlags, 0, 0, 1, Nothing)
              If res = 0 Then
                 'Do the things you want when connected
              ElseIf res < 0 Then
                 'when less then 0 there is no connection.
                  Try
                      'Try to connect again
                      InitPlcCom()
                  Catch ex As Exception
                  End Try
              End If

          Protected Function InitPlcCom() As Boolean
              Dim retVal As Boolean
              Try
                  fds.rfd = libnodave.openSocket(102, sPLCip)
                  fds.wfd = fds.rfd
                  If fds.rfd > 0 Then
                      Application.DoEvents()
                      di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
                      di.setTimeout(1000)
                      Application.DoEvents()
                      dc = New libnodave.daveConnection(di, 0, rack, Slot)
                      Application.DoEvents()
                      If dc.connectPLC() = 0 Then
                          'LogInfo("Connected to PLC " + sPLCip)
                          retVal = True
                      Else
                          'LogError("Couldn't open tcp connection to " + sPLCip)
                          retVal = False
                      End If
                  End If
              Catch ex As Exception
                  ' Error("Couldn't open tcp connection to " + sPLCip)
                  retVal = False
              End Try
              Return retVal
          End Function

       
    • Nobody/Anonymous

      Thak you very much.
      It works very good.
      I'm still checking is the reconecting is sure, but till this time it works great.
      I execute your function periodicaly with Timer and set and reset one output on PLC so I can easy check communication.
      You've wrote:
      One of the problems you have is that Ethernet has a timeout of 20 seconds
      So when you have problems it will take about 20 seconds before the "fds.rfd = libnodave.openSocket(102, IP) " will go on.

      This what you wrote for me reconnect automaticly, but is there any possibiliteis to make recconection quicker, and without hanging on my applications?

      Once again thank you very much,
      have a nice weekend!

       
    • Nobody/Anonymous

      Well i dont know a way to make reconnection faster. the 20 seconds timeout comes from within windows, its the tcp/ip timeout.

      To make sure your app doesn't hang, you can make the connect functuion as a thread.  that way the app will go on, while the thread connects to the plc.

      Below is the code for the class i use to connect to a PLC. It has code to connect using a thread. And there is a second thread that can be started and stopped to communicate to the PLC, and it will detect if the connection is interrupted or not. Keep in mind that I modified the code, so only the usefull stuff is still in there.

      Good luck with your application,
      Leon.

      Imports System.Windows.Forms
      Imports System.Text
      Imports System.Globalization
      Imports System.Threading
      Imports System.Diagnostics

      Public Class clsPLCCommunicatie
          'Constants declarations
          Private Const rack As Integer = 0
          Private Const Slot As Integer = 2

          'Private declarations
          Private fds As libnodave.daveOSserialType
          Private di As libnodave.daveInterface
          Private dc As libnodave.daveConnection
          Private sPLC_IP As String
          Private bIsConnected As Boolean = False
          Private thdPLC_Watch As Thread = New Thread(AddressOf PLC_Com)
          Private thdConnectPlc As Thread
          Private _bQuit As Boolean

          Friend ReadOnly Property IsConnectedToPLc() As Boolean
              Get
                  Return bIsConnected
              End Get
          End Property

          Public Sub New()
          End Sub

          Friend Sub Dispose()
              _bQuit = True
              If Not thdConnectPlc Is Nothing Then
                  If thdConnectPlc.IsAlive Then
                      thdConnectPlc.Abort()
                      Do
                          Application.DoEvents()
                      Loop Until thdPLC_Watch.IsAlive = False
                  End If
                  thdConnectPlc = Nothing
              End If
              If Not thdPLC_Watch Is Nothing Then
                  Do
                      Application.DoEvents()
                  Loop Until thdPLC_Watch.IsAlive = False
                  thdPLC_Watch = Nothing
              End If
              Try
                  dc.disconnectPLC()
                  dc = Nothing
                  libnodave.closePort(fds.rfd)
              Catch ex As Exception
              End Try
          End Sub

          Friend Function ConnectPLC(ByVal sIPAdress As String) As Boolean
              sPLC_IP = sIPAdress
              InitCommunicatie()
              Return bIsConnected
          End Function
         
          Friend Sub startCommunication()
              Try
                  If thdPLC_Watch Is Nothing Then
                      thdPLC_Watch = New Thread(AddressOf PLC_Com)
                      thdPLC_Watch.TrySetApartmentState(ApartmentState.MTA)
                      thdPLC_Watch.Start()
                  End If
              Catch ex As Exception
              End Try
          End Sub
         
          Friend Sub StopCommunication()
              _bQuit = True
              If Not thdPLC_Watch Is Nothing Then
                  Do
                      Application.DoEvents()
                  Loop Until thdPLC_Watch.IsAlive = False
                  thdPLC_Watch = Nothing
              End If
          End Sub

          Private Sub InitCommunicatie()
              If IsValidIP(sPLC_IP) Then
                  If thdConnectPlc Is Nothing Then
                      thdConnectPlc = New Thread(AddressOf connectPLCthd)
                      thdConnectPlc.TrySetApartmentState(ApartmentState.MTA)
                      thdConnectPlc.Start()
                  End If
                  If Not thdConnectPlc.IsAlive Then
                      thdConnectPlc = Nothing
                  End If
              Else
                  bIsConnected = False
              End If
          End Sub
         
          Private Sub connectPLCthd()
              Try
                  fds.rfd = libnodave.openSocket(102, sPLC_IP)
                  fds.wfd = fds.rfd
                  If fds.rfd > 0 Then
                      di = New libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k)
                      di.setTimeout(1000)
                      dc = New libnodave.daveConnection(di, 0, rack, Slot)
                      If dc.connectPLC() = 0 Then
                          bIsConnected = True
                      Else
                          bIsConnected = False
                      End If
                  Else
                      bIsConnected = False
                  End If
              Catch ex As Exception
                  bIsConnected = False
              End Try
          End Sub
         
          Private Sub PLC_Com()
              Dim _Entry As plcEvent
              Dim res As Integer
              Do
                  If bIsConnected Then
                      Try
                          'Check communicatie, try to read mb0
                          res = dc.readBytes(libnodave.daveFlags, 0, 0, 1, Nothing)
                          If res = 0 Then
                              'connection is there, and read action succesfull
                          ElseIf res < 0 Then
                              bIsConnected = False
                          End If
                      Catch ex As Exception
                      End Try
                  Else
                      InitCommunicatie()
                  End If
                  Thread.Sleep(100)
              Loop Until _bQuit
          End Sub

          Private Function IsValidIP(ByVal addr As String) As Boolean
              'create our match pattern
              Dim pattern As String = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\." & _
              "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"
              'create our Regular Expression object
              Dim check As New System.Text.RegularExpressions.Regex(pattern)
              'boolean variable to hold the status
              Dim valid As Boolean = False
              'check to make sure an ip address was provided
              If addr = "" Then
                  'no address provided so return false
                  valid = False
              Else
                  'address provided so use the IsMatch Method
                  'of the Regular Expression object
                  valid = check.IsMatch(addr, 0)
              End If
              'return the results
              Return valid
          End Function   
      End Class

       

Anonymous
Anonymous

Add attachments
Cancel





Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.