These four steps produce an L5X ready for Studio 5000 import. The full guide below covers every option in detail.
Overview
The UDT Library is the catalog of User-Defined Type definitions that PLCflow’s generation modules read from. When I/O Code emits a motor instance, it references the matching UDT from the library. When Alarm Code emits an alarm, it references an ALARM-category UDT. When Parameter Code emits a setpoint, it references a PARAMETER-category UDT.
System UDTs are included on every account (UDT_MotorSimple, UDT_MotorVFD, UDT_ValveDiscrete, UDT_ValveAnalog, UDT_SensorAnalog, UDT_Setpoint, ALARM_UDT) and cover the common device classes. Uploading custom UDTs from L5X, or building them in the editor, requires Pro. Free-tier accounts can browse and use the system UDTs but cannot add custom ones.
Step 1. Browse the library
Open UDT Library from the dashboard. The page is a table with one row per UDT, columns: Name, Category, Members (clickable count), Scope, Description, and Edit / Delete actions on each row.
Two filter dropdowns at the top:
- Scope. User Library (active) or Project Library (coming with Projects).
- Category. One of
DI,DO,AI,AO,VALVE,MOTOR,VFD_MOTOR,ALARM,PARAMETER, orAll. The category determines which generation module’s dropdown surfaces the UDT.
Click any row’s Name to open the details dialog. For a User-scope UDT this opens in edit mode (full editing). For a System UDT it opens in view mode. You can read the structure and adjust default values on each member, but cannot rename or remove members.
Step 2. Add a new UDT
Pro and above. The Upload UDT and New UDT features are only available the Pro plan and above. The system UDTs remain usable on Free tier; you just can’t add your own.
Upload UDT
Click Upload UDT in the top-right. The dialog accepts a single .L5X file containing one or more <DataType> elements.
In the dialog:
- Drop or browse for the
.L5Xfile (UDT export, AOI export with embedded UDTs, or program export; anything withDataTypeelements). - Set the Category for this UDT. It determines which generation module sees the UDT.
- Optionally set a Name Override if you want to rename the UDT during import.
- Click Upload. The UDT lands in your User-scope library.
New UDT
Click New UDT to open the editor with a blank UDT. The dialog has three sections:
- Identity. Name (must be unique within scope), Category, Description.
- Required Fields. Generator slots specific to the selected Category (see below).
- All Members. The full member list: name, data type (
BOOL,BIT,DINT,INT,SINT,REAL,STRING,TIMER,COUNTER), default value, description, required flag.
Click Add Member to append a row. Click Create UDT when done.
Binding members to generator slots
Each Category has a set of generator slots the modules need filled. For example, a MOTOR-category UDT needs members bound to the “run command”, “run feedback”, and “fault” roles. The dialog shows these slots in a Required Fields panel with a dropdown next to each one; pick which of your members fills each slot. Required slots show an orange marker; optional ones are grey.
Validation runs on save: a required slot left unbound blocks the save with a message naming the missing slot. Members not bound to any slot are kept as internal and emitted as part of the UDT but not driven by the generator.
Step 3. Edit existing UDTs
For User-scope UDTs, click the pencil icon on the row. The dialog opens in edit mode. You can rename members, change data types, add or remove members, rebind slots, and update defaults. Click Save Changes.
For System UDTs, the pencil icon is disabled (greyed out). Clicking the Name opens the dialog in view mode. You can still Save Defaults to set per-account default values for the system UDT’s members, but the structure itself cannot be modified.
Click the trash icon to delete a User-scope UDT. The confirmation dialog warns: “Tags referencing it will be orphaned.” Saved generation sessions that reference the UDT will fail to load cleanly until you fix the reference.
Step 4. Using the UDTs
Every generation module reads UDTs of the matching category at run time:
- I/O Code reads
MOTOR,VFD_MOTOR,VALVE,AI,AOUDTs for each device row. The UDT column dropdown on each row in the editor lists every available UDT for that device type. Free tier uses the system UDTs (UDT_MotorSimple,UDT_ValveDiscrete, etc.); Pro+ uses your custom uploads in addition. - Alarm Code reads
ALARM-category UDTs. Default isALARM_UDT; Pro+ accounts can pick custom alarm UDTs that share its role structure. - Parameter Code reads
PARAMETER-category UDTs. Default isUDT_Setpoint; Pro+ accounts can pick custom setpoint UDTs with extra members (engineering units, scaling fields).
To change a UDT’s structure, edit it in UDT Library. The next generation run picks up the new definition. Already-downloaded L5X files have the old structure baked in; re-generate to refresh.
Common pitfalls
- Wrong Category on the UDT. Categories are scoped per device class. A UDT in the
MOTORcategory will not appear in theVALVErow’s dropdown. If your custom UDT shows up in the library but not in the editor’s UDT column for the device you expected, this is usually why. - Required slot left unbound. The save button stays disabled until every required generator slot has a member bound. The dialog names the specific slot; pick a member from its dropdown and the validation clears.
- Renaming a member used by a saved session. Saved generation sessions capture the UDT name plus the row’s UDT reference. Renaming a UDT or changing its structure can break a previously-saved session’s load. Re-save sessions after major UDT changes.
- Treating system UDT defaults as immutable. Click the system UDT’s name to open it in view mode and tweak member defaults. This customizes the system UDT for your account without duplicating it.
FAQ
How many UDTs can the library hold?
There is no hard limit. Most accounts have under 30. Categories filter the list so the UI stays usable as the count grows.
Can I share custom UDTs across team members?
User-scope UDTs are visible only to the user who created them. Project-scope UDTs (visible to everyone on a project) ship with the Projects module. Org-wide libraries are on the roadmap. In the meantime, export a UDT to L5X from Studio 5000 and have each team member upload it.
Does the library support nested UDTs (a member with type = another UDT)?
The editor’s data type dropdown is limited to Logix primitive types (BOOL, BIT, DINT, INT, SINT, REAL, STRING, TIMER, COUNTER). Nested UDT references come through on L5X upload (PLCflow preserves them), but you can’t choose another UDT as a member type when building from scratch in the editor.
Can I import UDTs from an Ignition JSON file?
Not directly. The UDT Library upload dialog accepts .L5X only. For the Ignition JSON to Rockwell direction, the backend supports the conversion but the UI does not currently expose the JSON intake; reach out at [email protected] if you need it unblocked.
What happens to old generations when PLCflow updates a system UDT?
Already-downloaded L5X files have the old UDT structure baked in. New generations use the updated system UDT. If your shop needs a frozen baseline, upload your own copy of the system UDT into User scope and reference that one.
Related
- Tag Database. Tags reference UDTs by name. Set up the library first, then bulk-import tags that reference your UDTs.
- I/O Code, Alarm Code, Parameter Code. The three primary consumers of library UDTs.
Related modules
Library of reusable device, alarm, and parameter definitions. Tags defined here can be pulled into any code generation module via Import from DB.
Generate a Studio 5000 routine from an I/O list. Upload a spreadsheet, paste from one, or add rows by hand. Output is an importable L5X with tags, UDTs, and AOIs bundled in.
Define alarm conditions in a table. Get a Studio 5000 routine bundling the ALARM_UDT, alarm tags, and detection logic into one importable L5X.
Define setpoint parameters with initial value and min/max bounds. Generate a self-contained Studio 5000 routine with UDT_Setpoint instances, AOI_Setpoint calls, and the supporting tag definitions.
Honest feedback. We read all of it.