Author Topic: CompactLogix and MicroLogix questions  (Read 4509 times)

BarryTemp

  • Newbie
  • *
  • Posts: 3
    • View Profile
CompactLogix and MicroLogix questions
« on: August 27, 2013, 09:01:48 AM »
WARNING: Please be gentle, very much a NOOOOOOOB. Sorry for the long post.
Archie, this product is sheer brilliance.

I have a Compact Logix L32E and a Micrologix1400 SerB.
The code in both PLC's is to put the accumulator of a timer into array "Test[0]" till "Test[200]" for the Compact Logix and "N223:0" till N223:200" for the MicroLogix as fast as possible.
I can connect to both PLC's and receive the tag name and the tag data into 2 separate data grids. I read 201 integers per PLC.


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I currently run off a timer executing every 5 Seconds which calls ReadCompactLogix() and ReadMicroLogix()

Private Sub ReadCompactLogix()

        Dim sTemp As String
        Dim iLoop As Integer

        EthernetIPforCLXComm1.AsyncMode = True
        For iLoop = 0 To 200
            sTemp = "Test[" + iLoop.ToString + "]"
            EthernetIPforCLXComm1.ReadAny(sTemp, 1)
        Next
        EthernetIPforCLXComm1.AsyncMode = False
End Sub



Private Sub ReadMicroLogix()

        Dim sTemp As String
        Dim iLoop As Integer

        EthernetIPforPLCSLCMicroComm1.AsyncMode = True
        For iLoop = 0 To 200
            sTemp = "N223:" + iLoop.ToString
            EthernetIPforPLCSLCMicroComm1.ReadAny(sTemp, 1)
        Next
        EthernetIPforPLCSLCMicroComm1.AsyncMode = False

End Sub


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I then use the DataReceived event handler as follows:

 Private Sub EthernetIPforCLXComm1_DataReceived(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs) Handles EthernetIPforCLXComm1.DataReceived
        Dim sTemp As String
        Dim iLoop As Integer

        Try
            sTemp = e.PlcAddress
            Dim iLength As Integer = sTemp.Length
            Dim sLoop As String = Mid(sTemp, 6, iLength - 6)
            iLoop = CInt(sLoop)
            dgvCompactLogix.Item(0, iLoop).Value = e.PlcAddress
            dgvCompactLogix.Item(1, iLoop).Value = e.Values(0)

            'Calculate the time to return all the variables
            If iLoop = 200 Then
                If dgvCompactLogix.Item(1, 200).Value > dgvCompactLogix.Item(1, 0).Value Then
                    txtCompactLogix.Text = dgvCompactLogix.Item(1, 200).Value - dgvCompactLogix.Item(1, 0).Value
                Else
                    txtCompactLogix.Text = dgvCompactLogix.Item(1, 200).Value - dgvCompactLogix.Item(1, 0).Value + 9999
                End If
            End If

        Catch ex As Exception

        End Try
End Sub




 Private Sub EthernetIPforPLCSLCMicroComm1_DataReceived(ByVal sender As Object, ByVal e As Drivers.Common.PlcComEventArgs) Handles EthernetIPforPLCSLCMicroComm1.DataReceived
        Dim sTemp As String
        Dim iLoop As Integer
        Dim iStringLength As Integer
        Dim iStringPosition As Integer

        Try
            sTemp = e.PlcAddress
            iStringLength = sTemp.Length
            iStringPosition = InStr(sTemp, ":")
            Dim sLoop As String = Mid(sTemp, iStringPosition + 1, iStringLength - iStringPosition)
            iLoop = CInt(sLoop)
            dgvMicroLogix.Item(0, iLoop).Value = e.PlcAddress
            dgvMicroLogix.Item(1, iLoop).Value = e.Values(0)

            'Calculate the time to return all the variables
            If iLoop = 200 Then
                If dgvMicroLogix.Item(1, 200).Value > dgvMicroLogix.Item(1, 0).Value Then
                    txtMicroLogix.Text = CInt(dgvMicroLogix.Item(1, 200).Value) - CInt(dgvMicroLogix.Item(1, 0).Value)
                Else
                    txtMicroLogix.Text = CInt(dgvMicroLogix.Item(1, 200).Value) - CInt(dgvMicroLogix.Item(1, 0).Value) + 32765
                End If
            End If

        Catch ex As Exception

        End Try

End Sub
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Data is returned to the respective grids.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Question 1: NumberOfElements

I was hoping to address the array by using the 200 value below. By doing this, it only returns "Test[0]" and "N50:0" only. How do I correctly address NumberOfElements?

Private Sub cmdCompactLogixArray_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCompactLogixArray.Click
        EthernetIPforCLXComm1.AsyncMode = True
        EthernetIPforCLXComm1.ReadAny("Test[0]", 200)
        EthernetIPforCLXComm1.AsyncMode = False
End Sub


Private Sub cmdMicroLogixArray_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdMicroLogixArray.Click
        EthernetIPforPLCSLCMicroComm1.AsyncMode = True
        EthernetIPforPLCSLCMicroComm1.ReadAny("N50:0", 200)
        EthernetIPforPLCSLCMicroComm1.AsyncMode = False
End Sub

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Question 2: Subscribe method

In another post, Archie gives an example.

Public Class frmSubscribe
    Private SubscriptionID As Integer

    Private Sub frmSubscribe_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        EthernetIPforCLXComm1.UnSubscribe(SubscriptionID)
    End Sub

    Private Sub frmSubscribe_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        EthernetIPforCLXComm1.IPAddress = "192.168.101.253"
        SubscriptionID = EthernetIPforCLXComm1.Subscribe("MyTag", 1, 250, AddressOf SubscribedDataReturned)
    End Sub

    '* Show the value when it is returned
    Private Sub SubscribedDataReturned(ByVal sender As Object, ByVal e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs)
        'Me.Text = e.Values(0)
        TextBox1.Text = e.Values(0)
    End Sub

