Menu

EasyModbusTCP.NET 5.0 - IOExceptions

2018-04-28
2022-04-24
  • Scott Mongrain

    Scott Mongrain - 2018-04-28

    Hello!

    I am trying to use EasyModbusTCP v5.0 in my (fairly ambitious) project to connect to multiple slave devices and read/write values from/to them in a control loop as a Modbus master device. I'm writing the code in VisualBasic.NET. At present, I'm using your EasyModbusTCP Server Simulator v5.0 as my "slave device" under test before moving on to the real thing.

    Problem

    At the moment, I cannot get it to run for more than about 15-90 seconds continuously without throwing exceptions:

    Exception 1:

    System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
    --- End of inner exception stack trace ---
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
    at EasyModbus.ModbusClient.ReadInputRegisters(Int32 startingAddress, Int32 quantity)
    at RTModbusControl.EnergyCell.ReadMeasurements() in C:\Users\Scott\source\repos\RTModbusControl\RTModbusControl\EnergyCell.vb:line 66

    Exception 2:

    System.IO.IOException: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall. ---> System.Net.Sockets.SocketException: A blocking operation was interrupted by a call to WSACancelBlockingCall
    at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
    --- End of inner exception stack trace ---
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
    at EasyModbus.ModbusClient.ReadInputRegisters(Int32 startingAddress, Int32 quantity)
    at RTModbusControl.EnergyCell.ReadMeasurements() in C:\Users\Scott\source\repos\RTModbusControl\RTModbusControl\EnergyCell.vb:line 66

    Code and Attempts to Fix

    I have tried to slow the loop down (one calling timer event per 250 ms), and only execute one block of read or write calls at a time, but I can't seem to get it to work consistently. I am instantiating clients (one for each device) as:

    ...
    connection.Client = New ModbusClient(ip, CType(port, Integer)) With {
      .UnitIdentifier = CByte(id),
      .ConnectionTimeout = 249
     }
     ...
    

    I then add this connection class instance to an EnergyCell class instance as CellConnection, which is what I use later. ip is a string containing the user-defined IP address of the device, which at present is set to the loopback (127.0.0.1), while port is set to another user-defined value (in this case, 502).

    I am reading or writing single registers, one after another with (for example):

    Public Sub ReadMeasurements()
        Dim registerAddresses As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9}
        Dim wordResult As Integer() = {0}
        Dim powerAngle As Double
    
        For Each a In registerAddresses
            If Not CellConnection.Client.Connected Then
                CellConnection.Client.Connect(CellConnection.Client.IPAddress, CellConnection.Client.Port)
                Working = True
                Try
                    wordResult = CellConnection.Client.ReadInputRegisters(a - 1, 1)
                Catch e As Exception
                    Console.WriteLine(e.ToString())
                End Try
            ElseIf CellConnection.Client.Connected Then
                Working = True
                Try
                    wordResult = CellConnection.Client.ReadInputRegisters(a - 1, 1)
                Catch e As Exception
                    Console.WriteLine(e.ToString())
                End Try
            End If
    
            Select Case a
                Case 1
                ...
    

    I proceed to perform some calculations on the measured values. There are also subroutines for writing values to the device registers and reading those values in the case of local control (i.e. if the device has a DSP connected to it). Each of them has an equal chance of throwing the exceptions, and it just seems to occur at random after some period of time. Everything works wonderfully until the exceptions start. Once that happens, no further communication occurs between my program and the Server Simulator and I cannot reconnect. I have tried using .Disconnect() and then .Connect() in the Catch block to no avail.

    I read through all the discussions here (even those which were not pertinent to my issue) and noticed that this has come up before. You may notice that I am setting UnitIdentifier to a value other than zero (specifically, a value entered by the user). This is because one application of this software will be to connect to multiple simulated devices running in the same OpalRT server, which has only one IP address, but each device will have its ID (slave address) set uniquely. The software running on the server, RT-LAB, is capable of implementing Modbus and allows each device to have a distinct address (as per the specification for the protocol's ADU over TCP).

    I have another form for testing the connection and Modbus function codes, and I can run as many tests as I'd like there, since they are single read/write calls with no automation; I have to press a button to read or write. This form works properly in RT-LAB as well, and seems to correctly address each device via the UnitIdentifier, reading or writing as commanded to the appropriate registers.

    I have a feeling I'm either overworking the Server Simulator or I'm abusing the NetworkStream, but I'm not sure. To that end, I've also tried using function codes FC03, FC04, and FC16, which seem to work well (for at least 10 minutes at a time, no exceptions), but I'd really like to be able to update values one at a time instead of in bulk if possible. I'd appreciate any guidance or assistance you can provide!

     
  • Aaron Pace

    Aaron Pace - 2018-08-14

    I'm having the same issue. Any headway on this error?

     
    • Anonymous

      Anonymous - 2018-08-16
      Post awaiting moderation.
    • Anonymous

      Anonymous - 2018-08-16
      Post awaiting moderation.
    • Scott Mongrain

      Scott Mongrain - 2018-08-16

      Somehow managed to get myself logged out prior to posting those two replies, and didn't notice. The gist of the problem was "helicopter parenting" the connection, and mistakes in the interpretation of signed/unsigned integers. I also started using the FC03, 04, and 16 functions.

       
      • Anonymous

        Anonymous - 2018-09-05
        Post awaiting moderation.
      • Anonymous

        Anonymous - 2020-04-20
        Post awaiting moderation.
      • abx qwq

        abx qwq - 2022-04-19

        Hi Scott, I have the same issue. Did you resolve this ?

         
        • Scott Mongrain

          Scott Mongrain - 2022-04-24

          Yes. Connections (and thus, clients) are cheap; abandon them at the earliest sign of trouble. That means using Try...Catch where you should toss the connection in the Catch block as basically the only action (don't try to resolve anything, it's useless and more effort than it's worth), abandoning it after any latency longer than you'd like, also after a malformed response, etc. Basically just constantly remake clients/connections (they're more or less one and the same) and everything works perfectly. From there you can assess what things you'd actually like to try to accommodate/fix, but start with just tossing everything at the slightest sign of trouble and you'll be encouraged by how well the results bear out. I know I was!

          You can see the full program here.

           
          • Anonymous

            Anonymous - 2022-07-06
            Post awaiting moderation.
  • Anonymous

    Anonymous - 2021-07-15
    Post awaiting moderation.
  • Anonymous

    Anonymous - 2023-10-02
    Post awaiting moderation.

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.