Doing some testing for a job being quoted. We tried connecting an RX3i PLC to my local ignition server for it to communicate via the built-in OPC UA server in the PLC. I got Ignition connected just fine (super easy, barely an inconvenience), and was able to read and write data to simple tags. We had issues with PAC giving us fits if we tried to expose an entire data structure to OPC if it had boolean tags in it. Individual boolean tags worked ok. We also tried boolean and real array tags. Even though they were set up as read/write on both the Publish and OPC settings, Ignition couldn't write to them. I was trying to write to individual elements inside the arrays, but kept getting errors that the server didn't support those writes.
I've done some reading and it seems like the thing to do is make individual tags for each array element like I've done in the past and address them accordingly. Thing is, I don't know how to do that with Emerson's OPC server. Here's the OPC Path to the boolean array tag:
nsu=OpcUaServer/PACSystems;s=Test
With A-B array tags, I just need to point it to the right array element, so if it was A-B, it'd be Test[0] or Test[1] instead of test. When I tried this on the Emerson PLC, it didn't work. I tried using .0, [0].0, etc.
Is there a specific format I need to use for the OPC path to make individual tags for array elements, or do I need to script it somehow?
The necessary syntax, if supported by the PLC at all, would be specific to the RX3i. Can you drill down to an array element in the OPC Browser? If you can, use the "copy path" right click menu action. If not, individual array element access is probably not supported.
But again, specific to the RX3i.
It will not drill down. When I browse the OPC server and bring the tag in, it comes in as a boolean array (or float array in the case of the other) and won't accept any other data type. It will READ the array no problem. Not necessarily with Ignition, but I've worked with other OPC servers in the past (I'm probably thinking of RSLinx's awful OPC server actually) where even if you can't browse subelements of a tag, you can manually specify them in the OPC path and they still work. Let's say you have a tag called "integer", you could add a ".0" to the OPC path and it would give you the value of the first bit.
But this is a completely different server of course and the rules don't necessarily apply. I just wondered if anybody familiar with the RX3i would know if it's possible to do the same with.
FWIW, the sales rep who brought the rack in told us it's running a "really old" firmware, so maybe they've fixed some of this in the new version. I'm not optimistic, but maybe.
You might have to write to these boolean arrays (and other arrays) via scripting.
If you write in e.g. the Tag Browser by changing the value for just one of the elements, Ignition will attempt to write using the Index Range parameter of the OPC UA Write service. This is how you target a single element (or range of elements) for a read or write when the type is an array.
Unfortunately some/most servers don't support this. So instead if you have to racily write the entire new array value down. In Ignition the only way to do that is via scripting.
Any plans to expose this for use in system.opc.*
calls?
Or perhaps a generic way to encode that in an OPC Item Path?
Maybe... I've wanted to expose system.opcua
functions for reading and writing that map closely to the service calls, primarily for reading/writing attributes other than value. This would probably be the place to do it.
Every time I look at it though I end up kicking the can down the road because I either need to do some horrible mapping between Ignition/JSON types or do some horrible script namespace hacking like with the BACnet read/write raw functions to make types from the module available to the script author.
Perhaps an additional, optional, OPC tag property for the index range? Combined with allowing a tuple of (item, range)
in lists for script calls that would otherwise take just lists of item
?
The optional property would be cool, not sure how feasible it is in the current implementation. There's no support anywhere in Ignition for using it on the Read service right now, and no way on the existing interfaces to pass that information down.
The scripting functions would be easier to augment. I'll keep that in mind. Still the same issue though with reads - no way to pass the info along. The OPCWriteRequest
interface explicitly includes this info:
/**
* If present, the node identified by {@link #getNodeId()} is an array this
* value should be written to the element or elements at the given {@link IndexRange}.
*
* @return if present, the {@link IndexRange} to write this value to.
*/
default Optional<IndexRange> getIndexRange() {
return Optional.empty();
}
I'll keep this stuff in mind... I'd like to make it possible.
1 Like
Hmmm. A breaking change on the read service? Or perhaps a default implementation?
Too bad big breaking changes should wait for new LTS releases.... 
Just wanted to update this. I got an answer from Emerson Tech support. As it turns out, they added support for the IndexRange parameter in their OPC UA firmware version 11.01. I was using 10.9.
This is documented in the PACSystems Ethernet Communications User Manual (GFK-2224AG), Section 11.1, page 224:
“Starting with PACSystems Firmware release 11.01, controllers that support the Enhanced version of the Baseline Address Space will add all out of bounds scalar variables and array variables to the OPC UA address space…”
1 Like