Thursday, March 24, 2011

OPC client in Asp .NET C#

The goal is to create an OPC client in Asp .Net website to read and write against Kepware KepServerEX and then deploy the website to IIS7.

I got a dll, OPCDAAuto.dll, from a client and I need to utilize this dll to access the KepServerEX 5.2 in order to read and write some values into the PLC module.
For practice purpose, I created a regular website in Visual Studio 2008 and added the reference of the dll, then I used using OPCAutomation; in my project to start coding the OPC client. Here are my testing codes.

// set up some variables
OPCServer ConnectedOpc = new OPCServer();
Array OPCItemIDs = Array.CreateInstance(typeof(string), 10);
Array ItemServerHandles = Array.CreateInstance(typeof(Int32), 10);
Array ItemServerErrors = Array.CreateInstance(typeof(Int32), 10);
Array ClientHandles = Array.CreateInstance(typeof(Int32), 10);
Array RequestedDataTypes = Array.CreateInstance(typeof(Int16), 10);
Array AccessPaths = Array.CreateInstance(typeof(string), 10);
OPCGroup OpcGroupNames;

// connect to KepServerEX
ConnectedOpc.Connect("Kepware.KEPServerEX.V5", "");

Add tags and OPC group.

// set up the tags
OPCItemIDs.SetValue("Counting.PLC.Station1.LoggedON", 1);
OPCItemIDs.SetValue("Counting.PLC.Station2.LoggedON", 2);
OPCItemIDs.SetValue("Counting.PLC.Station3.LoggedON", 3);
OPCItemIDs.SetValue("Counting.PLC.Station1.Operator", 4);
OPCItemIDs.SetValue("Counting.PLC.Station2.Operator", 5);
OPCItemIDs.SetValue("Counting.PLC.Station3.Operator", 6);

// set up the opc group
OpcGroupNames = ConnectedOpc.OPCGroups.Add("Group01");
OpcGroupNames.DeadBand = 0;
OpcGroupNames.UpdateRate = 100;
OpcGroupNames.IsSubscribed = true;
OpcGroupNames.IsActive = true;
OpcGroupNames.OPCItems.AddItems(6, ref OPCItemIDs, ref ClientHandles, out
ItemServerHandles, out ItemServerErrors, RequestedDataTypes, AccessPaths);

Read the values from the server for those tags.

// read
Array ItemServerValues = Array.CreateInstance(typeof(string), 10);
object a;
object b;
OpcGroupNames.SyncRead((short)OPCAutomation.OPCDataSource.OPCDevice, 6, ref
ItemServerHandles, out ItemServerValues, out ItemServerErrors, out a, out b);
Label2.Text = (string)ItemServerValues.GetValue(4);
Label3.Text = (string)ItemServerValues.GetValue(5);
Label4.Text = (string)ItemServerValues.GetValue(6);

Write some values into the server for those tags.

// write
Array ItemServerValues = Array.CreateInstance(typeof(object), 7);
ItemServerValues.SetValue(1, 1);
ItemServerValues.SetValue(1, 2);
ItemServerValues.SetValue(1, 3);
ItemServerValues.SetValue("Test Op 1", 4);
ItemServerValues.SetValue("Test Op 2", 5);
ItemServerValues.SetValue("Test Op 3", 6);
OpcGroupNames.SyncWrite(6, ref ItemServerHandles, ref ItemServerValues, out
ItemServerErrors);

The above codes were running fine in the VS2008, but when I deployed to IIS7, I encountered some errors.
The first error looks like this:

Retrieving the COM class factory for component with CLSID {28E68F9A-8D75-11D1-8DC3-3C302A000000} failed due to the following error: 80040154.

And here is the second error:

Error HRESULT E_FAIL has been returned from a call to a COM component.

I believed these errors coming from the dll. I spent two days to search online and did some try and error. Finally, I figured out I need to twist two settings in the IIS7 to make it run properly.

1. Right click on the application pool to select Advanced Settings. Set "Enable 32-Bit Applications" to True. (This will resolve the first error and let the second error show up.)
2. Also in the Advanced Settings of the application pool, set Process Model -> Identity to LocalSystem. (This will resolve the second error and no more errors.)

I am not sure these changes will affect the security of the web application or not, but since the application is in a closed network environment, I think I don't have to worry about it at this moment.

9 comments:

  1. Thank you so much! worked like a charm! you probably saved me hours of frustration

    ReplyDelete
  2. You can work with OPC in direct .NET way, without COM interop, using
    QuickOPC (http://www.opclabs.com/products/quickopc/languages-and-tools/csharp )

    (disclaimer: this is self-promotion, but is not out of context & might be useful)

    ReplyDelete
  3. Thank you so much! This is useful for me, but now I am trying to connect to remote KepServerEX. What should I do to connect to remote KepServerEX??
    Can you show me the way?
    Thanks in advance.

    ReplyDelete
  4. De gran ayuda el post, muy bueno

    ReplyDelete
  5. I can't write from visual studio to kepware v5

    ReplyDelete
  6. What steps have you taken, and what are the symptoms (error message etc.)?

    ReplyDelete
  7. Can we connect to kepwareEX 6 with this code?

    ReplyDelete
  8. how can I watch the quality object?

    ReplyDelete