Strange AOI behavior at V32

elfrider

Member
Join Date
Nov 2015
Location
Midlands
Posts
30
Hi,

I'm experiencing a very strange issue with the functionality of an AOI after upgrading to firmware V32.

Bit of background:

CPU is a CLX 1756-L81E. The AOI in question is passed a BOOL array of size 1472 from the HMI, call it HMI_IN[1472], tagged against an InOut parameter, which is defined as say BOOL_IN[1472]. This array is basically holding a load of HMI maintained push buttons, to provide an 'enable' at a given time of day (peg timer).

The AOI has been live in multiple projects at V31 or lower, with no issues whatsoever. This particular project also started life at V31, and worked perfectly throughout all my testing at that point.

The CPU firmware was then flashed up to V32.014, and Studio 5000 taken to V32.03.

The problem:

The problem is related to indirect referencing using the BOOL[1472] array. The AOI takes the current time of day and calculates which element of the 1472 should be examined - this value is held in a DINT called INDEX. We then use an XIC on "BOOL_IN[INDEX]" to fire a single BOOL called ACTIVE, which is an output parameter.
The AOI is always correctly calculating the INDEX value based on the current time of day. The XIC is then becoming true (green), but the ACTIVE bool is not being set! What is really strange is that if you toggle on a bool of minus 32, the XIC goes false, but the ACTIVE bool is set i.e when HMI_IN[ACTIVE-32] is on, ACTIVE becomes set, even though the XIC is correctly showing false. In other words, if the BOOL for the current time segment is 267, turning on HMI_IN[235] causes the ACTIVE bit to be set.

What I've tried:

1. Re-flashing V31 - this immediately resolved the issue. Flashing back to V32 and the problem immediately returns.
2. Based on a technote I found which was very very loosely related (something about V32 & 33 being enhanced and having a special structure for BOOLS in AOI's), I exported the entire project file as an l5k, then reimported from this. THIS RESOLVED THE ISSUE, or so I thought.
3. Having now moved on to a second project using the same AOI (again was V31, been upgraded to V32). This project uses three instances of the AOI - two instances of the AOI worked fine straight after the upgrade, but the third had the same issue as per the above. So I exported/imported as l5k, but rather than fix the problem, it made all three instances broken!

Since then, I've tried:
1. exporting/reimporting the AOI itself
2. deleting & recreating the effected parameters
3. deleting the AOI and recreating it from scratch.
4. Putting the AOI in a periodic task
5. Deleting all other logic from the AOI other than the effected area
6. Delete & recreate the tags assigned against the AOI
7.Added my own temporary BOOL[1472] (not set via the HMI). None of the above worked.

Interestingly, it seems on the odd occasion where it has been working, once that project is saved and I come back to it, download it to the CPU, it remains working. It's like whatever is wrong is held in the project file. My concern (with the first project) is I don't know what's causing it, so I can't guarantee any future action won't suddenly break it. It wouldn't be so bad if it never worked, but the fact I've witnessed it working @ V32 sometimes is what is really concerning.

Video 1 shows the XIC correctly becoming true but the ACTIVE bool not getting set. Video 2 shows the effect of turning on the "minus 32" bool - the XIC correctly goes false, but the ACTIVE bool is set.

Any ideas please? Going to V33 isn't currently an option I have, neither is V32.04 (the client only approves certain versions based on their own staff laptops' FTSP version etc.)

Video 1: https://1drv.ms/v/s!Au76vHzH0CuTxDabCXZIx_FOrrSt?e=vVWpR2
Video 2: https://1drv.ms/v/s!Au76vHzH0CuTxDX8TG7pQ1_FFOL-?e=YKazbM

Thanks.
 
Last edited:
I don't know what the problem is exactly, but there are 1440* minutes in a day, and that array has 1472 elements, or 32 more than the number of minutes in a day; that difference is 32, which sounds like it may be related to the 32 offset found in the testing.

What is PEG_INDX, where is PEG_INDX defined (i.e. inside the AOI or outside the AOI?), and is it being recalculated anywhere else?

