Author Topic: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber  (Read 8292 times)

RedBinary

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Red Binary
After getting some time to look deeper into the issue I had posted about in the Support Questions category it appears that sometimes the driver returns the SequenceNumber from ReadyAny() rather than the expected array of strings. It must be misinterpreting AsyncMode to make this happen. I believe this is the same issue as discussed at http://sourceforge.net/projects/advancedhmi/forums/forum/875091/topic/6729354 and I am using the 3.26 beta.

I'm not yet familiar enough with the code to fully understand how AsyncMode is being used, among other things. It looks like the driver's AsyncMode property is temporarily set to True in PollUpdate() so I'm guessing that it's possible that the ReadAny() call that I'm making is sometimes corresponding to this brief period while components on the form are updating. This wouldn't explain why once the bug manifests it is persistent, though.

Any insight, advice, or suggestions?

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #1 on: March 19, 2013, 08:41:17 PM »
I have not yet been able to reproduce this yet, but the next version (3.27) has some portions of the Ethernet driver reworked, so maybe it will be fixed.. I'm not sure when the version will be ready for release.

RedBinary

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Red Binary
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #2 on: March 19, 2013, 09:21:20 PM »
I'd be happy to test 3.27 for you and/or send you a project that will allow reproduction of the bug.

kf4ozb

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #3 on: March 20, 2013, 07:58:02 AM »
I would be happy to test 3.27 also.

This is a hard bug to reproduce. I think the key is heavy network traffic.  It also tends to only show up when I don't have the debugger running, This may just be a coincidence.

Working off of Red Binary's statement that it's returning the SequenceNumber I will do some further investigations from my end.

Thanks,

Mickey

RedBinary

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Red Binary
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #4 on: March 20, 2013, 10:56:50 AM »
I can reproduce it readily. I believe it's a case of having components on the form that are polling at regular intervals and a ReadAny() in code that can be triggered at unpredictable times in relation to the component's polling. In my case anyway. I loaded up the driver with logging an can positively say that I am getting the SequenceNumber returned. The only case that I can see where this can happen is if AsyncMode is true. From what I've seen is that the bug only manifests when the ReadyAny() occurs while the components are updating. I would say then that the more components and more programmatic ReadAny() calls the more likely the bug is to manifest.

The particulars of my project are that there are 6 BasicLabels & 7 BasicIndicators on the form. There are also 2 conditions that will call ReadAny(). One instance is cyclic and event-driven. Every time one of the BasicLabels changes from off to on it will read an 100 member array from the PLC. This condition very rarely will awaken the bug. The second condition is when one of 4 buttons is pushed. This will read 2 separate 100 member arrays. It is at this point that the bug is most commonly seen. I can push the buttons repeatedly around 2x per second to make this happen and it has never taken more than 20 button presses.

I'll reiterate that I'm not at a point where I have any real understanding of the code. VB is definitely not my first language and PLC communication protocols are something that I'm very in the dark about - especially AB/Rockwell. For these reasons I don't want to make any presumptions on any solution proposals. I will, however, ask if there is a preferred way to separate out the usages/properties of AsyncMode and/or to have 2 distinct procedures?

RedBinary

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Red Binary
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #5 on: March 20, 2013, 11:35:48 AM »
I figured I would show some of the logging that I did to demonstrate:

A successful read. Address Program:HEAD_2.PARISON_FB[0] is the manually called ReadAny() delivering 50 members each in 2 calls in the midst of the AsyncMode results of the components.
Code: [Select]
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress ESTOP_OK, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 114
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:HEAD_2.PARISON_FB[0], numberOfElements 50) while loop: ActiveRequest True, Delays 1
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:HEAD_2.PARISON_FB[0], numberOfElements 50) while loop: ActiveRequest True, Delays 2
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress LAST_CYCLE_TIME, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 115
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:HEAD_2.PARISON_FB[0], numberOfElements 50) SequenceNumber 116, returning d{19,19,19,19,20,20,20,20,20,20,20,21,21,21,21,21,22,22,22,22,23,23,24,24,24,25,25,25,26,26,26,26,27,27,27,27,27,28,27,27,27,27,27,26,26,26,25,25,25,24}
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:ACCUM_1.CUSHION_KEYIN, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 118
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:HEAD_2.PARISON_FB[50], numberOfElements 50) SequenceNumber 119, returning d{24,24,24,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,20,20,20,20,20,20,20,20,20,20,20,20,20,19,20,20,20,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20}
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:ACCUM_1.SHOT_SIZE_KEYIN, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 120

