Communicating with Rockwell Controllers Part I: Optimizing User Defined Types

The Logix5000 Family

This two part series focuses on using Rockwell ControlLogix, CompactLogix, and similar controllers programmed by RSLogix5000 / Studio5000. These will collectively be referred to here as "CLx". Note that Rockwell controllers in other families lack some of the features discussed below.

User Defined Types

User Defined Types (UDTs) allow data of different types to be combined into a single controller tag. UDTs are useful to:

  • Organize data within a controller.
  • Reduce development time for multiple similar devices.
  • Combine data to be transferred as one tag between AOIs (Add-On-Instructions).
  • Combine data to be transferred as one tag for processors-to-processor communication.

UDTs may not be modified on-line. Changing them requires a download, so plan ahead!

UDT Member Order

The order in which members of UDTs are listed determines their order in memory. Poorly ordering members wastes memory - it consumes bits in memory and network traffic that transfer no useful information.

Fully utilized and optimized UDT Rockwell Controller | Cross Company

Follow these rules to optimize UDT memory usage:

  • CLx processors are 32-bit, so memory is handled in 32-bit chunks (the red lines in these screen shots indicate transitions between 32-bit words).
  • BOOLs consume 1 bit, SINTs (small integers) consume 8 bits or one byte, and INTs consume 16 bits or two bytes. All other data types, including atomic types DINT (32-bit double integer), REAL (32-bit floating point) & LINT (64-bit long integer for date/time stamps), as well as all complex types, consume memory in multiples of 32 bits.
  • If you add a BOOL to a UDT, always add at least eight BOOLs together.
  • If you have an odd multiple of 8 BOOLs, add an odd number of SINTs before them.
  • Round out sections of the UDT with BOOLs, SINTs, and INTs that do not consume a multiple of 32 bits with more of those types to reach exactly 32 bits.
  • INTs must start at the beginning of a 32 bit section or on the 16th bit. If you have two SINTs and an INT, or an INT followed by two SINTs, that consumes 32 bits. But if you have a SINT, then an INT, then a SINT, that consumes 64 bits, with 32 of them wasted.

8 wasted bytes UDT Rockwell Controller | Cross Company

  • Generally, simply grouping types together will minimize waste without doing any counting or adding spares.

Improved UDT but not optimized Rockwell Controller | Cross Company

  • Switching back and forth between types - especially between 32+bit and BOOL types - will maximize waste.

16 wasted bytes UDT Rockwell Controller | Cross Company

  • There are many reasons to COPy a portion of a UDT. CLx does not allow a COPy to start with a BOOL, but if there are BOOLs after the first member being copied, they will copy. The length of the copy is determined in multiples of the destination type referenced. Implications:
    • If the first member of a UDT is a BOOL, it cannot be COPied unless the entire UDT is COPied.
    • If the first member to be COPied is an INT, you can only COPy an even number of bytes to another instance of the same UDT (you could copy an odd number if the target is an array of SINTs or a different UDT with a SINT as the first member of the destination).
    • If the first member to be COPied is anything other than a SINT or INT, you can only COPy to another instance of the same UDT in chunks of 4 or more bytes.
    • Therefore, I recommend starting all UDTs with SINTs, then BOOLs, then INTs, then everything else. And if the UDT is for communication purposes, the first SINT should be the HB.

Add-On-Instructions Are Different

The above guidelines apply to UDTs. AOI parameters have some similarities to UDT members, but AOI parameter ordering is not important - that information is automatically optimized for memory consumption, and is not necessarily stored in memory in the same order the parameters appear.

Nested UDT Members

If a controller has multiple identical pieces of equipment with many pieces of data, it often makes sense to create a UDT for one piece of equipment, then a large main UDT containing an instance of the equipment UDT for each piece of equipment - and spare instances if there is the slightest possibility that more might be added.

Nested UDT Rockwell Controller | Cross Company

UDTs and AOIs

You can nest AOI instances inside UDTs. All Input and Output parameters will be visible. In/Out parametes do not “live” in the AOI, so they will not be part of the UDT. If the AOI has local tags, they will consume memory in the UDT, but will not be visible.

UDTs and other complex types can only be In/Out parameters for AOIs - not Inputs or Outputs. But if you want a UDT to “live” in an AOI, add it as a local tag. It will not be visible to outside logic. It can be visible to an HMI or outside controllers if its External Access is changed from the default “None” to “Read Only” or “Read/Write”. And you can make atomic type (BOOL, SINT, INT, DINT, and REAL) members of the UDT visible to outside logic by creating parameters aliased to those members.


User Defined Types are a great tool to organize a wide variety of data into single CLx tags. Proper ordering of members will avoid wasting memory and allow greater flexibility in copying portions of the UDT.

Contact Cross Company

Chris Hardy is an electrical engineer out of Georgia Tech. At Cross Company Integrated Systems since 1994, Chris has process control experience with boilers, alternative energy, water/waste water, chemicals, pharmaceuticals, security, textiles and automotive. Chris also programs controllers/HMIs and writes custom windows applications for communication, data collection, display, trending and reporting.