Author Topic: MicroLogix DataSubcriber2 and SQL  (Read 6128 times)

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
MicroLogix DataSubcriber2 and SQL
« on: October 08, 2015, 12:22:13 PM »
I want to log PLC data to a SQL database every time a change occurs in the PLC. I have both MicroLogix and CompactLogix PLCs, so far all the testing has been done in MicroLogix, all the PLC information data such as the IP, Tags and driver type are also stored in the database. When the window loads, I create an EthernetIPforSLCMicroCom array, a DataSubscriber2 array and a PLCAddressItem array, because I might have 1 or 25 different PLCs to log, each with 1 or 50 different tags to log. I already checked the code multiple times and everything seems like it would have to run fine. The problem is that when the data changes the event handler is not firing up. I already checked multiple post regarding dataChanged but I continue with same problem. Any help? Thanks in advanced

'MicroLogix
        For Each rowMicroLogixDistinctIPs As DataRow In dtMicroLogixDistinctIPs.Rows 'each row contains an unique IP
            Dim _ping As New Ping
            Try
                Dim _pingReply = _ping.Send(rowMicroLogixDistinctIPs.Item(0).ToString(), 1000) 'ping PLC to see if it is online
                If _pingReply.Status = IPStatus.Success Then 'if it is pingable
                    If IsNothing(MicroDriver(indexPLCMicroDriver)) Then 'if driver has not been initialized
                        MicroDriver(indexPLCMicroDriver) = New EthernetIPforSLCMicroCom(Me.components) 'MicroDriver is initialized
                    End If
                    MicroDriver(indexPLCMicroDriver).IPAddress = rowMicroLogixDistinctIPs.Item(0).ToString() 'assigns IP to driver
                    MicroDriver(indexPLCMicroDriver).PollRateOverride = 1000 'check data every 1000 milliseconds
                    'SQL Query output for following dataTable
                    'PLC_ID     IP        IPDescription   ControllerType     TagName       TagDescription            Location            StartTime                EndTime
                    '   1    10.103.12.23   Press          MicroLogix         ST41:0   Current Running Model         Cell 2     2015-09-07 17:01:00.000      2020-09-07 17:01:00.000
                    Dim dtAllTagsFromOneIP As DataTable = SQLQuery.SelectAllTagsFromOneIP(rowMicroLogixDistinctIPs.Item(0).ToString()) 'gets all Tags that correspond to PLC/IP
                    Dim totalAllTagsFromOneIP As Integer = dtAllTagsFromOneIP.Rows.Count 'assigns the number of total tags that correspond to one IP
                    Dim PLCAddressItem(totalAllTagsFromOneIP) As PLCAddressItem 'creates an PLCAddressItem array and assigns the total tags
                    Dim indexPLCAddressItem As Integer = 1
                    For Each rowAllTagsFromOneIP As DataRow In dtAllTagsFromOneIP.Rows 'For each tag
                        If IsNothing(PLCAddressItem(indexPLCAddressItem)) Then 'if PLCAddressPLC has not been initialized
                            PLCAddressItem(indexPLCAddressItem) = New PLCAddressItem 'PLCAddressItem is initialized
                        End If
                        PLCAddressItem(indexPLCAddressItem).LastValue = Nothing 'assigns last value
                        PLCAddressItem(indexPLCAddressItem).NumberOfElements = 1 'assigns number of elements
                        PLCAddressItem(indexPLCAddressItem).PLCAddress = rowAllTagsFromOneIP.Item(4).ToString() 'assigns PLC address
                        PLCAddressItem(indexPLCAddressItem).ScaleFactor = 1.0R 'assigns scale factor
                        PLCAddressItem(indexPLCAddressItem).ScaleOffset = 0R 'assigns scale off set
                        PLCAddressItem(indexPLCAddressItem).SubscriptionID = 0 'assigns subscription ID
                        If IsNothing(DataSubsMicro(indexPLCMicroDriver)) Then ' if dataSubcription2 has not been initialized
                            DataSubsMicro(indexPLCMicroDriver) = New DataSubscriber2 'DataSubsMicro is initialized
                            DataSubsMicro(indexPLCMicroDriver).CommComponent = MicroDriver(indexPLCMicroDriver) 'assigns driver to datasubscriber
                        End If
                        DataSubsMicro(indexPLCMicroDriver).PLCAddressValueItems.Add(PLCAddressItem(indexPLCAddressItem)) 'adds to DataSubcriber2 the recently created PLCAddressItem
                        DataSubsMicro(indexPLCMicroDriver).PollRate = 1000 'assigns to DataSubscriber2 the poll rate
                        DataSubsMicro(indexPLCMicroDriver).SynchronizingObject = Me 'assigns to DataSubscriber2 the synchronizing object
                        DataSubsMicro(indexPLCMicroDriver).Value = Nothing 'assigns to DataSubscriber2 the value

                        indexPLCAddressItem += 1 'increases the index for the PLCAddressItems
                    Next
                    AddHandler DataSubsMicro(indexPLCMicroDriver).DataChanged, AddressOf DataChanged 'adds a event handler to data changed
                End If
            Catch ex As Exception
                MsgBox("AdvancedHMI error: " + ex.Message)
            Finally
                indexPLCMicroDriver += 1 'increases the index used for the PLC drivers and DataSubscribers2
            End Try
        Next
        MsgBox("done loading")
    End Sub

