Download as pdf or txt
Download as pdf or txt
You are on page 1of 16

Understanding OPC Diagnostics

V4.110 and Up Document v1.02

Overview
If you have used KEPServerEX for a while then you have probably seen and used the channel diagnostics. The channel diagnostics are an essential tool in diagnosing communications issues with devices. Likewise, OPC diagnostics, a newer feature, allows us to diagnose the OPC process between the server and a client application.
Note: One of the advantages of OPC diagnostics is the ability to save the diagnostics capture and then open it in the OPC diagnostics viewer again later. This makes it much easier to compare tests.

How to Enable Diagnostics


Diagnostics is enabled or available at the server level. When developing custom client applications or when experiencing problems with an OPC client, it is good practice to use diagnostics to see exactly how the client application is connecting to and requesting data from the server if it is connecting at all. For these examples we used the Kepware OPC Quick Client and the SimDemo project that installs with the server. We manually created 2 client connections and used Disconnect and Connect to initiate connections. We are also only using a couple of items in each connection. 1. In the server main menu, click on View|Diagnostics|OPC to open the OPC Diagnostics window.

KTAN-90041

Page 1 of 16

Start button

Figure 1 button to start capturing OPC diagnostics right away but you will 2. You could click on the Start probably want to take a look at the configuration settings first. Click on Diagnostics | Options to display the Options dialog which displays the configuration settings.

Configuration Settings
Typically you will manually start the OPC diagnostic capture, but if you are launching the server as a service or from a client connection, then you will want to enable it to start on startup. See Figure 2 below and a description of the Options settings.

Figure 2 a. You can decide whether or not OPC diagnostics information should be captured every time the server is started by selecting the 'Automatically start capturing diagnostics on startup' checkbox. Remember that the performance of the server is affected by capturing diagnostic information, as it is an additional layer of processing that occurs between all client/server communications. By default this functionality is turned off. b. You can also decide whether or not to persist the OPC diagnostic information to disk when the server is shutdown by selecting the 'Preserve diagnostics to disk on shutdown'. This can be useful if you need to go back in time to determine where a particular issue may have occurred. You can also create your own backup of diagnostics data at any time through the File -> Save As menu option. By default this functionality is turned on

Page 2 of 16

KTAN-90041

c. Since diagnostic information has an affect on memory/file storage, you can set the maximum number of OPC diagnostic events to be captured at any specific time, by modifying the 'Maximum number of diagnostics to capture'. This value only pertains to the number of events and does not include the number of details, as the detail count for a particular event could be potentially very high. The range for this setting is 1000 to 30000. The default value is 5000.

Filtering
The Filter Dialog allows you to select which events you want to capture. This aids in debugging a particular issue by eliminating events that do not pertain to a particular issue.
Note: Most clients will make continuous GetStatus calls into the server to determine that the server is still available. Filtering this event will simplify the diagnostics data to examine

Figure 3 Each method (e.g., GetErrorString) of every OPC Data Access 1.0, 2.0 and 3.0 interface (e.g., IOPCCommon) supported by the server is available as a filter. You can select a method by clicking the checkbox to the left of the method name. Additionally, you can select all methods of an interface by double clicking the interface name. By default, all methods for all interfaces are selected.
Note: Filter changes apply only to new events captured. Previous events that meet the filter criteria will not be removed from the view.

KTAN-90041

Page 3 of 16

Capturing the Diagnostics


Once you have everything configured you can start to capture OPC diagnostics. In our example we manually started OPC diagnostics and then started our client application so that we could capture the diagnostics from Connect to Disconnect. We are not filtering OPC transactions so ours gets busy very quickly. 3. Start the diagnostics capture. (Figure 4)

Start button

Figure 4 4. Connect your application and you will see each OPC transaction posted in the diagnostic viewer. (Figure 5).

Figure 5 5. If you are going to send the captured OPC diagnostics data to Kepware Technical Support, you will need to save the data. Click on File | Save As in the Diagnostics main menu. You can choose to save the diagnostics as an OPCDIAG file that can be re-opened in the viewer later or, you can save it as a text file to view offline. (Figure 6)

