Author Topic: Driver slowing to a halt - almost  (Read 2912 times)

Chipprogr

  • Newbie
  • *
  • Posts: 10
    • View Profile
Driver slowing to a halt - almost
« on: June 20, 2016, 03:32:27 PM »
Hi Team, I have a question. I am assigning a driver via code, Im not dragging it from the toolbox and dropping it on the form. I am using a backgroundworker to keep the driver's read/writes off the User Interface thread so that in the event of a problem communicating, it doesn't drag the UI to a dead halt.    What is happening, however, is that my read/write cycle starts off at about 33ms to complete a pass and within an hour its at 200ms and then over a few hours it gets to 0.5 seconds to complete a pass of the routine. Below is some example code , there are probably 30 read/writes that take place in total per pass. It just gets slower and slower. Any idea on whats going on? Memory leak of some sort?

Public PLCDriver As AdvancedHMIDrivers.EthernetIPforMicro800Com
PLCDriver = New AdvancedHMIDrivers.EthernetIPforMicro800Com(components)
-code example

 Do While True
      If PLC_IO_Write.bNewHour Then
        PLC_IO_Write.bNewHour = False
        PLCDriver.Write("PlateCnt_PerHr_Tick", "1")
      End If
     System.Threading.Thread.Sleep(0)

loop

Thanks -Eric

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Driver slowing to a halt - almost
« Reply #1 on: June 20, 2016, 05:01:11 PM »
When adding controls and components to the form in designer, Visual Studio and the Form class implicitly takes care of several tasks. One task is checking whether a class implements Iinitialize. If it does, VS adds code to call BeginInit and EndInit. Another item it does is call dispose on an item if it implements IDisposable.

The drivers implement IDisposable and if dispose is not called, it will not be able to release all of its resources.

If you're objective is to avoid using the main UI thread, there are several methods to do this. As you discovered the Read and Write methods will hold until the command is completed. There is also 2 other commands that do not block, these are BeginRead and BeginWrite.

BeginRead and BeginWrite comes with a risk. Since the driver can processor commands several magnitudes faster than the PLC can process and respond to them, the driver must use a queue which is 30 items deep. A BeginRead or BeginWrite takes about 0.1ms to process. A PLC typically takes between 5 and 20ms to process a command. So if you have a loop calling BeginWrite, within 3ms you can fill tyhe queue which is faster than the PLC can process even the first command. So it is up to the user to properly throttle BeginRead and BeginWrites to ensure it doesn't fill the queue.

Another approach, which you are implementing is to use a secondary thread and use the Write so the driver throttles the commands. This is a perfectly acceptable method, but it is not the most efficient to create a new instance of the driver. You can use a driver instance that was added to the form.

In your code that is running on a background thread, are you positive you are not creating multiple background threads that stay in the loop? You can check this by pausing your application in VS, then dropping down the list of threads to see how many there are.

Also a continuous loop that has no exit path or "rest" period is not the most efficient. The preferred and more efficient method is to use a System.Threading.EventWaitHandle

The EventWaitHandle will hold a thread without maxing out a threads CPU time and release when told to. This is an example of how to use it:

Code: [Select]
   Private HoldRelease As New System.Threading.EventWaitHandle(False, Threading.EventResetMode.AutoReset)
   Private ExitThread as boolean


--------------- Your Background worker thread
Do while Not ExitThread
   HoldRelease.Reset
   HoldRelease.waitone(5000)
   If PLC_IO_Write.bNewHour Then
        PLC_IO_Write.bNewHour = False
        EthernetIPforMicro800Com1.Write("PlateCnt_PerHr_Tick", "1")
    End If
End While


--------- Another area of your code
If PLC_IO_Write.bNewHour Then
    HoldRelease.Set
End If

stix

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Driver slowing to a halt - almost
« Reply #2 on: June 21, 2016, 12:34:43 PM »
I have had a similar issue reassigning PLC Addresses - I have tried to do this both with the driver on the form and also creating it programatically : I have 180 objects on the form using BasicLabel , I change the PLC Address through an Iteration and use FindControl(controlName,true) on each control I then set the PLCAddress . This works to some extent - if I do this 3 times in a row it can choke, sometimes it will do 12 times, So if you imagine a UDT in the Compact Logix PLC  'MySystem01.ValueTag'  where I change to 'MySystem02.ValueTag' and so on for 12 different components. I simply reassign all 180 objects on the screen to the new Address.  This works for a few times and then slogs down and locks my UI, I wait and wait a bit and then my UI comes back, and I can change and change and then slog even half way through.