Private Sub DataChanged(sender As Object, e As Drivers.Common.PlcComEventArgs)
        MsgBox("e.values: " + e.Values(0).ToString() + "; e.PLCAddress: " + e.PlcAddress)
    End Sub

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: MicroLogix DataSubcriber2 and SQL
« Reply #1 on: October 08, 2015, 12:28:31 PM »
Forgot to include the following, I am using the AHMI399a solution and also I am using MS VS 2015 express

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: MicroLogix DataSubcriber2 and SQL
« Reply #2 on: October 08, 2015, 02:46:47 PM »
The DataSubscriber was designed to make subscribing easy without the need to write code using the Visual Designer. Since you are doing everything in code, it will be better to directly subscribe to the driver and not use a DataSubscriber. Later today I will post an example of how to do this.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: MicroLogix DataSubcriber2 and SQL
« Reply #3 on: October 08, 2015, 04:25:00 PM »
Here is an example of subscribing directly via code:


    Private SubscriptionID As Integer
    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        EthernetIPforCLXCom1.Subscribe("MyTag", 1, 500, AddressOf DataReturned)
    End Sub

    Private LastValue As String
    Private Sub DataReturned(ByVal sender As Object, ByVal e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs)
        If e.PlcAddress = "MyTag" Then
            If e.Values(0) <> LastValue Then
                '* Do something here for the value changed

                LastValue = e.Values(0)
            End If
        End If
    End Sub

    Private Sub MainFormX_FormClosing(sender As Object, e As Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        '*Release the subscription so the driver stops reading from the PLC
        EthernetIPforCLXCom1.UnSubscribe(SubscriptionID)
    End Sub

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: MicroLogix DataSubcriber2 and SQL
« Reply #4 on: October 08, 2015, 04:40:59 PM »
Wow the code is much simpler. I apparently I was making things more complicated than what it had to be. Thank you very much for your help. Apparently AHMI has it all. Good job Archie.

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: MicroLogix DataSubcriber2 and SQL
« Reply #5 on: October 08, 2015, 06:51:53 PM »
Archie, one more question. Is there a way to know from which IP the data is coming using subscribers. Lets take the following example.


EthernetIPforCLXCom1.Subscribe("MyTag", 1, 500, AddressOf DataReturned)
 EthernetIPforCLXCom2.Subscribe("MyTag", 1, 500, AddressOf DataReturned)

Private LastValue As String
Private Sub DataReturned(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
        If e.PlcAddress = "ST41:11" And e.IP = "1.1.1.1" Then
            If e.Values(0) <> LastValue Then
                'Write to SQL
                LastValue = e.Values(0)
            End If
        ElseIf e.PlcAddress = "ST41:11" And e.IP = "2.2.2.2" Then
            If e.Values(0) <> LastValue Then
                'Write to SQL
                LastValue = e.Values(0)
            End If
        End If
    End Sub

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5269
    • View Profile
    • AdvancedHMI
Re: MicroLogix DataSubcriber2 and SQL
« Reply #6 on: October 08, 2015, 07:29:38 PM »
I would use 2 separate DataReturned subs

EthernetIPforCLXCom1.Subscribe("MyTag", 1, 500, AddressOf DataReturnedA)
 EthernetIPforCLXCom2.Subscribe("MyTag", 1, 500, AddressOf DataReturnedB)

 Private Sub DataReturnedA(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
     
  End Sub

 Private Sub DataReturnedB(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
     
 End Sub

hektop

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: MicroLogix DataSubcriber2 and SQL
« Reply #7 on: October 23, 2015, 04:31:33 PM »
I forgot to reply back but I found a way to do it without creating multiple DataReturn subs

Private Sub CLXDataReturned(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs)
        Dim PlcIp, PlcTag, PlcValue As String
        Try
            Dim DriverComm As AdvancedHMIDrivers.EthernetIPforCLXCom = CType(sender, AdvancedHMIDrivers.EthernetIPforCLXCom) This is the important part
            PlcIp = DriverComm.IPAddress This is how I get the IP value
            PlcTag = e.PlcAddress
            PlcValue = e.Values(0).ToString()
            comparePLCDataWithSQL(PlcIP, PlcTag, PlcValue)
        Catch ex As Exception
            SQLQuery.InsertInto4FieldsQuery("tblErrorLog", "IP", sender.IPAddress, "LogTime", Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), "Error", ex.Message, "Tag", e.PlcAddress)
        End Try

    End Sub