End Class


Modifications Made to Archies code was EthernetIPforCLXCom1 replaced with EthernetIPforCLXComm1 (Running Ver 3.41 of driver)

There is an error and I do not know how to fix it.
SubscribedDataReturned has a blue squiggle under it and the error is:
Method "Private Sub SubscribedDataReturned(ByVal sender As Object, ByVal e As MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs)" does not have a signature compatible with 'Delegate Sub ReturnValues(values() as String)

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Question 3: Performance
In my real life application, I need to read 250 integers as quickly as possible (i.e. every 2 seconds would be great).
What is the best way to handle this? As per timer above OR to use the Subscribe method OR ?????

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: CompactLogix and MicroLogix questions
« Reply #1 on: August 27, 2013, 10:48:54 AM »
I definitely recommend using the latest version (3.58 as of this posting) because the EthernetIP drivers have been revamped making them more stable and faster.

When reading arrays or consecutive elements, it is much faster to read with a single read:
Code: [Select]
Dim values() as string
values=EthernetIPforCLXCom1.Read("Test[0]",201)
' values(0) is Test[0]
' values(1) is Test[1]
' etc

Depending on your network speed and processor, you should be able to perform that read at least every 500ms. It is the same for the MicroLogix

Code: [Select]
Dim values() as string
values=EthernetIPforPLCSLCMicroCom1.Read("N223:0",201)


There are 3 read methods:

Synchronous:
Simplest read method, however ties up UI (User Interface) thread leaving the form unresponsive while waiting for a response from PLC. With the Ethernet driver, typical response is about 5ms, so the thread tie up is practically unnoticeable.

Asynchronous:
Require a call to initiate and an event handler to receive the data. The call to initiate (BeginRead) will return immediately and not tie up the UI thread. This is most obvious in slower communications such as RS232. Ethernet is typically fast enough that there is no noticeable difference between synchronous and asynchronous unless reading very large amounts of data.

Subscriptions:
The are the most complex, but lets the driver handle all of the work and optimize the reads. Currently only one elements at a time can be subscribed to. Does not allow multiple elements in an array to be read with a single subscription. Subscriptions update at the rate of the PollRateOverride as set in the driver properties. Too many subscriptions at a fast rate can consume a lot of bandwidth and slow things down. All of the built in controls use subscriptions in order to ensure the most optimized reading. For example, if one BasicLabel us set to display MyTag[0] and another set to display MyTag[1], the driver will make a single request from the PLC, split the results and send it to the appropriate BasicLabel.

BarryTemp

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: CompactLogix and MicroLogix questions
« Reply #2 on: August 27, 2013, 12:20:51 PM »
Sorry, I am 17 versions behind, we are slow in South Africa.

So if I want to use the subscribe method, I will have to create 250 instances of the Subscribe function. When will the subscribe method handle arrays?

It sounds like the best option for me would be to use Asynchronous read with NumberOfElements with the DataReceived event handler?

Thanks again for this product.

Barry

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: CompactLogix and MicroLogix questions
« Reply #3 on: August 27, 2013, 12:25:03 PM »
Array handling for subscriptions isn't planned until version 4. If using asynchronous reads with version 3.41, use them with care. There was a major issue when performing a lot of reads in code along with controls on the form. Sometimes it would not return any data and sometimes you would get the sequence number instead of the data. This was the motivation to revamping 3.5 in order to resolve these problems. In 3.5, the Asyncmode property was removed and replaced with Read(synchronous) and BeginRead(asynchronous)

You're not completely 17 versions behind. The versions jumped from 3.43 to 3.5.1. From there up to 3.5.8, it was mainly a series of bug fixes to the new drivers.
« Last Edit: August 27, 2013, 12:26:37 PM by Archie »

BarryTemp

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: CompactLogix and MicroLogix questions
« Reply #4 on: August 28, 2013, 07:33:34 AM »
Thanks for the feedback. I am now using version 358 and there is a dramatic improvement in driver performance. WOW.
It is great that the NumberOfElements function  is working.

====================================================================================================================
As per your post, I did the following:
        Dim sTemp As String
        Dim iLoop As Integer

        Dim values1(300) As String

        values1 = EthernetIPforPLCSLCMicroCom1.Read("N50:0", 200)

        For iLoop = 0 To 199
            sTemp = "N50:" + iLoop.ToString
            dgvMicroLogix.Item(0, iLoop).Value = sTemp
            dgvMicroLogix.Item(1, iLoop).Value = values1(iLoop)
        Next

It errors at iLoop = 82

====================================================================================================================
BUT doing this works and returns all the variables:

        Dim sTemp As String
        Dim iLoop As Integer

        Dim values1(300) As String
        Dim values2(300) As String

        values1 = EthernetIPforPLCSLCMicroCom1.Read("N50:0", 101)
        values2 = EthernetIPforPLCSLCMicroCom1.Read("N50:100", 101)

        For iLoop = 0 To 100
            sTemp = "N50:" + iLoop.ToString
            dgvMicroLogix.Item(0, iLoop).Value = sTemp
            dgvMicroLogix.Item(1, iLoop).Value = values1(iLoop)
        Next

        For iLoop = 100 To 199
            sTemp = "N50:" + iLoop.ToString
            dgvMicroLogix.Item(0, iLoop).Value = sTemp
            dgvMicroLogix.Item(1, iLoop).Value = values2(iLoop - 100)
        Next
====================================================================================================================