Main Content

Work with Structure-Formatted Data

When Structures Are Used

Industrial Communication 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.

Perform a Read Operation on Multiple Items

To illustrate how to use structure-formatted data, the following example reads values from three items on the Matrikon™ OPC Simulation Server.

Step 1: Create OPC Group Objects

This example creates a hierarchy of OPC 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');

Step 2: Read Data

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);

Step 3: Interpret the Data

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})

Step 4: Read More Data

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})

Step 5: Clean Up

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

Interpret Structure-Formatted Data

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.

Structure-Formatted Data for a Single Item

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.

Structure-Formatted Data for Multiple Items

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.

Structure-Formatted Data for Events

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.

Structure-Formatted Data for a Logging Task

Industrial Communication 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.

When to Use Structure-Formatted Data

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.

Convert Structure-Formatted Data to Array Format

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.