Page 4 of 16

KTAN-90041

Figure 6
Note: We saved our example in both formats and will use parts of the text file in the next section to explain what you are seeing in the diagnostics.

Evaluating the Diagnostics


For the rest of our examples we are going to use excerpts from the saved text file version of the OPC diagnostics. By now you have probably done your own OPC diagnostics and are trying to figure out what it is telling you. In most cases you will be capturing the diagnostics to send to technical support. However the following will explain a little about the file for you.
The default of the diagnostics is to capture and show all of the OPC transactions. If your goal is to verify the adding of Groups and Items as well as how they are polled etc., then you will want to set some filters before doing the capture. See the Filtering section above.

Connecting to the Server


The first transaction of importance is the actual connection of the client to the server. Note that the connection is assigned a Diagnostic Client ID. This is useful if you have more then one client application connecting to the server and only one client is exhibiting a problem. (See Text 1)

6/29/2006 12:08:20:662 PM IClassFactory::CreateInstance () 0000000000: Event started 0000000000: InterfacePointer = 0x01BB3F98 0000000000: [in] pUnkOuter = 00000000 0000000000: [in] iid = {00000000-0000-0000-C000-000000000046} 0000000000: [in] ppvObject = 011CF478 0000000000: Created new server instance. Assigning diagnostics ClientID = 00000004 0000000000: Function succeeded. Result = 0x00000000. 0000000000: [out] *ppvObject = 0x01C34B90 0000000000: Event complete

Text 1

KTAN-90041

Page 5 of 16

Adding the OPC Group


Next, the OPC group is added from the client application. Notice that it has a unique name. OPC group names cannot be duplicated within a client connection. The group is also set to active and the update rate is being set for the group to 1000 msec. (See Text 2) The server then sends a Group Handle ID and a Revised Update Rate back to the client application. The revised update rate is usually the same as the requested update rate unless the requested rate is out of range. (See Text 2) The last thing that you should see with every event like this is an Event complete message. This indicates that the client has acknowledged the response. (See Text 2)

6/29/2006 12:08:20:709 PM [ClientID: 00000004] IOPCServer::AddGroup () 0000000000: Event started 0000000000: InterfacePointer = 0x01D26C10 0000000000: [in] Name = Test1 0000000000: [in] Active = True 0000000000: [in] RequestedUpdateRate = 1000 0000000000: [in] ClientGroupHandle = 0x00A12580 0000000000: [in] TimeBias = 0 0000000000: [in] Deadband = 0.000000 0000000000: [in] LocaleID = 1033 0000000000: Function succeeded. Result = 0x00000000 0000000000: [out] ServerGroupHandle = 0x01D5E378 0000000000: [out] RevisedUpdateRate = 1000 0000000000: Event complete

Text 2

Page 6 of 16

KTAN-90041

Adding the OPC Items


