Author Topic: ModbusTCPCOM Timeout Issue  (Read 1064 times)

Andrew.Lenzo

  • Newbie
  • *
  • Posts: 6
    • View Profile
ModbusTCPCOM Timeout Issue
« on: June 18, 2019, 04:30:58 PM »
Hello,

I have a class called "Signal" setup as follows.
Code: [Select]
Public Class Signal 'class with properties of signal. Links ModbusTCP/IP driver to memory bit adresses for power and color

    Dim _Connection As AdvancedHMIDrivers.ModbusTCPCom
    Dim _PWRaddress As String 'memory bit address of power control relay
    Dim _CLRaddress As String  'memory bit address of color control relay

    Public Property Connection() As AdvancedHMIDrivers.ModbusTCPCom
        Get
            Return _Connection
        End Get
        Set(value As AdvancedHMIDrivers.ModbusTCPCom)
            _Connection = value
        End Set
    End Property

    Public Property PWRaddress As String
        Get
            Return _PWRaddress

        End Get
        Set(value As String)
            _PWRaddress = value

        End Set
    End Property
    Public Property CLRaddress As String
        Get
            Return _CLRaddress
        End Get
        Set(value As String)
            _CLRaddress = value
        End Set
    End Property

    Public Sub WriteCLR(ByVal WriteValue As Integer)
        _Connection.Write(_CLRaddress, WriteValue) 'writes to signals color address
    End Sub

    Public Sub WritePWR(ByVal WriteValue As Integer)
        _Connection.Write(PWRaddress, WriteValue) 'writes to signals power address
    End Sub
End Class

I have initialized 40 "signals" on load in the main form as "signal1", "signal2", etc. I then added these signals to various object arrays which groups them together and allows me to write to that group using a single button click by looping through all of the signals in that groups array. This works fine except when connection is lost to one of the ModbusTCP drivers. If I disconnect one of the PLCs, the program seems to freeze as it trys to connect to the PLC for every signal in the array.

I am wondering if there is a way to access the status of the Modbus connection and move on the the next object in the array if it is not active or not able to ping that PLC. Any help would be greatly appreciated.

Thanks,

Andrew


Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: ModbusTCPCOM Timeout Issue
« Reply #1 on: June 18, 2019, 04:38:46 PM »
The Write function is synchronous, so it will hold your code until either a response or a timeout.

You need to either run it on a background thread or use BeginWrite. With BeginWrite it is up to you to ensure you do not flood the buffer.

Andrew.Lenzo

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: ModbusTCPCOM Timeout Issue
« Reply #2 on: June 19, 2019, 07:49:20 AM »
Thank you for your reply Archie. I've never done asynchronous programming before so this may be a good opportunity to learn! Seems simple enough but I'm still trying to get my head around whats happening when I am creating tasks and how to pass info to them. Also, can I create the tasks/threads in my object method or do I need to do that when the main form calls it?

I noticed that there is a function that returns a Boolean called IsSubscriptionActive(). Would it be possible to test the ModbusTCP connection before calling the write function using this? something like

Code: [Select]
if ModbusTCPCOM1.IsSubscriptionActive()
     ModbusTCPCOM1.Write(...)
else
     MSGBox("Com1 is not active")
end if



Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: ModbusTCPCOM Timeout Issue
« Reply #3 on: June 19, 2019, 10:46:44 AM »
The IsSubscriptionActive method is used to determine if a subscribed item still exists or has it been unsubscribed.

Keep in mind if a PLC disconnects the only way to know is by sending a request wand waiting for timeout. The same applies with connection. TCP does not give a disconnection event unless the device is gracefully disconnecting.

Your best chance is using ConnectionEstablish, ConnectionClosed, and ComError events.

if you use BeginWrite, it will not hold up your code and if it is unsuccessful it will fire the ComError event.

Andrew.Lenzo

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: ModbusTCPCOM Timeout Issue
« Reply #4 on: June 19, 2019, 11:29:10 AM »
Thanks this is very informative! I have resolved the freezing issues by running on background threads. It took a lot of googling but it turns out I just needed to use the threadpool and a lambda statements in the "signal" write methods as shown below. I still see a delay a reaction from the hardware as the background threads do their thing but the Main Form doesn't freeze which is fine for this project.
Code: [Select]
    Public Sub WriteCLR(ByVal WriteValue As Integer)
        System.Threading.ThreadPool.QueueUserWorkItem(Sub() _Connection.Write(_CLRaddress, WriteValue)) 'writes to signals color address
    End Sub

    Public Sub WritePWR(ByVal WriteValue As Integer)
        System.Threading.ThreadPool.QueueUserWorkItem(Sub() _Connection.Write(PWRaddress, WriteValue)) 'writes to signals power address
    End Sub

My next task is to add a network connection diagram to the HMI which will involve changing the color of some lines based on the connection status of the PLCs. It sounds like the ConnectionEstablished, ConnectionClosed, and ComError events may be exactly what I need to do that.

Thanks Archie!