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.
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.
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?
Yes. Or move it to the xyz_cfg UDT. The best optimization is for the fast subscribed items to boil down to a request for a single complex tag. Which yields a reply full of packed data. Since the driver browses all of the data types in the PLC, it knows how to unpack it.
Btw, if you struggle with allocating tags to fast/slow scan classes because thereâs just too many to go fast, you might want to consider my E/IP module. I/O buffers simply cannot be beat for snappy data transfer.
It can do thousands of tags at 100ms updates or faster.
Thanks for these ideas; I really like the 3 UDT organizational structure and the improvements to overall tag scans.
Also, for clarity, do you recommend FOR or AGAINST nesting these 3 UDTâs into a higher level UDT (ie: simply âxyzâ⌠so weâd only submit the master UDT to the AOI, and inside it would have the 3 sub UDTâs for example âxyz.Cmd.StartPBâ and âxyz.Fbk.StartLTâ and âxyz.Cfg.TemperatureSPâ )
Iâm not clear about âE/IP modulesâ, âPLC output bufferâ , âPLC input bufferâ, âI/O buffer chunksâ, or âE/IP I/O configurationsâ as eluded to in your text(s). Can you clarify the relationship between your 3 UDTâs and the terms listed above?
<EDIT 5/23/22; I found your website and the E/IP Module. VERY COOL! No need to reply about this.>
Against. These should be nested in arrays or UDTs of the same category (fbk, cmd, cfg), so that polling at the same pace happens with fewer outermost tags. That is the key to optimization.
Just want to make sure that Iâve fully wrapped my head around this.
Say I have multiple devices in a system all set up with UDTâs. Then having a single system_fbk UDT where each device is nested beneath that UDT such that device1_fbk would be called as system_fbk.device1_fbk and device2_fbk would be called as system_fbk.device2_fbk. This would be acceptable?
In Ignition, I can Ignore the system_fbk UDT and simply map each tag as needed and the driver will optimize the read to just the one system_fbk UDT tag, correct (assuming there are no forbidden elements defined)?
I know AOI's have been discussed frequently and I really didn't want to post this but there were times where it was unclear if people meant Ignition vs Rockwell UDT and whether AOI's were 100% not going to work OR if they worked under some scenarios. I also wanted to clarify the act of copying the data over which would be labor intensive from one tag to another tag.
I have an Ignition UDT that directly accesses individual elements of an AOI (let's use analog input P_AIn from PlantPax).
It is my understanding that this is not acceptable and is not optimized even though I directly access the tags.
Is that correct?
Does this affect all AOIs or only certain AOI's?
For example, if I created my own AOI, could I avoid the behavior?
After the UDT is created, I then need to COPY/MOV the files from the tag (P_AIn) to a new tag (CUSTOM_P_AIN_HMI) one at a time (Maybe there is an easier way to do this)
Option 2
Create a new Logix PLC tag and alias the AOI value of interest.
Conclusion
This seems time consuming and requires a lot of manual labor work for an AOI that was supposed to make things easier.
If I have 100 devices that require 30 tags a piece, someone will need to manually enter all 300 tags at some point (even if a UDT is used).
Is there something else I'm missing that would make this easier?
It is access to AOI datatypes in the PLC that cannot be optimized. Doesn't matter if the tags in Ignition are Ignition UDT members or stand-alone tags. This entire topic is about UDTs in the PLC versus AOIs in the PLC.
Ignition's driver cannot bulk read the AOI like it would other UDTs (in the PLC). So every element that is requested (in an AOI, any AOI) will be requested individually. They do work, just much slower. As others have benchmarked, this is about a 10:1 reduction in throughput.
The thing to take home is that, if you're reading a large* number of AOI tags from your PLC, you may have to reduce your scan rate to 2, 3, 5+ seconds which may or may not be acceptable for your application. Certainly for the applications I work on, operators expect 1s scan rates if not faster.
*large means different things for different processors. For an L83, this is something like ~8000+, for an L320ER, it's more like 4-5000+, although don't quote me on these as I haven't specifically tested the limits!
That would definitely help us at the moment, as we're actively looking to convert a massive PLC to using UDTs. What is the estimated timeframe if you have one? Actually, 5 large PLCs, and the PLC programmer would love not to use UDTs as it reduces visibility of AOI values