E.g. if PEG_INDX is 235 when Rung 16 executes, then ACTIVE will be assigned the same value as PEG_ARRAY[235] on Rung 16, and the [OTE ACTIVE] instruction will be displayed green if the values of ACTIVE, and PEG_ARRAY[235], are both 1, or it will be displayed not green if those values are both 0.

If, later in the scan, PEG_INDX is increased by 32, then the PEG_INDX will be 267, and the [XIC PEG_ARRAY[PEG_INDX]] contact on Rung 16 will be displayed as green if the value of PEG_ARRAY[267] is 1, or it will be displayed not green if that value is 0.

Is that AOI used more than once? Are we looking at the right instance of it?

Of course the interesting part of this is that the Studio5k firmwarree versions is what affects what is shown. Perhaps there were some display "enhancements" made between 31 and 32 that effect this change.

One way to test would be to add a branch on Rung 16 around the [XIC PEG_ARRAY[PEG_INDX]] and [OTE ACTIVE] instructions, that MOVes the value of PEG_INDX, at the time Rung 16 executes, into a variable not written to elsewhere; that will show what the value of PEG_INDX was at the time Rung 16 executed, and what the value of PEG_INDX is at the time the data are displayed.


* Multiplying by unity

1d = 24h, so 1d/1d = 1 = 24h/1d = 24h/d = 1

1h = 60min, so 1h/1h = 1 = 60min/1h = 60min/h = 1

So 1 = 1 * 1 = 24h/d * 60min/h = 1440min/d = 1
 
Last edited:
You are correct with the 1440 theory, I had the same thought earlier as it seemed more than a coincidence. However, the AOI has no notion of the 1440, it has a BOOL [1472] InOut parameter, and a BOOL[1472] tag as an argument against it, the fact we never actually set the last 32 bits is surely irrelevant?

PEG_INDX is a DINT tag local to the AOI itself, no setting is done externally. It simply holds the value equating to the current time using basic maths (see picture 1 for how this is done). This is done just above the rung with ACTIVE coil, and PEG_INDX is always calculated correctly and at no point is it written to again within the AOI.

There are three instances of the same AOI, as mentioned I can routinely get the project to have both working and non-working instances of the AOI at the same time.

See picture 2 which shows some further testing carried out by a colleague (different laptop and a different L81E CPU). It removes the indirect referencing element from the equation. You can clearly see coils being set when they shouldn't, and not when they should.

I'm getting to the point where I'm starting to think V32 (or at least the minor revision I'm using) is simply broken!

Picture1.jpg Picture2.jpg
 
This is from the release notes from V33 of Studio, details the following anomaly which has been addressed:


Anomalous behavior using indirect addressing to a Boolean tag within an Add-On Instruction data type
Anomalous behavior sometimes occurred when using indirect addressing to a Boolean tag within an Add-On Instruction data type containing an alias parameter.
This anomaly first identified in version 28.03. (Lgx00221210, Lgx00221328, Lgx00221329, Lgx00221330, Lgx00221331)
 
Wow, definitely broken.


It's a minor point, but assuming the AOI does not change any of the arrays values, I think BOOL_IN should be a Input parameter, not an InOut parameter.


What happens if you make PEG_INDX an Input or InOut parameter, and pass a separate DINT into each AOI instance?


What if, instead of BOOL_IN[1472], you pass it DINT_IN[46], and do some form of [XIC DINT_IN[(PEG_INDX - (PEG_INDX & 31))/32].[PEG_INDX & 31] OTE ACTIVE] instead?
 
Last edited:
I did try that earlier, it won’t allow an array data type to be passed into an AOI as anything other than an InOut parameter.

I dare say handling it with DINTs as you suggest will work (going by the anomaly being with BOOL arrays) - it would require a rework of the HMI screens :)mad:) but would make the AOI safe for V32.

I’m going to do some bench testing with v33 too to confirm the problem is definitely resolved. What’s a bit odd is the fact the notes say the anomaly was reported at V28, but this AOI has been used many times at V29 & V31 without issue.
 
