AdvancedHMI Software

General Category => Support Questions => Topic started by: thug_ on March 02, 2017, 05:06:43 AM

Title: High CPU usage ?
Post by: thug_ on March 02, 2017, 05:06:43 AM
Hi All,

I am running application which is reading 17 registries from PLC every 100ms. PLC type is Allen Bradley MicroLogix 1200, and I am using Serial to USB connection with PLC. I am using SerialDF1forSLCMicroCom driver form AdvancedHMI, and BeginRead method for reading those registries.

When I run application my CPU usage is around 15- 20% which is little bit high for what I need. I ran performance profiler from red gate on it and it is showing that AdvancedHMIDrivers.S erialDF1forSLCMicroCom.OnDataReceived (PlcComEventArgs e) is "hot" and taking 34,5% time with children. It is everything running in WPF app.

Any suggestion how I could decrease usage of CPU?

Thanks


Title: Re: High CPU usage ?
Post by: Archie on March 02, 2017, 05:25:10 AM
Temporarily comment out your code in the DataReceived event handler and see what effect that has.
Title: Re: High CPU usage ?
Post by: thug_ on March 02, 2017, 05:31:38 AM
In that event handler I am assigning all values, which will later on be passed to UI, so basically nothing is happening if I comment out that part of code, I did and I run app, as it is expected CPU = 0, but I am not reading anything from PLC in that case.
Title: Re: High CPU usage ?
Post by: Archie on March 02, 2017, 07:48:58 AM
I'm not sure if I understand fully when you say you are not reading anything from the PLC.....Are you calling the BeginRead in the DataReceived event handler?
Title: Re: High CPU usage ?
Post by: thug_ on March 02, 2017, 08:57:54 AM
          public SerialDF1forSLCMicroCom m_plc = new SerialDF1forSLCMicroCom();
          public event EventHandler<CameraResultsEventArgs> ResultsAvailable;
          System.Windows.Threading.DispatcherTimer plcPoll = new System.Windows.Threading.DispatcherTimer();
           public void Read()
           {
           
            m_plc.Write("N7:0", "100");
            m_plc.Write("N7:14", "100");
            m_plc.Write("N7:15", "100");
            m_plc.Write("N7:16", "100");
            plcPoll.Interval = TimeSpan.FromMilliseconds(100);
            plcPoll.IsEnabled = true;
            plcPoll.Tick += plcPoll_Tick;
            m_plc.DataReceived += m_plc_DataRecieved;
            plcPoll.Start();
        }

        void plcPoll_Tick(object sender, EventArgs e)
        {
            m_plc.BeginRead("N7:0", 17);
            //m_plc.BeginRead("C5:0.ACC", 7);
         
        }

        void m_plc_DataRecieved(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e)
        {
            CamCollection values = new CamCollection();

            try
            {
                if (e.PlcAddress == "N7:0" && e.Values.Count == 17)
                {
                    values.Camera1.Trigger = e.Values[0];
                    values.Camera1.CurInspectionTime = e.Values[4];
                    values.Camera1.MaxInspectionTime = e.Values[3];

                    values.Camera2.Trigger = e.Values[14];
                    values.Camera2.MaxInspectionTime = e.Values[6];
                    values.Camera2.CurInspectionTime = e.Values[7];

                    values.Camera4.Trigger = e.Values[16];
                    values.Camera4.CurInspectionTime = e.Values[13];
                    values.Camera4.MaxInspectionTime = e.Values[12];

                    values.Camera3.Trigger = e.Values[15];
                    values.Camera3.CurInspectionTime = e.Values[10];
                    values.Camera3.MaxInspectionTime = e.Values[9];

                    if (ResultsAvailable != null)
                        ResultsAvailable(this, new CameraResultsEventArgs { Camera1 = values.Camera1, Camera2 = values.Camera2, Camera3 = values.Camera3, Camera4 = values.Camera4 });

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Error reading nValues: {0}", ex.ToString()));
                plcPoll.Stop();
            }


That's the part of code where is reading done.
Title: Re: High CPU usage ?
Post by: Archie on March 02, 2017, 09:02:07 AM
Try just commenting out this line to see what effect it has on CPU usage:

 if (ResultsAvailable != null)
                        ResultsAvailable(this, new CameraResultsEventArgs { Camera1 = values.Camera1, Camera2 = values.Camera2, Camera3 = values.Camera3, Camera4 = values.Camera4 });
Title: Re: High CPU usage ?
Post by: thug_ on March 02, 2017, 09:26:06 AM
It decreased but it is still around 7- 10..
Title: Re: High CPU usage ?
Post by: Archie on March 02, 2017, 09:31:00 AM
Are you only calling Read a single time. If it is called more than once, you will accumulate these timers because the only time plcPoll is stopped is during an exception.

Also have you tried using subscriptions with PollRateOverride set to 100 to let the driver handle the updates using it's own background thread?
Title: Re: High CPU usage ?
Post by: thug_ on March 02, 2017, 10:16:36 AM
No I am just calling once when btnRead is pressed, that is the part of code when is happening :

  private void btnReadPlc_Click(object sender, RoutedEventArgs e)
        {
            _wp = new WriteReadPlc();
            //_draw.DrawDynamicGraph();
            _wp.ResultsAvailable+=wp_ResultsAvailable;
            try
            {
                Task.Factory.StartNew(() => {
                    _wp.Read();                 
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Error reading from PLC"));     
            }
}

I tried to use subscriptions but I don't how to read 17 registries, with subscription, do I need to create for every registry one subscription, or there is some way to read all of them with one subscription ?

Title: Re: High CPU usage ?
Post by: Archie on March 02, 2017, 02:27:58 PM
What version of AdvancedHMI are you using? Various sub-versions of 3.99 have fixed issues related to asynchronous reading and high CPU usage. Although I do not think any of them will pertain to what you are seeing.

According to your code, each time the button is clicked, you will launch another thread with a timer that will add more reading. So a second click will then read 17 values every 50ms.

A subscription can read 17 values by specifying the number of elements in the subscribe call.
Title: Re: High CPU usage ?
Post by: thug_ on March 03, 2017, 04:33:51 AM
As I said I tried with subscription but I couldn't make to work

   //subscriptionTime = m_plc.Subscribe("N7:", 17, 100, plc_GigeOneDataRecieved);

This the line of code how I was trying to do, later in plc_GigeOneDataRecieved I was just assigning values to my variables. But I could get this work only when I read 1 element, so instead of 17 if I give 1 as numOfElements, it was working but 17 no. I am using 3.9.9.17 version of AdvancedHMI, later today I will try to get newset version and try again with subscribtions.
Title: Re: High CPU usage ?
Post by: bachphi on March 03, 2017, 12:58:33 PM
try N7:0

But I would use a Bool bit to trigger your subscribe, then in DataChanged event , do a beginread (ex. PLC.BeginRead("Sta03Data[0]", 17)),

then catch returned values in DataReceived event with

If e.PlcAddress = "Sta03Data[0]" Then

            _serialNumber = e.Values(0)
            _pressure = e.Values(1)
            _flow = e.Values(2)
Title: Re: High CPU usage ?
Post by: thug_ on March 03, 2017, 08:41:37 PM
I tried N7:0 as well but I just get a value for N7:0 others I am not getting. I didn't understand the part with bool bit to trigger subscribe, can you just give an example with code it will be easier for me to understand.

Thanks.
Title: Re: High CPU usage ?
Post by: Archie on March 03, 2017, 08:46:57 PM
I tried N7:0 as well but I just get a value for N7:0 others I am not getting. I didn't understand the part with bool bit to trigger subscribe, can you just give an example with code it will be easier for me to understand.
When your DataReceived event fires, is there only 1 element in e.Values ?
Title: Re: High CPU usage ?
Post by: thug_ on March 03, 2017, 10:53:38 PM
Yes Archie it is only 1 element in e.Values, when DataRecived event fires.
Title: Re: High CPU usage ?
Post by: Archie on March 04, 2017, 08:43:52 AM
Yes Archie it is only 1 element in e.Values, when DataRecived event fires.
This has been confirmed as a bug in the driver. A patch has been made to fix this issue. You can download the  V399v Patch 1 from here:

https://sourceforge.net/projects/advancedhmi/files/advancedhmi/3.5/Patches
Title: Re: High CPU usage ?
Post by: thug_ on March 04, 2017, 11:58:07 AM
Thanks Archie, I suppose I will just replace MfgControl.AdvancedHMI.Drivers.dll in my project with this from the patch ?

Unfortunately I won't be able to test it before Wednesday next week, so I will get back with results next week.

Cheers.
Title: Re: High CPU usage ?
Post by: Archie on March 04, 2017, 12:07:52 PM
Thanks Archie, I suppose I will just replace MfgControl.AdvancedHMI.Drivers.dll in my project with this from the patch ?
Yes, you replace the file found in AdvancedHMIDrivers\support
Title: Re: High CPU usage ?
Post by: thug_ on March 10, 2017, 09:20:26 AM
Thanks Archie it is working, my CPU usage is now around 7-12%, is that too high by your opinion ?
Title: Re: High CPU usage ?
Post by: Archie on March 10, 2017, 09:25:06 AM
Thanks Archie it is working, my CPU usage is now around 7-12%, is that too high by your opinion ?
It really depends on your system. But from my experience it is very high. I have run applications with dozens of items on a page with a PollRateOverride of 0 (giving a 6ms refresh) and the CPU still never exceeded 5% on moderate systems.
Title: Re: High CPU usage ?
Post by: Archie on March 10, 2017, 09:31:08 AM
You may want to do a Wireshark capture to see what is really happening on the communications which may reveal issues in your code.
Title: Re: High CPU usage ?
Post by: thug_ on March 10, 2017, 08:30:32 PM
Ok Archie thanks for advice I will try wireshark as well sometimes during next week and I will post results.

Thanks so much for your support.