We have added the OPC group so now we have to add the collection of items to be polled by the server for this group. In our example we added 4 items. Of importance are the Item ID, the Requested Data Type, the Active State, and a Client handle number. (See Text 3) A. Count The number of items that were added. B. Item ID This is the item in the server you want to have it poll (Channel_1.Device_1.Tag_3) C. Requested Data Type This how you want the value, for example as a short or a word. This is sent as a value or canonical data type. In the highlighted text the Hex value 0x0002 is for the short data type. (See our application note KTAN-90028, Canonical Data Types.) D. Active State This is set to True so that the server will poll the item automatically. E. Client Handle This is what the server will send back with data change events identifying the item that has changed values.
6/29/2006 12:08:20:709 PM [ClientID: 00000004] IOPCItemMgt::AddItems () 0000000000: Event started 0000000000: InterfacePointer = 0x01D27430 0000000000: GroupName = Test1 0000000000: [in] Count = 4 0000000000: [in] ItemID [0] = Channel_1.Device_1.Tag_3 0000000000: [in] AccessPath [0] = (null) 0000000000: [in] RequestedDataType [0] = 0x0002 0000000000: [in] Active [0] = True 0000000000: [in] ClientHandle [0] = 0x00A26AD8 0000000000: [in] Blob [0] = 0x00000000 0000000000: [in] BlobSize [0] = 0 0000000000: [in] ItemID [1] = Channel_1.Device_1.Tag_2 0000000000: [in] AccessPath [1] = (null) 0000000000: [in] RequestedDataType [1] = 0x0002 0000000000: [in] Active [1] = True 0000000000: [in] ClientHandle [1] = 0x00A23368 0000000000: [in] Blob [1] = 0x00000000 0000000000: [in] BlobSize [1] = 0 0000000000: [in] ItemID [2] = Channel_1.Device_1.Tag_1 0000000000: [in] AccessPath [2] = (null) 0000000000: [in] RequestedDataType [2] = 0x0002 0000000000: [in] Active [2] = True 0000000000: [in] ClientHandle [2] = 0x00A232E0 0000000000: [in] Blob [2] = 0x00000000 0000000000: [in] BlobSize [2] = 0 0000000000: [in] ItemID [3] = Channel_1.Device_1.Bool_1 0000000000: [in] AccessPath [3] = (null) 0000000000: [in] RequestedDataType [3] = 0x000B 0000000000: [in] Active [3] = True 0000000000: [in] ClientHandle [3] = 0x00A0F9C8 0000000000: [in] Blob [3] = 0x00000000 0000000000: [in] BlobSize [3] = 0

Text 3 The server will respond back to the client in the Add time transaction with a Function succeeded Result, and then for each item added an Error code, the canonical data type of the item a Server handle and Access writes. The last transaction is an Event Complete message which is the client acknowledging that it has received the response. (See Text 4)

KTAN-90041

Page 7 of 16

F. Function Succeeded This is a success code for the event. A code of 0x00000000 indicates that all items were added successfully. A code of 0x00000001 indicates that one or more of the items added to the server failed. G. Item Error code If the item was added successfully then this code will be 0x00000000. If it did not get added successfully then you will get an error code like 0x80040005. When an item fails you should check the Server message log for an error as well. H. Item Canonical Data Type This is the numerical code for the Data type of the Item. In the highlighted example 0x0002 is for the Short or signed integer data type, which is what was requested for this item. I. Item Server Handle This is a unique number created by the server for each item that is requested by the OPC client.
Note: If you add the same item to the server 50 times then the server will track it with 50 different Server handles in a database that it creates. Doing this causes the server to use more System RAM and can easily impact the performance of your system.

J.

Item Access Rights This lets you know whether the item is configured for Read/Write (3) or Read Only (1). If it is Read Only then any attempt to write to the device will fail.
0000000000: Function succeeded. Result = 0x00000000 0000000000: [out] Error [0] = 0x00000000 0000000000: [out] CanonicalDataType [0] = 0x0002 0000000000: [out] ServerHandle [0] = 0x01DBBBE0 0000000000: [out] AccessRights [0] = 3 0000000000: [out] dwBlobSize [0] = 0 0000000000: [out] Error [1] = 0x00000000 0000000000: [out] CanonicalDataType [1] = 0x0002 0000000000: [out] ServerHandle [1] = 0x01DBBD88 0000000000: [out] AccessRights [1] = 3 0000000000: [out] dwBlobSize [1] = 0 0000000000: [out] Error [2] = 0x00000000 0000000000: [out] CanonicalDataType [2] = 0x0002 0000000000: [out] ServerHandle [2] = 0x01DBBF30 0000000000: [out] AccessRights [2] = 3 0000000000: [out] dwBlobSize [2] = 0 0000000000: [out] Error [3] = 0x00000000 0000000000: [out] CanonicalDataType [3] = 0x000B 0000000000: [out] ServerHandle [3] = 0x01DBC0D8 0000000000: [out] AccessRights [3] = 3 0000000000: [out] dwBlobSize [3] = 0 0000000000: Event complete

