Author Topic: Subcribers not working?  (Read 3287 times)

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Subcribers not working?
« on: March 03, 2016, 05:08:38 PM »
I am using VS 2015 community edition, Advanced HMI 3.99d, Windows 10 Pro. I am trying to subscribe two different tags to one AB MicroLogix controller and two different tags to one AB Compact logix controller. The problem is that the Event Handlers are not being triggered, when the data is changed. attached is my code. Any suggestions? Do any of you see something wrong with my code?

Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim MicroComm As New EthernetIPforSLCMicroCom()
        Dim CLXComm As New EthernetIPforCLXCom()
        Try
            'MicroLogix
            MicroComm.IPAddress = "10.103.12.23"
            MicroComm.PollRateOverride = 500
            MicroComm.Subscribe("ST41:0", 1, 500, AddressOf MicroDataReturned)
            MicroComm.Subscribe("F8:1", 1, 500, AddressOf MicroDataReturned)
            'CompactLogix
            CLXComm.IPAddress = "10.103.12.14" 'saves IP address into driver
            CLXComm.PollRateOverride = 500 'everytime the driver gets data from PLC
            CLXComm.Subscribe("CYCLE_COUNTER.CYCLE1", 1, 500, AddressOf CLXDataReturned)
            CLXComm.Subscribe("Current_Recipe", 1, 500, AddressOf CLXDataReturned)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub MicroDataReturned(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
        Try
            If e.PlcAddress = "ST41:0" Then
                Label2.Text = e.Values(0).ToString()
            End If
            If e.PlcAddress = "F8:1" Then
                Label3.Text = e.Values(0).ToString()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub CLXDataReturned(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
        Try
            If e.PlcAddress = "CYCLE_COUNT.CYCLE1" Then
                Label4.Text = e.Values(0).ToString()
            End If
            If e.PlcAddress = "Current_Recipe" Then
                Label5.Text = e.Values(0).ToString()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Subcribers not working?
« Reply #1 on: March 03, 2016, 08:25:24 PM »
Does it work if you add the driver to the form and use a DataSubscriber?

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Subcribers not working?
« Reply #2 on: March 03, 2016, 08:30:11 PM »
The problem may be where you are declaring your driver instances. You have them inside the FormLoad event handler, which means as soon as that sub exits, the drivers may be disposed.

They will need to be declared as Private variables outside of the subroutines.

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Subcribers not working?
« Reply #3 on: March 04, 2016, 11:32:11 AM »
I tried both sugestions, but none of them worked. I am still getting no data from the driver intance nor getting the event being triggered. I do get data from the PLC if I just use the Read function from the PLC no matter where I place the driver instance. Also it I get data and it gets updated if I just use the GUI forms. Is just that for the project I am working on I have to do everything by code since the PLC data (IPs and tags) might change over time since the PLC data it is being retrieved from a database. Any more suggestions?

1.)
    Moving the driver instance to the top of the mainform_load Sub as private.

2.) Using a dataSubcriber2. I am not sure if I have the correct code though.

Private MicroComm As New EthernetIPforSLCMicroCom()
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            'MicroLogix
            MicroComm.IPAddress = "10.103.12.23"
            MicroComm.PollRateOverride = 500
            Dim DataSubsMicro As New AdvancedHMIControls.DataSubscriber2()
            Dim PLCAddressItem(0) As Drivers.PLCAddressItem
            Dim indexPLCAddressItem As Integer = 1
            If IsNothing(PLCAddressItem(0)) Then 'if PLCAddressPLC has not been initialized
                PLCAddressItem(0) = New Drivers.PLCAddressItem 'PLCAddressItem is initialized
            End If
            PLCAddressItem(0).LastValue = Nothing 'assigns last value
            PLCAddressItem(0).NumberOfElements = 1 'assigns number of elements
            PLCAddressItem(0).PLCAddress = "ST41:0" 'assigns PLC address
            PLCAddressItem(0).ScaleFactor = 1.0R 'assigns scale factor
            PLCAddressItem(0).ScaleOffset = 0R 'assigns scale off set
            PLCAddressItem(0).SubscriptionID = 0 'assigns subscription ID
            DataSubsMicro.CommComponent = MicroComm 'assigns driver to datasubscriber
            DataSubsMicro.PLCAddressValueItems.Add(PLCAddressItem(0)) 'adds to DataSubcriber2 the recently created PLCAddressItem
            DataSubsMicro.PollRate = 1000 'assigns to DataSubscriber2 the poll rate
            DataSubsMicro.SynchronizingObject = Me 'assigns to DataSubscriber2 the synchronizing object
            DataSubsMicro.Value = Nothing 'assigns to DataSubscriber2 the value
            AddHandler DataSubsMicro.DataChanged, AddressOf MicroDataReturned 'adds a event handler to data changed
     Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