Code: [Select]
    Private Sub ReAssignPLCAddress(planningClass As String, Is_ReadOnly As Boolean)
        IsReadOnly = Is_ReadOnly
        tblPlan.SuspendLayout()
        Dim element As Integer = 0
        Dim total As Integer = tblPlan.RowCount - 1
        For element = 0 To total
            Dim rowIndexer As String = "[" + element.ToString() + "]."
            For gutters As Integer = 1 To 4
                Try
                    Dim num As String = gutters.ToString()
                    Dim gutterTag As String = "Length_Cog_" + num + "_Inches"
                    Dim plcPath As String = planningClass + rowIndexer + gutterTag
                    Dim tempLabel As BasicLabel = New BasicLabel()
                    Dim ctrlX As Control() = tblPlan.Controls.Find(element.ToString() + gutterTag, True)
                    Dim ctrl As Control = ctrlX(0)
                    If Not ctrl Is Nothing Then
                        If ctrl.GetType() Is GetType(AdvancedHMIControls.BasicLabel) Then
                            tempLabel = ctrl
                            tempLabel.PLCAddressValue = plcPath
                            If IsReadOnly Then
                                tempLabel.PLCAddressKeypad = ""
                            Else
                                tempLabel.PLCAddressKeypad = plcPath
                            End If
                        End If
                    End If
                Catch ex As Exception
                    Dim err As String = ex.ToString()
                End Try
            Next
        Next
        tblPlan.Update()
    End Sub

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Driver slowing to a halt - almost
« Reply #3 on: June 22, 2016, 01:54:30 PM »
I did some testing with ModbusTCPCom and a simulator and everything worked as expected. This evening I will try it with a CompactLogix.

When you see this slow down, have you checked Task Manager to see if CPU usage has increased or memory usage keeps growing?

Chipprogr

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Driver slowing to a halt - almost
« Reply #4 on: June 28, 2016, 11:24:00 AM »
hi,
   Come to find out, even if I build a simple application only using the 'drag to form driver' and built in controls, after a day or so, the system needs to shut down and restart to become responsive again. After a while - a few hours, the task manager shows memory usage increase and then it dumps about 100meg from the memory usage and the application continues to slow down. Ive used your program before with great luck on other processors, this 800 series micro is not playing so nice.

Thanks for any help you can provide.

-Eric

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Driver slowing to a halt - almost
« Reply #5 on: June 28, 2016, 03:38:36 PM »
The Micro800 driver is actually the exact same driver as for the EthernetIPforCLX with just a couple property settings different. Are you using the latest version 3.99k ?

Chipprogr

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Driver slowing to a halt - almost
« Reply #6 on: June 29, 2016, 07:08:00 PM »
HI Archie,

   I had success and failure.. The version I was using was 399d.. I copied in the 399k code and made the necessary adjustment to the commComponent naming. The version k driver is working great and does not build up over time ; however... I have a couple forms that have controls on them. Identical except that I am switching between a few PLC's  (micro 800's) and those controls had  a dedicated driver  on the form. I would reassign the ipaddress and the controls would follow to the new PLC just fine. Now that is broken. When I switch ipaddress, the controls will show a correct value but immediately stop reading. They retain that value but never update again. I have also noticed that If i use 2 of the same drivers on different forms, addressed to 1 single PLC, they conflict with each other (unique naming for each)  , that also previously worked.

Any ideas? Thank you so much for your product and for your support.
-Eric

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Driver slowing to a halt - almost
« Reply #7 on: June 29, 2016, 07:36:11 PM »
I don't have multiple Micro800's so I am unable to test the changing of IP Addresses.

I did test multiple driver instances on both the same form and on a second form, but unable to reproduce any issues.

When you say they conflict, what are you seeing?

Chipprogr

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Driver slowing to a halt - almost
« Reply #8 on: June 29, 2016, 08:32:04 PM »
Hi , I realized after posting that I needed to clarify. I have several drivers that are programmatically Assigned with different ip addresses. I am only changing the comComponent of the controls. In version 399d it worked great, k is broke in this way. What I'm seeing is error messages on the controls. They say things like 'unable to connect to plc(22)' and stuff about index is outside of the bounds, and something about non-negative numbers. I'm away from the Plc at the moment so this is from memory. It's like the drivers are conflicting if they are assigned the same ip. Example - 2 meters with 2 drivers - same ip. They will error ever so often. Version 399d didn't but it's unusable because of the memory / thread issue causing it to slow down and lock up. Hope this helps. Il know more in the morning.

Thanks-eric

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Driver slowing to a halt - almost
« Reply #9 on: June 29, 2016, 08:52:59 PM »
There was a recent problem found with the controls when changing the ComComponent property. See the last post in this thread:

http://advancedhmi.com/forum/index.php?topic=1352.msg7173#msg7173