Text 4

Page 8 of 16

KTAN-90041

The Data Change Event


Now that the items are added, you will start getting data change events. (See Text 5) The data change event occurs any time that the value received when polling the PLC has changed from the previous poll or when the item quality changes. A. Group Name This is the name of the OPC group for which the data change event is sent. B. Intializing Call for x Items- This is the number of items sent in the change event. C. Item ID This is the item that is being updated. This is for debugging purposes. This is not part of the data change event that the client receives. D. Client Handle This is how we identify the item in the client. It is the handle that was returned to the client when the item was added. E. Value This is the value of the item now that the value or the quality has changed. F. Time This is the time that the change occurred. G. Quality This is the quality of the data. A value of 0x00C0 (192) indicates that the value that is displayed is from a successful poll of the device. H. Error This is an error code that indicates the possible reason for the bad quality. Typically you will get an error code of 0x80040005 which is a generic error code. This should prompt you to check the server message log. I. Sending Client On Data Change This indicates that the data change was sent to the client application. J. Call Succeeded result This indicates that the client application received the data change event. It will respond with a result code of 0x00000000 that it was successful or 0x00000001 that it failed.

KTAN-90041

Page 9 of 16

6/29/2006 12:08:20:725 PM [ClientID: 00000004] IOPCDataCallback::OnDataChange () 0000000000: Event started 0000000000: InterfacePointer = 0x0019EF74 0000000000: GroupName = Test1 0000000000: Initializing call for 4 item updates. 0000000000: [in] ItemID [0] = Channel_1.Device_1.Bool_1 0000000000: [in] ClientItemHandle [0] = 0x00A0F9C8 0000000000: [in] Value [0] = 0 0000000000: [in] Time [0] = 12:08:20:725 0000000000: [in] Quality [0] = 0x00C0 0000000000: [in] Error [0] = 0x00000000 0000000000: [in] ItemID [1] = Channel_1.Device_1.Tag_1 0000000000: [in] ClientItemHandle [1] = 0x00A232E0 0000000000: [in] Value [1] = 142 0000000000: [in] Time [1] = 12:08:20:725 0000000000: [in] Quality [1] = 0x00C0 0000000000: [in] Error [1] = 0x00000000 0000000000: [in] ItemID [2] = Channel_1.Device_1.Tag_2 0000000000: [in] ClientItemHandle [2] = 0x00A23368 0000000000: [in] Value [2] = 142 0000000000: [in] Time [2] = 12:08:20:725 0000000000: [in] Quality [2] = 0x00C0 0000000000: [in] Error [2] = 0x00000000 0000000000: [in] ItemID [3] = Channel_1.Device_1.Tag_3 0000000000: [in] ClientItemHandle [3] = 0x00A26AD8 0000000000: [in] Value [3] = 142 0000000000: [in] Time [3] = 12:08:20:725 0000000000: [in] Quality [3] = 0x00C0 0000000000: [in] Error [3] = 0x00000000 0000000000: [in] ClientHandle = 0x00A12580 0000000000: [in] TransactionID = 0x00000000 0000000000: [in] MasterQualityResult = 0x00000000 0000000000: [in] MasterErrorResult = 0x00000000 0000000000: Sending client OnDataChange notification. 0000000000: Call succeeded. Client result = 0x00000000 0000000000: Event complete

Text 5

Other Ways to Get Data


Now lets talk about the other ways to read and write to the server. They are Synchronous Reads for Device or Cache and Asynchronous Reads for getting the data. There are Synchronous and Asynchronous Writes for sending data down to the device. We will show you what these methods look like in the diagnostic view. See other Kepware white papers for pros and cons of using the different methods.

Page 10 of 16

KTAN-90041

Synchronous Device Reads