In a bugged call to ReadyAny() it is returning as if it is also AsyncMode. This time it is for Program:HEAD_3.PARISON_CPT[0]
Code: [Select]
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress SAFETY_GUARDS_CLOSED, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 127
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress CUSHION, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 128
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress Program:HEAD_3.PARISON_CPT[0], numberOfElements 50) SyncLock: AsyncMode, SequenceNumber 129
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress EMPTY, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 131
10:19:06 AM Wednesday, March 20, 2013  :DRVR: ReadAny(startAddress ESTOP_OK, numberOfElements 1) SyncLock: AsyncMode, SequenceNumber 132

It's the same line of code in the form making both of these calls:
Code: [Select]
                    Dim profile_points1(50) As String   'read times out trying to pull all 100 points in one shot
                    Dim profile_points2(50) As String   'so break it into 2 separate arrays & calls

                    Dim addr1 As String = "Program:HEAD_" & (currentHead + 1) & ".PARISON_CPT[0]"
                    Dim addr2 As String = "Program:HEAD_" & (currentHead + 1) & ".PARISON_CPT[50]"

                    profile_points1 = plc_clx.ReadAny(addr1, 50)

Just now I notice that the unsuccessful call did not go through the delay loop, either.

RedBinary

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Red Binary
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #6 on: March 20, 2013, 01:37:08 PM »
I had a little more time to look at this today. I'm not in any way, shape, or form saying that this is a solution - just that it reinforces the initial diagnosis.

I changed the ReadyAny() prototype declaration in ICommComponent and the function in EthernetIPforCLXComm (as well as in every other driver class that uses the inheritance) to take an optional boolean parameter to mask out external calls to the function:
Code: [Select]
    Function ReadAny(ByVal startAddress As String, ByVal numberOfElements As Integer, Optional ByVal externalCall As Boolean = False) As String()
Then I added the " And Not externalCall" to the if then/else block in ReadAny() in EthernetIPforCLXComm that contains the returns:
Code: [Select]
If PLCAddressByTNS(SequenceNumber And 255).AsyncMode And Not externalCall Then
Finally, I changed my calls in the form to include the added externalCall parameter.
Code: [Select]
feedback_points1 = plc_clx.ReadAny(addr1, 50, True)
After making these changes I have yet to be able to cause the bug to occur after 200+ button presses.

I have not seen any negative or unintended consequences yet, but it is presumed that there are going to be some.

Again, I'm not saying this is a solution or even a band-aid.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #7 on: May 10, 2013, 10:57:08 PM »
I have a theory of what causes this problem:

AsyncMode is a property, therefore any thread can change it's value at any time. Subscriptions are continuously polled and set the property to True prior to calling ReadAny. If a user call to ReadAny is started with AsyncMode set to False, then a subscription update fires and changes the value of AsyncMode to True after the user call starts, but before it uses the value, it will treat the user call as an Async call and return the TransactionID.

If this proves to be the problem, then I will have to remove AsyncMode as a property and make it a parameter that is passed to ReadAny. That will make a unique copy of the value that other threads cannot change at a critical moment.

Your last solution kind of re-enforces my theory of what is happening.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #8 on: May 12, 2013, 08:23:34 PM »
To All:

Version 3.27 is now available to see if it resolves these problems.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #9 on: June 03, 2013, 08:36:35 AM »
I was able to reproduce the problem by putting a lot of controls on a form and using ReadAny in code. I have posted version 3.40 that fixes the problem. These is a new method named ReadSynchronous that should be used when doing a synchronous read in code.

mariya

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #10 on: June 20, 2013, 02:30:49 AM »
very nice post I like this forum




« Last Edit: August 06, 2014, 03:22:56 AM by mariya »

Bad Sector

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #11 on: June 28, 2013, 09:40:44 AM »
I'm not understanding how to use the new EthernetIPforCLXComm1.ReadSynchronous.  The release notes say: Added ReadSynchronous to IComComponent and all drivers
ReadSynchronous should now be used in place of the following:
EthernetIPforCLXCom1.AsyncMode=False
value=EthernetIPforCLXCom1.ReadAny("Tag1")

For instance, I am using:
plcvalue = EthernetIPforCLXComm1.ReadAny(plcaddy)

If I try:
plcvalue = EthernetIPForCLXComm1.ReadSynchronous(plcaddy)    ... VS gives an error likely because I have formatting wrong..


how do I change that to use the new ReadSynchronous?  Or do I need to?  Thanks!

« Last Edit: June 28, 2013, 09:59:21 AM by Bad Sector »

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5262
    • View Profile
    • AdvancedHMI
Re: EthernetIPforCLXComm ReadAny() sometimes returns SequenceNumber
« Reply #12 on: June 28, 2013, 11:54:32 AM »
There is an error in those release notes. You must also specify the number of elements to read:

plcvalue = EthernetIPForCLXComm1.ReadSynchronous(plcaddy,1)