One of the problems with OPC UA (some would say it’s one the features) is that it is very flexible. There are multiple ways to accomplish things and no one way that is the best. For example, there are at least three ways you can command an OPC UA server to take an action. None of them are perfect or best, they are just alternatives. If you’re a Ph.D. student and need a topic, this is good fodder for a paper if not a thesis. But for us in the real world, we just like to get things done. We want to know how to do something not to hear about a bunch of options to do it.
But with OPC UA there are always lots of options. In previous articles, I introduced the fact that there are (at least) three ways to turn a Modbus device (Modbus TCP or Modbus RTU) into a more flexible OPC UA device. The most common ones are:
OPC UA Native Representation – map the entire Modbus data space to objects in the OPC UA data space with registers and variables having descriptive names that make more sense to the application. You can read that article by clicking on this link above.
Modbus Native Representation – Similar but simpler representation than the OPC UA Native representation.
Modbus Data Transport – A way to convert a Modbus device to an OPC UA device using OPC UA as a transport. Instead of a client using OPC UA Read and Write attribute functionality to read an OPC UA address space, the actual Modbus message packet is sent across the network embedded in the OPC UA transport (whichever one is used). I’ll discuss Modbus Data Transport in a future article.
What’s valuable about Modbus Native representation is its simplicity. Instead of creating an entirely new representation for the Modbus data as objects and attributes, we use the typical Modbus naming convention for registers and coils:
0xxxx is Status Coil Address Space from 00000 to 065535
1xxxx is Input Coil Address Space from 10000 to 165535
3xxxx is Input Register Address Space from 30000 to 365535
4xxxx is Holding Register Address Space from 40000 to 465535
This means that OPC UA Clients can refer to OPC UA Attributes that have the same names as the original registers and coils. The actual structure of the OPC UA address space looks like this:
In this structure there is a Modbus Object folder under the root and ObjsFolders. The Modbus object folder contains all of the data from the original Modbus device. Both registers and coils are contained in the same folder. Clients access these variables by specifying their Attribute name which is the Modbus Address preceded by the string “COIL” or “REG.” It’s much like sending a Read Register or Read Coil command to a native Modbus device.
Notice that each variable is linked to a type definition. The type definition specifies the details of the type. For registers, the type specifies an unsigned 16-bit integer. For coils, the type specifies a bit type. The variable type is important because a Client, uncertain of the type, can follow the link from a variable to determine exactly what the variable is.
This is only one of the many ways to represent Modbus data in an OPC UA device. In the next article in this series, we’ll discuss a different one: using OPC UA as a transport for Modbus data.