Synchronous Device Reads tell the server to read the request items from the device and return the items whether data has changed or not. See Text 6 and Text 7 for the details of the Synchronous Device Read transaction. A. GroupName Name of the OPC Group Sending the request. B. Source This parameter tells where the read should come from, the device or the disk memory cache. C. Count This is the number of items being requested. D. ServerHandle This is the server handle that was reported back to the client when the item was added to the OPC group.
7/11/2006 5:18:43:829 PM [ClientID: 00000004] IOPCSyncIO::Read () 0000000000: Event started 0000000000: InterfacePointer = 0x01BEF210 0000000000: GroupName = Test1 0000000000: [in] Source = OPC_DS_DEVICE 0000000000: [in] Count = 1 0000000000: [in] ServerHandle [0] = 0x01BF9368 0000000000: ServerHandle 0x01BF9368 -> ItemID = Channel 1.Device 1.Tag 1.

Text 6 E. Function Succeeded This is a success code for the event. A code of 0x00000000 indicates that all items were read successfully. A code of 0x00000001 indicates that one or more of the items to be read in the server failed. F. Error If the date is in error this will have a code that can indicate the reason for the error. G. Value The value from the device or last value if in error. H. Time The time that this items value and quality were updated to the server. I. Quality The current Quality of the data as it was update to the server. J. ClientHandle This is the client handle that the client application assigned to the item when it was added. K. Event Complete This indicates that the client has acknowledged the response from the server and the transaction is now completed.
0000000016: Function succeeded. Result = 0x00000000 0000000016: [out] Error [0] = 0x00000000 0000000016: [out] Value [0] = 972 0000000016: [out] Time [0] = 17:18:43:829 0000000016: [out] Quality [0] = 0x00C0 0000000016: [out] ClientHandle [0] = 0x00A0CD58 0000000016: Event complete

Text 7

KTAN-90041

Page 11 of 16

Synchronous Cache Reads


The Cache read is no different from the device read other then the source parameter that is used. This tells the server to read the last value that was stored in the disk memory cache.
7/11/2006 5:18:47:670 PM [ClientID: 00000004] IOPCSyncIO::Read () 0000000000: Event started 0000000000: InterfacePointer = 0x01BEF210 0000000000: GroupName = Test1 0000000000: [in] Source = OPC_DS_CACHE 0000000000: [in] Count = 2 0000000000: [in] ServerHandle [0] = 0x01BE5B48 0000000000: [in] ServerHandle [1] = 0x01BF9368 0000000000: ServerHandle 0x01BE5B48 -> ItemID = Channel_1.Device_1.Bool_1. 0000000000: ServerHandle 0x01BF9368 -> ItemID = Channel_1.Device_1.Tag_1. 0000000000: Function succeeded. Result = 0x00000000 0000000000: [out] Error [0] = 0x00000000 0000000000: [out] Value [0] = 0 0000000000: [out] Time [0] = 17:18:46:733 0000000000: [out] Quality [0] = 0x00C0 0000000000: [out] ClientHandle [0] = 0x00A0CDE0 0000000000: [out] Error [1] = 0x00000000 0000000000: [out] Value [1] = 975 0000000000: [out] Time [1] = 17:18:46:733 0000000000: [out] Quality [1] = 0x00C0 0000000000: [out] ClientHandle [1] = 0x00A0CD58 0000000000: Event complete

Text 8

Page 12 of 16

KTAN-90041

Asynchronous Reads
Asynchronous reads are similar to the Synchronous read requests in that they return all of the requested item values whether there has been a change or not. The difference is that the client does not wait for the server to complete the read request; instead the server sends an Asynchronous Read Complete message to the client when it has completed the request.

