Cannot read some tags inside Rockwell AOI

Phil, currently I don’t use UDTs for my AOIs. One, how much more efficient are we talking comparing UDTs to internal AOI data types? I haven’t seen anything abnormal from past projects and have had some high tag counts. Two, what do you do for default values and read/write access if you use UDTs? Having default values has been why I haven’t jumped ship yet. I assume you either don’t use default vales or write code for first pass?

An order of magnitude slower. Or worse if you read many AOI booleans.

A tag created from a normal UDT with no inaccessible members can be read in its entirety in a single tag read request. Up to ~500 bytes normally, or ~4000 bytes with large connections. Same with arrays of such UDTs and/or nested UDTs. Any time you have an algorithm with mixed data types, a regular UDT provides a way to monitor every variable using a subscription that doesn’t have to waste resources by spanning gaps or issuing multiple requests. Have a dozen 40-byte UDTs in an array or as named elements of an outer UDT? With everything within subscribed? A single request gets the whole batch packed together. Do the same entirely with an AOI’s in, out, and local members? Separate requests for every item in every AIO. (Some can be wrapped up in a multiple-service request, but those requests will still contain all of the AIO member names and the responses will have the same overhead for each item.)

Also note that the requests that read large logix tags can still efficiently transfer tags that are larger than the available buffers by using continuation requests. As long as there are no forbidden elements, which means no AOIs allowed.

As to the rest: Regular UDTs do not have default values for members. But you can control external access for individual members. However, if you make anything forbidden (no external access at all), you have the same problem as the AOIs. If you don’t want it accessible, leave it in the AOI.

1 Like

Thanks for the response Phil.

Yes, I know UDTs don’t have default values. I was asking what you do, I’m assuming nothing?

I just came across the topic. We also use AOIs everywhere, and we do have issues with slowness in some PLCs. This seems like something that should definitely be added into the user manual and also perhaps into the gateway as a warning when configuring a “new” Logix device. Those of us who aren’t also software devs doing work with modules, specifically with PLC drivers, and have an in-depth knowledge of AB comms simply won’t know this (such as me).
Do you know the reason rockwell changed from efficient to inefficient AOI comms?

Because they suck! :slight_smile:

Edit, on a serious note, I have noticed slowness on their own products, specifically ME, using AOIs.

1 Like

Well if FactoryTalk is anything to go by… then that’s certainly how it would seem

Then we are all doomed…

That’s just from the unholy alliance with Microsoft.

I don’t know… I can actually do things in most Microsoft products. FT on the other hand, you’re stuck with the limited things that you’re given.

Because it was a security hole you could drive a truck through.


I use first scan rungs where applicable. Habit, as older Logix versions didn’t have default values either, and I try to create AOIs for the least common denominator.

Just to be crystal clear: I am a big fan of Add-on Instructions. I just work around this particular gotcha by moving “public” data into a separate UDT that is passed to the AOI as an in/out parameter.


I guess that’s a pretty good reason :slight_smile:

Thanks to @pturmel recommendations I can confirm that the order of magnitude is correct when moving away from reading AOIs and only reading UDT’s.

What we do is have an AOI that has an In/Out Parameter that is the HMI only UDT. All other tags that are needed in the program outside of the AOI originate from the AOI that way we can differentiate between the two when looking at the code. It has changed the load factor and mean response on logix PLC’s in some respects to a 10th of what they were before. Also being smart with tag groups on the tags. See: CLX performance for information on that.

For default values @jlandwerlen, we have an init bit in the AOI that is default low and when that init bit is high that we set default values in the HMI UDT within the AOI and then set that init bit low.


Yes, thanks Phil.

Good thing is making these changes shouldn’t take very long.

1 Like

Changing things over was easier than I though, even needing to write a little code for default values. But, losing the ability to change values from the AOI faceplate in Studio is a bummer. Not a huge deal to drill into the InOut tag, but it was nice seeing specific tags right there.

Curious what everyone does for naming when using AOI and UDT together. For example, before on a motor AOI I would name it M1000. Now I need an instance tag for the AOI and one for InOut UDT. In the past and currently I’m naming the InOut M1000 and the AOI M1000_AOI. Thoughts??

Well, I usually use three UDTs for my AOIs. The AOI gets the base name (xyz, perhaps) for its functionality. The others:

  • xyz_fbk This is the collection of values that present the process variables, indicators, trigger integers, etc. Subscribed in Ignition with a fast pace, or mapped through my E/IP module from a PLC output buffer.

  • xyz_cmd This is the collection of setpoints and command bits and handshake short integers. Subscribed as needed (slow/leased is fine), but usually mapped to a PLC input buffer with E/IP. If so, can contain momentary buttons driven from my custom component.

  • xyz_cfg This is the collection of configuration items for the AOI, like process/alarm limits, tuning constants, operating modes, etc. Subscribed slow in a leased scan class, so the traffic is only present when the user has the corresponding configuration UI open.

Note that Ignition never writes into the xyz_fbk data, and the PLC never writes to xyz_cmd. This is crucial to avoid race conditions. And it fits well with E/IP I/O configurations.

If someone were to have those 3 UDTs combined into one, but still use the scan classes you defined, what would be the main difference?

Also, do you sort your UDTs in alphabetical order, or in data type order to keep size down? Can I assume either way will have no impact on Ignition?

There will be a big impact.

Aside from the problem with hidden elements, the other major win for optimization is to combine multiple UDTs into as few top-level tags as practical. Either arrays or as nested UDTs (I tend to do the latter, in I/O buffer chunks). This is because subscription optimization only works within a tag, not across multiple tags. If you mix my three into a single UDT, the fast subscription for the _fbk pieces within a larger tag will have big gaps and won’t optimize. The other parts will either go along for the ride (and be discarded every cycle) or will split the request into multiples. Similarly, when copying to/from I/O buffers, you’d need a CPS instruction for each instead of a single CPS for the whole buffer.

And yes, I carefully place elements in a PLC UDT to minimize total size by minimizing gaps. Not necessarily zealously, as that can be a pain on the maintenance side, but I at least put SINTs followed by booleans as a unit. I avoid the use of 64-bit types in newer firmware, as that makes even bigger internal gaps, and cause any UDT containing them to be 64-bit aligned, too.

If this level of complexity makes your head spin, keep in mind that your UDT in Ignition can ignore the existence of the three sub-UDTs on the PLC side, and present them for UI development as if they were merged.

1 Like

Using your example xyz_fbk, if there were 10 tags, and I needed 2 of those to run at a fast pace vs default/normal, would you break them out into another UDT? Basically, all tags in a UDT should belong to the same scan class?