Author Topic: ModbusRTU Send Que Full  (Read 2472 times)

scott.clark

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
ModbusRTU Send Que Full
« on: March 05, 2015, 11:05:11 AM »
I have a Modbus device that gets powered off and back on, so when I want to communicate, I poll with a read instruction and have been using the exception "No Reponse from PLC. Ensure driver settings are correct." as an indication that  the modbus device is not powered on. 

I am guessing "Send Que Full" exception is a result of taking too long for the Modbus device to power up.  How can I Poll the modbus device while waiting for it to power up without filling up the send Que?

Thanks for the help!


Code: [Select]
Private Sub ModbusRTU_Control()
        Dim n_strMessage As String
        Dim n_strValueRead As String = Nothing
        Dim n_strValue5(4) As String
       
        Dim ModbusRTUComMainForm As New ModbusRTUCom
        ModbusRTUComMainForm.PortName = g_INIFIleSettings.ModbusRTUPortName
        ModbusRTUComMainForm.BaudRate = g_INIFIleSettings.ModbusRTUBaudRate

        Try
            Do While (g_ModbusRTURequestConnection)
                '******************************************
                '* Attempt to read values to validate ModbusRTU Connection
                '* Success indicates That ModbusRTU connection is established
                '* We read these particular registers because we need them anyway
                '******************************************

                Try
                    n_strValue5 = ModbusRTUComMainForm.Read("44120", 5)
                    g_ModbusRTU_Connnected = True

                Catch ex As Exception
                    g_ModbusRTU_Connnected = False
                    If ex.Message = "No Reponse from PLC. Ensure driver settings are correct." Then
                        n_strMessage = "Procedure MainForm:ModbusRTU_Control() failed with error" & vbCrLf & "XCM25D is not connnected or not powered"
                        ShowMessageBox(n_strMessage)

                    ElseIf ex.Message = "Unknown error code -1" Then
                        'I believe this error code is a result of DLL232_SerialCom not disposing quick enough before ModbusRTUComMainForm is used
                        g_ModbusRTURequestConnection = false

                    Else
                n_strMessage = ex.Message & "While Testing Connection"
                        ShowMessageBox(n_strMessage)
                    End If
                End Try

                Thread.Sleep(100)
               
          Loop

           
        Catch ex As Exception
            n_strMessage = ex.Message & " in Procedure ModbusRTU_Control()"
            ShowMessageBox(n_strMessage)
        End Try

        ModbusRTUComMainForm.Dispose()
    End Sub


Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5325
    • View Profile
    • AdvancedHMI
Re: ModbusRTU Send Que Full
« Reply #1 on: March 05, 2015, 12:33:32 PM »
The SendQue (sometimes referred to as a mailbox) holds the packets while they are transmitted one at a time and waits for a response. The ModbusRTU que holds a maximum of 50 packets. If there is no communications and requests continue to be added to the que, the que will rapidly fill up, then give the Send Que Full exception.

The timeout period is dependent on the baud rate, so let's say it calculates to 1 second. After each packet is sent, the driver will wait for 1 second for a response. So if packets are added to the que by a read or write faster than 1 second each while there is no established communications, the que will fill up.

Each driver instance handles it's own subscriptions and the subscriptions updates are only sent one at a time. So if you have 50 driver instances, it can fill the que. Or if you have less driver instances, but read/write in your own code then you can also fill the que.

If you start your application without communications, you can DisableSubscriptions in the driver until you know the driver has established communications.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5325
    • View Profile
    • AdvancedHMI
Re: ModbusRTU Send Que Full
« Reply #2 on: March 05, 2015, 01:50:08 PM »
I added a ConnectionEstablished event to the ModbusRTU driver. This will be part of version 3.98

scott.clark

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Re: ModbusRTU Send Que Full
« Reply #3 on: March 06, 2015, 07:16:16 AM »
I am using version 3.97d

I am starting the application without a ModbusRTUCom Driver.  In this application, I am testing a modbus devices.  When I need communcations with the modbus device, the above code is executed, when finished with testing,  the procedure exits and disposes the ModbusRTUComMainForm instance of ModbusRTUCom(This is the only Instance of ModbusRTUCom that is executed in this application).   Each time we execute the ModbusRTU_Control() procedure, it is likely there will be some packets that don't get replies. 

Does disposing the ModbusRTUComMainForm instance of ModbusRTUCom flush out the SendQue?  If not, what would?

Thanks!

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5325
    • View Profile
    • AdvancedHMI
Re: ModbusRTU Send Que Full
« Reply #4 on: March 06, 2015, 09:12:23 AM »
The Dispose should flush everything. I did correct a problem for the next version that I found that could have possibly not disposed the TransportLayer correctly, which would then hold the que.

How often does the subroutine execute? Is it possibly triggered by a multi-threaded app where that routine is called many times simutaneously? The Read that you are using is Synchronous, so it should hold at that line until it successfully reads or throws away the packet on a timeout.

scott.clark

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Re: ModbusRTU Send Que Full
« Reply #5 on: March 06, 2015, 06:01:28 PM »
The subroutine is in it's own thread and is only executed in this thread.
The subroutine, once started has a Do While Loop that runs until the public variable ("g_ModbusRTURequestConnection" becomes false, at which time the Loop exits and disposes the ModbusRTUCom instance.
The subroutine is called once every couple of minutes and runs for about 20 seconds before exiting.
The loop in the subroutine polls using the read instruction at 100ms per interval.

How long is the timeout?

The two exceptions I have observed are:
"No Reponse from PLC. Ensure driver settings are correct."
"Unknown error code -1"
 
I assume the first one is the result of the timeout.....does the second one make any sense?

Additonal info:
In the same thread that calls this ModbusRTU_Control() , there is another subroutine that uses the same COM port for a DLL that does a firmware update to the modbus device. It is called similarly and is disposed  prior to calling the ModbusRTU_Control() subroutine.  I found that I had at add a 500mSec wait time before calling the  ModbusRTU_Control() sub to insure the COM port was available.


Thanks!

scott.clark

  • Jr. Member
  • **
  • Posts: 96
    • View Profile
Re: ModbusRTU Send Que Full
« Reply #6 on: March 10, 2015, 10:40:56 AM »
I am getting the following exception when executing the ModbusCom Read:

"Unknown error code -1"

What does it mean?

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5325
    • View Profile
    • AdvancedHMI
Re: ModbusRTU Send Que Full
« Reply #7 on: March 10, 2015, 06:26:49 PM »
Some critical fixes were made to the Modbus drivers. These fixes are part of the new version 3.98. Try that version to see if you still have the problem.