Best way to structure UDTs

We’re putting together some code practices and I’m working on the Ignition side, and wanted to see people’s thoughts on the ‘best’ way to structure higher-level UDTs. Specifically, if I should aim to nest lower-level UDTs, which might add complication, or keep the UDTs separate, which might lead to unorganized/duplicated tags.

A specific example would be a PID loop, which includes PV, SP, CV, Auto/Manual, etc… The PV might be some temperature reading – which already has it’s own UDT (AnalogIn), which also has nested UDTs for the different alarms (HH, H, LL, L). In the actual PLC code, we move the value from the AnalogIn UDT to the PID PV, so it is duplicated in the PLC so the obvious approach would be to:

  1. Create a UDT instance for the temperature reading, and a separate UDT for the PID loop, without nesting – the PID.PV would be the same as the AnalogIn.ScaledValue. This seems simplest, but I worry that there might be a lot of unnecessary/duplicated tags, so the other option would be to:

  2. Nest the ‘AnalogIn’ UDT in the PID UDT. So any AI tag being used in a higher-level UDT can exist entirely in that UDT instance without duplicating tags. But this will not match the PLC structure exactly, so I’d need to put some custom parameters in there, and I could see it getting complicated, so I’m thinking that it might not be worth the trouble.

Or perhaps there’s a 3rd, even better approach that I’m not thinking of?

1 Like

In your PID example, are you doing a separate set of alarms for the PV of the PID? I wouldn’t expect you to. If that’s the case, I’d probably keep the UDT for the analog input separate from the PID UDT. The analog input PID would do all of the alarming for the input while the PID UDT would be specific to the PID. I would probably still create the “.PV” submember for the PID UDT so that it is available as a value if you want to use it for a faceplate/popup or similar (this will make displaying it similar). I would expect that any alarms that the PID generates will be PID specific (bad configuration, bad input value, etc.).

Nesting UDTs can get complicated and locks you in to a fixed way of working.

I would recommend your option 1, and have a standard AnalogIn UDT with alarms, setpoints etc, and a seperate PID UDT that just references the AI.ScaledValue. There will be more tags, but it seperates the logic better and allows more flexibility. Why does it matter if there are a few more tags if it makes understanding easier. Ignition can handle a lot of tags, so there will be no performance problems.