OPC Toolbox™ software uses structures to return data from an OPC server, for the following operations:
Synchronous read operations, executed using the read
function.
Asynchronous read operations, executed using the readasync
function.
Data change events generated by the OPC server for
all active, subscribed groups or through a refresh
function
call.
Retrieving logged data in structure format from memory
using the getdata
or peekdata
functions.
In all cases, the structure of the returned data is the same. This section describes that structure, and how you can use the structure data to understand OPC operations.
To illustrate how to use structure-formatted data, the following example reads values from three items on the Matrikon™ OPC Simulation Server.
This example creates a hierarchy of OPC Toolbox objects for the Matrikon Simulation Server. To run this example on your system, you must have the Matrikon Simulation Server installed. Alternatively, you can replace the values used in the creation of the objects with values for a server you can access.
da = opcda('localhost','Matrikon.OPC.Simulation.1'); connect(da); grp = addgroup(da,'StructExample'); itm1 = additem(grp,'Random.Real8'); itm2 = additem(grp,'Saw-toothed Waves.UInt2'); itm3 = additem(grp,'Random.Boolean');
This example reads values first from the device and then from the server cache. The data is returned in structure format.
r1 = read(grp, 'device'); r2 = read(grp);
The data is returned in structure format. To interpret the data, you must extract the relevant information from the structures. In this example, you compare the Value, Quality, and TimeStamp to confirm that they are the same for both read operations.
disp({r1.ItemID;r1.Value;r2.Value}) disp({r1.ItemID;r1.Quality;r2.Quality}) disp({r1.ItemID;r1.TimeStamp;r2.TimeStamp})
By reading first from the cache and then from the device, you can compare the returned data to see if any change has occurred. In this case, the data will not be the same.
r3 = read(grp); r4 = read(grp, `device'); disp({r3.ItemID;r3.Value;r4.Value})
Always remove toolbox objects from memory, and the variables that reference them, when you no longer need them.
disconnect(da) delete(da) clear da grp itm1 itm2 itm3
All data returned by the read
, opcread
,
and getdata
functions, and included in the data
change and read async event structures passed to callback functions,
has the same underlying format. The format is best explained by starting
with the output from the read
function, which provides
the basic building block of structure-formatted data.
When you execute the read
function with a
single daitem
object, the following structure is
returned.
rSingle = read(itm1) rSingle = ItemID: 'Random.Real8' Value: 1.0440e+004 Quality: 'Good: Non-specific' TimeStamp: [2004 3 10 14 46 9.5310] Error: ''
All structure-formatted data for an item will contain the ItemID
, Value
, Quality
,
and TimeStamp
fields.
Note
The Error
field in this example is specific
to the read
function, and is used to indicate any
error message the server generated for that item.
If you execute the read
function with a group
object containing more than one item, a structure array is returned.
rGroup = read(grp) rGroup = 3x1 struct array with fields: ItemID Value Quality TimeStamp Error
In this case, the structure array contains one element for each
item that was read. The ItemID
field in each element
identifies the item associated with that element of the structure
array.
Note
When you perform asynchronous read operations, and for data change events, the order of the items in the structure array is determined by the OPC server. The order may not be the same as the order of the items passed to the read function.
Event structures contain information specifically about the event, as well as the data associated with that event.
The following example displays the contents of a read async event.
cleareventlog(da); tid = readasync(itm); % Wait for the read async event to occur pause(1); event = get(da, 'EventLog') event = Type: 'ReadAsync' Data: [1x1 struct]
The Data field of the event structure contains
event.Data ans = LocalEventTime: [2004 3 11 10 59 57.6710] TransID: 4 GroupName: 'StructExample' Items: [1x1 struct]
The Items field of the Data structure contains
event.Data.Items ans = ItemID: 'Random.Real8' Value: 9.7471e+003 Quality: 'Good: Non-specific' TimeStamp: [2004 3 11 10 59 57.6710]
From the example, you can see that the event structure embeds
the structure-formatted data in the Items
field
of the Data
structure associated with the event.
Additional fields of the Data
structure provide
information on the event, such as the source of the event, the time
the event was received by the toolbox, and the transaction ID of that
event.
OPC Toolbox software logs data to memory and/or disk using
the data change event. When you return structure-formatted data for
a logging task using the opcread
or getdata
function, the returned structure
array contains the data change event information arranged in a structure
array. Each element of the structure array contains a record,
or data change event. The structure array has the LocalEventTime
and Items
fields
from the data change event. The Items
field is
in turn a structure array containing the fields ItemID
, Value
, Quality
,
and TimeStamp
.
For the read, read async and data change events, you must use structure-formatted data. However, for a logging task, you have the option of retrieving the data in structure format, or numeric or cell array format.
For a logging task, you should use structure-formatted data when you are interested in
The “raw” event information returned by the OPC server. The raw information may help in diagnosing the OPC server configuration or the client configuration. For example, if you see a data value that does not change frequently, yet you know that the device should be changing frequently, you can examine the structure-formatted data to determine when the OPC server notifies clients of a change in Value, Quality and/or TimeStamp.
Timing information rather than time series data. If you need to track when an operator changed the state of a switch, structure-formatted data provides you with event-based data rather than time series data.
For other tasks that involve time series data, such as visualization
of the data, analysis, modeling, and optimization operations, you
should consider using the cell or numeric array output format for getdata
and opcread
.
For more information on array formats, see Array-Formatted Data.
If you retrieve data from memory or disk in structure format,
you can convert the resulting structure into array format using the opcstruct2array
function. You pass the structure
array to the function, and it will return the ItemID
, Value
, Quality
, TimeStamp
,
and EventTime
information contained in that structure
array.
The opcstruct2array
function is particularly
useful when you want to visualize or analyze time series data without
removing it from memory. Because peekdata
only
returns structure arrays (due to speed considerations), you can use opcstruct2array
to
convert the contents of the structure data into separate arrays for
visualization and analysis purposes.
Note
You should always retrieve data in numeric or cell array format
whenever you only want to manipulate the time series data. Although
the opcstruct2array
function has been designed
to use as little memory as possible, conversion in MATLAB® software
still requires storage space for both the structure array and the
resulting arrays.
For an example of using opcstruct2array
,
see Write a Callback Function.