So we found a working fix for the problem today. By changing the BOOL_IN array from an InOut parameter to a local tag instead, then setting the External Access setting for it to Read/Write, we can set the pegs on the HMI to write directly to this array, and all testing has since proved successful.

The anomaly mentions using aliases as being the issue - I’m guessing an InOut parameter is a form of alias in the way it points to the tag it references I suppose, and therefore changing it has got around the anomaly.
 
The anomaly mentions using aliases as being the issue - I’m guessing an InOut parameter is a form of alias in the way it points to the tag it references I suppose, and therefore changing it has got around the anomaly.


There is perhaps some architecture requirement that translates to requiring the InOut parameter to start on an 8-byte boundary, and if the actual BOOL_IN array in the calling code is not on such a boundary out in the main program but instead on a byte address that ends in either 0x4 or 0xc, then the low three bits of that parameter address get zeroed in the AOI, so 0x...4 become 0x...0 and 0x...c becomes 0x...8, which boils down to an offset of 32 bits.


Just a theory.
 
To the best of my knowledge all Logix data tags START on a 32-bit boundary. In addition, all data tags have a size that is a multiple of 32 bits. If the basic data type doesn't require 32 bits then the bits not required are not used. Bool arrays are a good example of this as a bool array packs bits into 32-bit groups.

For example, a BOOL (NOT a bool array) an INT, a DINT and a REAL tag would all occupy 32 bits of memory. However, so would a tag defined as a bool array of 3 elements (BOOL[3]) or a 32-element bool array (BOOL[32]). A bool array tag defined as BOOL[33] would occupy 64 bits, as would a BOOL[64] array.

This can get a little squirrelly in a UDT since a UDT will pack like data types as tightly as it can. So a UDT with a single INT would be 4 bytes long. But so would a UDT with two INTS.

A UDT with a single INT and a single BOOL would be 8 bytes long. But so would a UDT with a single INT followed by two consecutive BOOLs. Or two consecutive INTs followed by two consecutive BOOLs.

However, a UDT with a single INT followed by a single BOOL followed by a single INT would contain 12 bytes.

I'm going through this exercise to try and highlight how memory allocation and use in a Logix processor might not be intuitive. The other thing to be REALLY careful of is the use of a COP command with a length that takes you past where you want to go. The processor is more than happy to keep copying data past a boundary you might want to end at. And the only memory that is guaranteed to be contiguous in the Logix PLC are arrays, structures (UDTs and processor defined data types) and strings. other than that you can't make any statements about the location of one tag relative to another in memory.

For example, assume I am going to COP the contents of one 10-element array to another 10-element array but I accidentally type in 100 as the length. Basically, Source A and Source B simply define head pointer to the instruction. The instruction will just start copying bytes from the Source A starting point to the Source B starting point until the appropriate number of bytes is copied. this means things you don't want overwritten will be written to with data from an indeterminate (or very difficult to determine) source. This is especially pertinent with InOut parameters to an AOI since they are themselves passed by reference. So inside the AOI you are not working on a COPY of the data from outside the AOI, you are working on the same data. That can create some fairly odd things to happen as well.

Keith
 

Similar Topics

Hello all, I am facing an issue with my Commander SK that I cannot solve on my own, I am struggling on it since several days :confused: The...
Replies
9
Views
1,071
Hi. I'm doing an upgrade of an old 1400e to a new panel view plus 7 standard using ftv studio v 12,which will be communicating to a slc 5/04 via...
Replies
15
Views
2,643
Can someone explain the jumper between the elements? Does it do anything? See attached jpeg.
Replies
4
Views
693
We have an OPC server getting data from a Compactlogix PLC. The PLC also communicates with a Panelview and a couple VFDs via Ethernet/IP...
Replies
3
Views
1,171
I have a small system controlled by a Siemens S7-1200 PLC. I created a totalizer function block (TIA v17), where I'm counting total revolutions...
Replies
16
Views
3,159
Back
Top Bottom