Read Request
Since the read is in 2 parts there are a few differences in the format of the read transaction. See Text 9 for the parts that are different from a Synchronous Read. A. TransactionID This is a unique ID that is provided by the OPC client. If they are sending several read requests this allows the client to verify that it gets a response to each request. B. CancleID This is returned by the server to the client application. The client application can use this ID to cancel these requests before it completes. C. Error You can get errors when making the request of the server for data which are returned here.
7/11/2006 5:18:52:401 PM [ClientID: 00000004] IOPCAsyncIO2::Read () 0000000000: Event started 0000000000: InterfacePointer = 0x01BF0520 0000000000: GroupName = Test1 0000000000: [in] TransactionID = 0x013D3041 0000000000: [in] Count = 4 0000000000: [in] ServerHandle [0] = 0x01BE5B48 0000000000: [in] ServerHandle [1] = 0x01BF9368 0000000000: [in] ServerHandle [2] = 0x01BF3968 0000000000: [in] ServerHandle [3] = 0x01BE65E0 0000000000: Initializing an AsyncIO2::Read transaction. 0000000000: ServerHandle 0x01BE5B48 -> ItemID = Channel_1.Device_1.Bool_1. 0000000000: ServerHandle 0x01BF9368 -> ItemID = Channel_1.Device_1.Tag_1. 0000000000: ServerHandle 0x01BF3968 -> ItemID = Channel_1.Device_1.Tag_2. 0000000000: ServerHandle 0x01BE65E0 -> ItemID = Channel_1.Device_1.Tag_3. 0000000000: Function succeeded. Result = 0x00000000 0000000000: [out] CancelID = 0x01C83360 0000000000: [out] Error [0] = 0x00000000 0000000000: [out] Error [1] = 0x00000000 0000000000: [out] Error [2] = 0x00000000 0000000000: [out] Error [3] = 0x00000000 0000000000: Event complete

Text 9

KTAN-90041

Page 13 of 16

Read Complete
In the read complete message you get the same items in the packet that you do for data change events, plus you get the Transaction ID as well. A client application that is keeping track of these will be able to clear this from its list of outstanding request.
7/11/2006 5:18:52:401 PM [ClientID: 00000004] IOPCDataCallback::OnReadComplete () 0000000000: Event started 0000000000: InterfacePointer = 0x00195E6C 0000000000: [in] Count = 4 0000000000: [in] ClientHandle = 0x00A1DDD8 0000000000: [in] TransactionID = 0x013D3041 0000000000: [in] MasterQualityResult = 0x00000000 0000000000: [in] MasterErrorResult = 0x00000000 0000000000: [in] ClientItemHandle [0] = 0x00A0CDE0 0000000000: [in] Value [0] = 0 0000000000: [in] Time [0] = 17:18:52:401 0000000000: [in] Quality [0] = 0x00C0 0000000000: [in] Error [0] = 0x00000000 0000000000: [in] ClientItemHandle [1] = 0x00A0CD58 0000000000: [in] Value [1] = 981 0000000000: [in] Time [1] = 17:18:52:401 0000000000: [in] Quality [1] = 0x00C0 0000000000: [in] Error [1] = 0x00000000 0000000000: [in] ClientItemHandle [2] = 0x00A11F40 0000000000: [in] Value [2] = 981 0000000000: [in] Time [2] = 17:18:52:401 0000000000: [in] Quality [2] = 0x00C0 0000000000: [in] Error [2] = 0x00000000 0000000000: [in] ClientItemHandle [3] = 0x00A11EB8 0000000000: [in] Value [3] = 981 0000000000: [in] Time [3] = 17:18:52:401 0000000000: [in] Quality [3] = 0x00C0 0000000000: [in] Error [3] = 0x00000000 0000000000: Sending client OnReadComplete notification. 0000000000: Call succeeded. Client result = 0x00000000 0000000000: Event complete

Text 10

Sending Data to the Device


We have seen what it looks like when the server sends updates to the client or responds to a request for data, now lets see what happens when the client application sends data to the device. There are 2 options for sending data and they are via Synchronous or Asynchronous Writes.

Synchronous Writes
Synchronous writes, like Synchronous reads, require the server to execute the write and respond back to the server before doing anything else. Likewise, the client application is waiting for the response before it can do anything else. A. Group Name Group containing the item that is being written to. B. Count Number of items being written. C. ServerHandle Server handle received when the item was added to the server D. Value Value that is being written to the item.

Page 14 of 16

KTAN-90041