End Sub

Private Sub MicroDataReturned(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
        Try
            If e.PlcAddress = "ST41:0" Then
                Label2.Text = e.Values(0).ToString()
            End If
            If e.PlcAddress = "F8:1" Then
                Label3.Text = e.Values(0).ToString()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
End Sub


rbelknap

  • Jr. Member
  • **
  • Posts: 68
    • View Profile
Re: Subcribers not working?
« Reply #4 on: March 04, 2016, 12:06:46 PM »
Your also declaring the DataSubscriber in the subroutine.  Move that outside as a private also.

Anything that needs to exist after the subroutine ends needs to be declared outside of it.


hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Subcribers not working?
« Reply #5 on: March 04, 2016, 12:21:26 PM »
rbelknap,

I did as suggested, but my labels continue without updating. Any other thoughts? Is there an example you might know somewhere in this fórum for me to take a look and compare?

    Private CLXComm As New EthernetIPforCLXCom()
    Private MicroComm As New EthernetIPforSLCMicroCom()
    Private DataSubsMicro As New AdvancedHMIControls.DataSubscriber2()
    Private PLCAddressItem(0) As Drivers.PLCAddressItem
    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
       'all my previous code
    End Sub


Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Subcribers not working?
« Reply #6 on: March 04, 2016, 12:27:49 PM »
Try this just to verify everything you have is working:

- Add a driver instance to the form and set the communication properties
- Add a DataSubscriber2 to the form
- Set the PCLAddressValueItems to your address
- Double click the DataSubscriber2
- Enter the code:
Label1.Text=e.values(0)

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Subcribers not working?
« Reply #7 on: March 04, 2016, 01:17:58 PM »
I did a quick test with version 3.99d and it worked as expected:
Code: [Select]
    Private PLCCom As New AdvancedHMIDrivers.EthernetIPforSLCMicroCom

    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PLCCom.IPAddress = "192.168.2.8"
        PLCCom.SynchronizingObject = Me

        PLCCom.Subscribe("N7:0", 1, 500, AddressOf DataReturned)
    End Sub

    Private Sub DataReturned(ByVal sender As Object, ByVal e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs)
        Me.Text = e.Values(0)
    End Sub

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Subcribers not working?
« Reply #8 on: March 04, 2016, 01:42:32 PM »
Archie,

It worked. I guess I just needed the following line of code "PLCCom.SynchronizingObject = Me". Thanks for the help Archie, the little details always matter.

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Subcribers not working?
« Reply #9 on: March 04, 2016, 03:22:58 PM »
Archie,

why synchronizingObject made the difference and why Me?

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: Subcribers not working?
« Reply #10 on: March 04, 2016, 08:26:37 PM »
Archie,

why synchronizingObject made the difference and why Me?
In a Windows application the GUI (graphical user interface) works on a single thread. Other parts of the application can run on any number of threads. The AdvancedHMI drivers typically operate on 2-3 background threads. When data is returned, it is handled on one of the background threads. If a backround thread attempts to change something in the GUI, such as setting a Label's text property, it will cause a cross-thread operation exception.

In order to avoid this exception, it is necessary to invoke a call on the GUI thread with the data from the driver. The purpose of the SynchronizingObject is to give something to the driver that operates on the GUI thread. The driver can then use it to invoke the DataReturned call on the GUI thread.

The keyword "Me" is setting it to the current form.

Chances are if you watched the Output window in Visual Studio before you had set your SynchronizingObject, it was probably showing exceptions every time it called the DataReturned.