Author Topic: Advanced HMI Subscribe is not working  (Read 2646 times)

JanVanDerZijden

  • Newbie
  • *
  • Posts: 2
    • View Profile
Advanced HMI Subscribe is not working
« on: August 05, 2014, 03:56:10 AM »
Hi guys,

I am getting a error when trying to subscribe. The m_Plc.Read functions is working perfectly, but is going too slow for my application.

this is my code:

    private AdvancedHMIDrivers.EthernetIPforCLXCom m_Plc;
   
    public MainPageViewModel()
    {
       m_Plc = new EthernetIPforCLXCom();
   
       m_Plc.IPAddress = m_IPAddress;
       m_Plc.ProcessorSlot = Convert.ToInt32(m_ProcessorSlot);
       m_Plc.ComError += DoOnCommError;
       m_Plc.SubscriptionError += DoOnCommError;
   
       string testString = m_Plc.Read("MyTag"); 
       int index = m_Plc.Subscribe("MyTag", 1, 2000, testPlcReaded);
    }
   
     private void testPlcReaded(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e)
     {
         try
         {
             Console.WriteLine(e.Values[0]);
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex);
         }
     }

and this is the error I am getting:

    m_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
wich is in the folder: EthernetIPforCLXCom.vb.

there is a null-pointer to m_SynchronizingObject.

Error-details: System.NullReferenceException was unhandled by user code
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=AdvancedHMIDrivers
  StackTrace:
       at AdvancedHMIDrivers.EthernetIPforCLXCom.DataLinkLayer_DataReceived(Object sender, PlcComEventArgs e) in C:\prj\TLLAB\TLLAB\AdvancedHMIBeta363 (1)\AdvancedHMIDrivers\EthernetIPforCLXCom.vb:line 1269
       at MfgControl.AdvancedHMI.Drivers.CIP.OnDataReceived(PlcComEventArgs e)
       at MfgControl.AdvancedHMI.Drivers.CIP.DataReceivedEIP(Object sender, PlcComEventArgs e)
« Last Edit: August 05, 2014, 04:37:43 AM by JanVanDerZijden »

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5324
    • View Profile
    • AdvancedHMI
Re: Advanced HMI Subscribe is not working
« Reply #1 on: August 05, 2014, 09:18:46 AM »
To use subscriptions, you have to set the SynchronizingObject property. This is set automatically when you add a driver to the form in the designer. It's purpose it to return data back on the same thread the form runs on so the user code can put the data directly on visual controls without a cross thread error.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5324
    • View Profile
    • AdvancedHMI
Re: Advanced HMI Subscribe is not working
« Reply #2 on: August 05, 2014, 09:27:44 AM »
I cannot test this right now, but try to modify EthernetIPforCLX.vb start at about line 1268 to see if this resolves the issue:
Code: [Select]
                        Dim z() As Object = {Me, x}
                        '* 5-AUG-14 Added the ELSE to handle if the SynchronizingObject is not set
                        If m_SynchronizingObject IsNot Nothing Then
                            m_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
                        Else
                            If SubscriptionList(i).dlgCallBack IsNot Nothing Then
                                SubscriptionList(i).dlgCallBack.Invoke(Me, x)
                            End If
                        End If

JanVanDerZijden

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Advanced HMI Subscribe is not working
« Reply #3 on: August 07, 2014, 11:18:57 AM »
Hé, this is some good code, I have replaced it and I do not have the error anymore. There is only problem left: The eventhandler is only triggered once. Besides it is triggered again when a new subscription is added.

Here is the code where I think it not going good:

If SubscriptionThread Is Nothing Then
            SubscriptionThread = New System.ComponentModel.BackgroundWorker
            AddHandler SubscriptionThread.DoWork, AddressOf SubscriptionUpdate
            SubscriptionThread.RunWorkerAsync()
        End If

SubscriptionThread is not nothing here, so the handler is not added.

Thanks in advance!

calimero100582

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Advanced HMI Subscribe is not working
« Reply #4 on: September 09, 2014, 01:17:23 PM »
Update the method SubscriptionUpdate

Code: [Select]
    Private Sub SubscriptionUpdate(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs)
        While Not StopSubscriptions
            If Not m_DisableSubscriptions And GroupedSubscriptionReads IsNot Nothing Then
                '* 3-JUN-13 Do not read data until handles are created to avoid exceptions
                If Not HandleCreated AndAlso m_SynchronizingObject IsNot Nothing Then
                    If m_SynchronizingObject IsNot Nothing AndAlso TypeOf (m_SynchronizingObject) Is System.Windows.Forms.Control _
                         Then
                        If Not DirectCast(m_SynchronizingObject, System.Windows.Forms.Control).IsHandleCreated Then
                            'Exit Sub
                        Else
                            HandleCreated = True
                        End If
                    End If
                Else
                    Dim i As Integer = 0
                    While i < GroupedSubscriptionReads.Count And Not StopSubscriptions

                        SyncLock (ReadLock) ' Do not let the Internal request change during another read
                            Try
                                If Not m_DisableSubscriptions Then
                                    InternalRequest = True
                                    'Dim elapsed = timer.ElapsedMilliseconds

                                    '23-OCT-11 Moved before the next 4 lines
                                    Me.Read(GroupedSubscriptionReads(i).TagName, GroupedSubscriptionReads(i).NumberToRead)
                                    'elapsed = timer.ElapsedMilliseconds

                                    InternalRequest = False
                                Else
                                    Threading.Thread.Yield()
                                End If
                            Catch ex As MfgControl.AdvancedHMI.Drivers.Common.PLCDriverException
                                Dim x As New MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs(ex.ErrorCode, ex.Message)
                                x.Values.Add(ex.Message)
                                Dim z() As Object = {Me, x}

                                Try
                                    '****  TODO:  Send error to proper control(i indexes the grouped subscriptions, not individual subscription)
                                    If m_SynchronizingObject IsNot Nothing Then
                                        m_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
                                    Else
                                        If SubscriptionList(i).dlgCallBack IsNot Nothing Then
                                            SubscriptionList(i).dlgCallBack.Invoke(Me, x)
                                        End If
                                    End If
                                Catch ex2 As Exception
                                End Try
                            Catch ex As Exception
                                '* Send this message back to the requesting control
                                Dim x As New MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs(-99, ex.Message)
                                x.Values.Add(ex.Message)
                                Dim z() As Object = {Me, x}

                                '****  TODO:  Send error to control
                                'm_SynchronizingObject.BeginInvoke(SubscriptionList(i).dlgCallBack, z)
                                '* Slow down the poll rate to avoid app freezing
                                SubscriptionList(i).SkipReads = 10
                            End Try
                        End SyncLock

                        i += 1
                    End While
                End If
            End If

            Threading.Thread.Sleep(m_PollRateOverride)
        End While
    End Sub