E. Result Code This is a success code for the event. A code of 0x00000000 indicates that all items were written successfully. A code of 0x00000001 indicates that one or more of the items failed to be written to. F. Error Any item that failed will have an event code. A typical error code for writes is 0xC0040006 which means the item does not have Write access writes. G. Event Completed This indicates that the client application has acknowledged receiving the update from the server.
Note1: The server does writes one at a time unless you are writing to an array. This means that it can take a long time to complete a Synchronous write transaction if you are writing to a large number of items. Note2: Completion of the write means that the device has accepted the write request for the item, not that it has actually changed the value in its register. The server will not change the value that it is holding in its cache for this item until that item is read and the value is different from the one currently held.

7/11/2006 5:19:02:769 PM [ClientID: 00000004] IOPCSyncIO::Write () 0000000000: Event started 0000000000: InterfacePointer = 0x01BEF210 0000000000: GroupName = Test1 0000000000: [in] Count = 1 0000000000: [in] ServerHandle [0] = 0x01BF3968 0000000000: [in] Value [0] = 1 0000000000: ServerHandle 0x01BF3968 -> ItemID = Channel_1.Device_1.Tag_2. 0000000016: Function succeeded. Result = 0x00000000 0000000016: [out] Error [0] = 0x00000000 0000000016: Event complete

Text 11

Asynchronous Writes
Like Asynchronous reads, Asynchronous writes are comprised of 2 parts: the Write request and the Write complete.

Write Request
Like Reads, the Write request is similar to its synchronous counterpart except that it also has a Transaction ID, a Cancel ID, and an error code if the request is reject by the server.
7/11/2006 5:19:23:067 PM [ClientID: 00000004] IOPCAsyncIO2::Write () 0000000000: Event started 0000000000: InterfacePointer = 0x01BF0520 0000000000: GroupName = Test1 0000000000: [in] TransactionID = 0x013DA821 0000000000: [in] Count = 2 0000000000: [in] ServerHandle [0] = 0x01BF3968 0000000000: [in] ServerHandle [1] = 0x01BE65E0 0000000000: [in] Value [0] = 0 0000000000: [in] Value [1] = 0 0000000000: Initializing an AsyncIO2::Write transaction. 0000000000: ServerHandle 0x01BF3968 -> ItemID = Channel_1.Device_1.Tag_2. 0000000000: ServerHandle 0x01BE65E0 -> ItemID = Channel_1.Device_1.Tag_3. 0000000015: Function succeeded. Result = 0x00000000 0000000015: [out] CancelID = 0x01BE7640 0000000015: [out] Error [0] = 0x00000000 0000000015: [out] Error [1] = 0x00000000 0000000015: Event complete

Text 12

KTAN-90041

Page 15 of 16

Write Complete
The Write complete message contains an error code resulting from sending the request to the device and a completion message when the client application acknowledges that it received the completion event.

7/11/2006 5:19:23:083 PM [ClientID: 00000004] IOPCDataCallback::OnWriteComplete () 0000000000: Event started 0000000000: InterfacePointer = 0x00195E6C 0000000000: [in] Count = 2 0000000000: [in] ClientHandle = 0x00A1DDD8 0000000000: [in] TransactionID = 0x013DA821 0000000000: [in] MasterError = 0x0000 0000000000: [in] ClientItemHandle [0] = 0x00A11F40 0000000000: [in] Error [0] = 0x00000000 0000000000: [in] ClientItemHandle [1] = 0x00A11EB8 0000000000: [in] Error [1] = 0x00000000 0000000000: Sending client OnWriteComplete notification. 0000000000: Event complete

Text 13
Note: The same conditions apply to the Asynchronous write as they do the Synchronous write with one exception. The client does not wait for the write to complete. It is informed when the write is completed by the server and can continue with other tasks after sending the write request.

Summary
So now you understand something about the key OPC transactions. Knowing what is happening can help to solve any number of OPC issues between the client and server. This can also help to identify whether an issue lies in the OPC layer or the device layer. When OPC and Channel diagnostics are used together they can provide a detailed snapshot of the entire automation process.

Page 16 of 16

KTAN-90041

You might also like