Home / PLC / Allen Bradley / Opc client with C#: an how to video

Opc client with C#: an how to video

I made a video where i explain how to connect and read tags from and Opc server using OpcNetApi.dll library with C#.
This post follows a serie of old article that you can read on my old blog.

This code comes from Beckhoff OPC how-to section and if you run a google search of some parts of the code you can find more references and tips about implementing different functions of the API.

You can watch the video here:

Get the sample code

Also you can download the sample application from GitHub.

Share Button

70 comments

  1. Ashwin Ravichandran

    writeValues[0].ServerHandle = group.Items[0].ServerHandle;
    There’s an exception:

    IndexOutofRangeException was unhandled.
    Index was outside the bounds of the array.

    Can you please provide insight to this? 🙂

    Thanks in advance

  2. Is there an exception in my code or you are trying to using my code for your own application?
    Because i just downloaded it and the sample is working, so let me know please.

    Anyway you should put a breakpoint there and check for what array is null or uninitialized.
    If you copied and pasted my code you should check why writeValues array is null (not initialized).
    If you wrote your own write method this is what you will do:

    1 – Create an item to write and create a value for that item (ItemValue)
    2 – Add the item to the group, so he gets the ServerHandle assigned
    3 – Assign the same ServerHandle to the value (your instruction)
    4 – Write();

    When i do this cycle:

    for (int i = 0; i < valueList.Count; i++ ) valueList[i].ServerHandle = groupWrite.Items[i].ServerHandle; i assume that both arrays are initialized ( List valueList = new List(); )
    and of the same lenght (for each item you have an itemValue), else you get an exception because you are doing something wrong.

    That instruction is where i assign the ServerHandle to the ItemValue; without a ServerHandle you can’t write.

    • Can you tell me why this error comes?i am facing the same problem,but unable to understnd the reason why it arises.how can i remove the error?

      • You have two arrays (or list in my sample) of items that must be initialized one by one.
        I mean that before this line:
        writeValues[0].ServerHandle = group.Items[0].ServerHandle;
        you must have somewhere a code like:
        List valueList = new List(); //initialize the List
        ItemValue itemValue = new ItemValue(itemToWrite); //initialize the item at index 0
        […]
        valueList.Add(itemValue); //add the item

        Or if you are using arrays
        ItemValue[] itemValues = new ItemValue[1]; //init array of one element
        itemValues[0] = new ItemValue(); //init the 1st item
        itemValues[0].Value = “1”; // assign the value
        writeValues[0].ServerHandle = group.Items[0].ServerHandle; //assign the server handle

        I think that the most common error is forgetting the init each item of the array.
        The same initialization has to be done with both arrays.

        • Thanks mesta,but this is about writing to the server,how can i read from the server? i cannot get the data from the server…

        • I can’t understand what’s your error.
          Is it an error on this line ? writeValues[0].ServerHandle = group.Items[0].ServerHandle;
          Because this line is needed only when you write to your items.
          Also did you test the OPC Server with a Test client ? Could you read your items with the OPC test client provided by your OPC Server ?

        • writeValues[0].ServerHandle = group.Items[0].ServerHandle ,this line does give an error while writing. But I am not trying to write,I am trying to read the data from opc server. But, even after configuring the aliases and items in the opc server, I am unable to read any data….Kindly help me regarding this

        • Are you able to browse the OPC server through an OPC Test Client (like in this article) ?
          Can you read the values through the OPC Test client ?
          If you can’t read from an OPC Test client maybe it’s because of DCOM configuration.
          If you can browse the OPC server through the OPC Test Client and you can read the values, i can check and correct your code, but i will post it corrected in this site so it will be useful for all people.
          If you think that the problem is in the code that you wrote, just mail me to solution at michelecatta [at] gmail [dot] com.

  3. Excellent write-up on the basics of communicating with hardware using .NET. There’s not a lot of people writing about this online (that I can find). Keep up the great work!

  4. Hi i will try to execute your example and i get an execution time error :

    “Could not load file or assembly ‘OpcRcw.Dx, Version=1.0.1.21, Culture=neutral, PublicKeyToken=9a40e993cbface53’ or one of its dependencies. The system cannot find the file specified.”

    Cand you help me please?

    • This error message is caused by missing or incorrectly installed OPC core components (OpcRcw is a class of the core components).
      To solve the problem, please uninstall the OPC core components (if they are already installed) and then reinstall them.

      The installer can be found in the /Retail/OPC folder on our installation CDs or as a download on the website of the OPC Foundation (www.opcfoundation.org) under ? Downloads ? Redistributables.

      • I have installed the OPC core components downloaded from the OPC Foundation website but still have problem with OpcRcw.Dx which can’t be loaded. Any ideas what I can look for?

  5. Is it possible to create connection between your application and remote OPC serwer ??
    I mean not local network ,but Internet

    • I suppose that if you put the IP address instead of localhost inside the connection string you can connect to the OPC Server on the remote computer.
      I mean a connection string made like this:
      server.Url = new Opc.URL(“opcda://192.168.0.10/RSLinx OPC Server”);
      instead of
      server.Url = new Opc.URL(“opcda://localhost/RSLinx OPC Server”);

      To test the connectivity you should use an OPC test client, like the one provided by RSLinx (like in this article) or Matrikon OPC Explorer, or something else.

      • Ok I understand ,but what IP Port do you use in your program??
        Becuse if I want to connect with OPC serwer in Internet I must use NAT(Network Address Translation) in router.

        • Usually it’s the OPC Server vendor that provide the port name if it’s needed.
          For what i know, it’s needed only the IP of the remote PC to connect to a remote OPC Server; you should also configure the DCOM settings on both PC and configure both firewalls. Again, if there is a port to be open, is the OPC Server vendor that should tell you what port it is.
          To check the DCOM settings run a search on google on “how to configure DCOM for remote OPC server”.
          When you are able to browse the remote OPC server from your test client, you can try to connect to the server using my example.
          An easier way to connect to a remote OPC server is using an OPC Xml client, but i don’t have any example at the moment.
          Hope i helped.

        • I have error :CoCreateInstanceEx: Server RPC Is not accessible .
          Could you tell me what’s reasons??

        • It’s a Windows error, related to firewall and DCOM security settings.
          Check if this post helps you, or try to google the error for an answer.

        • Are you sure that your OPC Clinet is able to connect with OPC server by the Internet. Have you ever tried??
          Because, I heard that OPC Da is not allowed to access by the Internet (DCOM constraints)?

        • @KOMIN: The problem is not if my client works, because my client is a standard client, but it is how to configure DCOM services to go through internet.
          The configuration is far from easy, but both OPC foundation’s forum and Microsoft’s papers can help you with this.
          I suggest you to test the connettivity with an OPC Test client, better if it comes from your vendor. Once you could access to your server through internet, you can start develop your own client.

  6. Hello. Use your example, I’m trying to connect to the OPC server of the company B & R. connect remotely to the server that is running on the device. When I try to connect I get the error:

    “Unable to cast COM object of type ‘System.__ComObject’ to interface type ‘OpcRcw.Comn.IOPCServerList2’. This operation failed because the QueryInterface call on the COM component for the interface with IID ‘{9DD0B56C-AD9E-43EE-8305-487F3188BF7A} ‘failed due to the following error: Interface not supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). ”

    connection string : server.Url = new Opc.URL(“opcda://192.168.0.202/BR.OPC.Server_AR”);

    What do you think about this? Can you help me please?

    • Hi, the error “Interface not supported (Exception from HRESULT: 0×80004002 (E_NOINTERFACE)).” is a generic Windows error. Googling for it shows that can be caused by a bad installation (so you should try to stop the service with “regsvr32 /u + name of B&R dll”; repair or reinstall the OPC server then restart the service with “regsvr32 + name of B&R dll”).
      I think that you should contact B&R anyway, because the support is free for their products, and you can ask them why a common OPC DA client doesn’t work.
      Another test that you should do is also to browse the OPC server through an OPC Test Client from the PC that you are using the application (like in this article). If you can’t browse with a commercial client you can be sure that there are issues with the server or with Windows configuration.

      • Hello everybody , I know winforms very well but know nothing about WPF . can I still use these DLLs and APIs to write an OPC client using C# winform ? Thanks .

        • Yes, you can use the dlls with every .Net project.
          In the example i used WPF because i know it better than WinForms.

        • is there any licencing issue with these DLLs , like i learned to write a MODBUS based SCADA from your website only , and i realized that N-MODBUS library was open source . i am not able to figure out whether these Opc DLLs (OpcNetApi.Com.dll , OpcNetApi.dll ) are free open source or not ? I tried to download it from opc foundation`s website and figured out they are way expensive than a normal 120 tags scada available in the market .

        • OpcNetApi dlls are free to be redistributed, and you can get them from many open source software, or also you can find them included in some of your PLC software.
          The redistribution is permitted in the form of dll. The sources and SDK of OpcNetApi are available only if you are a member of OPCFoundations. In any case, you can’t redistribute the sources.
          Hope it’s clear.

        • i got it . Its not allowed to look inside the DLL`s code written by Opc Foundation but one can develop his own apps using it . seems like a pretty useful stuff. let me make a PLC dance using these DLLs .Thank you thank you …

        • works with wpf or winforms. OPC DA is from 2000 so all that stuff will work.

  7. Thank you, you just saved me having to buy a expensive ******* licence to create connection between my c# software and Siemens S7-300 PLC for this project my company works at.

  8. Hi!
    Mesta Thanx a lot for all your tutorials. They are excellent.

    I have a problem.. In localhost all works well.
    I want to acess my OPC server in a remote computer.
    I configure my firewall, DCOM settings etc and only in made it with a test client in my other computer

    When i try the application in my other PC, it gives the “Could not load or assembly OpcRcw.dx error, reading a bit and i tried installing the new version of core components. x64 x86 builds etc with no sucess for some days now!!

    Can you help me?

    • OpcRcw.dx is a common problem and you can find some solutions inside the comments of this and other posts. Basically you just need to install the redistributables from opcfoundation website.

      • Thank you for the reply.
        I did read the comments… I install the OPC core components but the problem persists… I install the two versions available with no success… x86 x64 on different machines.

        • Did you do any search in your hard drive to see if they are not been installed? usually those files are included in OPC Core Components 3.00 Redistributable.
          Or maybe you can search your other pc where those files are included and install the same program.
          Also, check this link: http://opcf.org/forum/archives/dx.html

        • well i have been trying a lot with no success… Dont have a clue now!! tried almost everything
          always the same error…

          The core components that i installed apear in my uninstaller, but i cant see the folder .

          Thank you very much Mesta for the answers, your site is great!
          Regards

        • If you have Windows 7, check
          C:\Users\[your name here]\AppData\Local\OPC Foundation\Core Components 3.00\

          App Data folder may be hidden, so you have to turn on hidden folder on windows.
          On Windows XP, there is another folder called similar to AppData and hidden too.

        • I have always the hidden folder turned off.
          In my …appdata\local doesnt apear nothing of OPC. Even if in installation i chose C:\

          But i can see in my uninstaller that the core components are installed,

        • Try to uninstall it and reinstall it. You just have to check for what folder it prompt you when you run the installer.

  9. Hello
    Is it possible to use your program in asp.net application?
    Moreover I don’t know where should I put your program in asp.net project and I don,t know how to start transfering date (I mean what event should trigger transfer date)
    Thanks

  10. Hello, it’s very useful example. But i have one question: How connect different group with different updaterate at once? Maybe you have example of it? Thank you!

    • You can create as many groups as you want with the update time that you specify. In this example i created a group to read and a group to write. Just create another read group.

  11. Hi, Mesta,

    Great video. Thanks for all efforts spent.

    But sorry to say I got the same issue of OpcRcw.xx loading failure. I’d checked all comments, and tried to download the core component SDK from OPC foundation. But the earliest version I can get from OPC is V1.0.1.30, while the sample application (the 3 .dll files) required ”
    OpcRcw.Dx, Version=1.0.1.21″.

    Can you instruct where I can allocate these files under specific 1.0.1.21 version? Or, to make all trouble gone, can you upload all OpcRcv.xx files you used in the demo to share?

    Thanks with best!

    • Search for AdvancedHmi on sourceforge, download the latest version, go on Drivers, Support, there you will find a folder that contains all the OPC dlls that you can redistribute. Hopefully they are compatible with the OPC Foundation’s latest version. I will do some tests at home with a new windows installation and see if there is something broken.

  12. Hi, guys! If you stil have problem “Could not load file or assembly ‘OpcRcw.Dx, Version=1.0.1.21, Culture=neutral, PublicKeyToken=9a40e993cbface53′ or one of its dependencies.” Try to install SLIK-DAC_Demo.exe(just use google search for it). I have tried almost everything, but only this installation helps me to solve the problem. May be it helps you too. Good luck!

  13. Should it be groupStateWrite.Active = true; instead of groupStateWrite.Active = false; ?
    In ConnectToServer() ?

    • If you need to read the items value, you set Active = true. Since I need only to write a value then clear the group and add other items, i keep Active = false.I usually have different group for read and write.

  14. Is it possible to get data manualy or to trigger event manually?

    • Groups have a method called Read that returns an array of ItemValue.
      You can choose to use a Read syncronous or asyncronous, depending on the overload of the method Read that you use.

  15. Mesta, can you help me?

    I’m building a c# client for Kepserver V5 with this libraries. I’m using your code as example, it’s reading good, but i can’t add items on Kepserver V5 (Runtime code from server: KEPServerEX\Runtime Attempt to add item ‘PLC1.’ failed)

    The code i use is:

    Connect OPC

    Opc.URL serverUrl = new Opc.URL(opcda://localhost/Kepware.KEPServerEX.V5);
    OpcCom.Factory fact = new OpcCom.Factory();
    server = new Opc.Da.Server(fact, null);
    server.Connect(serverUrl, new Opc.ConnectData(new System.Net.NetworkCredential()));

    Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();
    groupState.Name = “PLC”;
    groupState.UpdateRate = 1000;
    groupState.Active = true;
    group = (Opc.Da.Subscription)server.CreateSubscription(groupState);

    Add items:
    Opc.Da. Item [] items = new Opc.Da. Item [3];
    items[0] = new Opc.Da. Item ();
    items[0].ItemName = “PLC1.Value1” ;
    items[1] = new Opc.Da. Item ();
    items[1].ItemName = “PLC1.Value2” ;
    items[2] = new Opc.Da. Item ();
    items[2].ItemName = “PLC1.Value3” ;
    items = group.AddItems(items);

    Read Items
    // and now read the items again
    group.Read(group.Items, 123, new Opc.Da. ReadCompleteEventHandler (ReadCompleteCallback), out req);
    Console .ReadLine();
    }

    In Kepserver ExV5, i simulate the PLC’s. (Channel1.PLC1.Value1, Channel1.PLC1.Value2….)

    Thank for your help;)

    • Hi Erman,
      it’s difficult to help you without the KepServer, you should ask for assistance to their customer support, because it’s a commercial product and they have to help you.
      By the way to debug this things you need to browse the items with a test client, but you can also do it with OpcNetApi dll.
      Here there is an example:
      http://stackoverflow.com/questions/3727321/c-sharp-opc-client-net-api
      Check also the VB version.
      After you browse the items, you know the exact address and you can add them.
      In my opinion the problem is that you are using a wrong item name and the OPC doesn’t recognize it.

  16. I made an application like yours only to read data from as RSLinx OPC Server.
    It works perfectly. But I have a problem, when the RSLinx loses connection with the PLC i want to display a message in the form. How can I do this? Could you help me?

    • To check disconnections I usually read a bit that in PLC is always one.
      When RsLinx is disconnected from the PLC, the OPC Server read 0, so you can display that the plc is offline.
      Probably there are better way to detect if the plc is online or offline, but this one worked good enough for me.

  17. Richard waterson

    I took you’re example and modified it to run on my test CLX controller. Where can I find the info that explains what the naming conventions are for the ItemName. (.Example:”items[0].ItemName = “PLC1.Value1″) . Kind of like what stuff like “L2 ” means. I want to read and write numbers into large arrays and Im having a bit of trouble.
    Thanks

    • You can use RsLinx Opc test client to browse the items and items name.
      If you need to read/write array, the syntax is like
      array name + "[" + start index + "],L" + lenght that you want to read".
      For example to read the first 5 elements of the array “Sample” starting from the position 0, you write:
      Sample[0],L5

      • Thanks for the response. I like you’re site because its about the only one that relates to what I’m doing. I went ahead and poked around in the RsLinx Opc test client And I think I have the syntax to PLC addressing figured out. I have one more question. I have a Kinect V2 and I am using the depth data coming from the camera to look for defects in panels that move through its view. Right now I am using the advanced HMI stuff (Learned from you’re examples) to write a 512 int array of depth data every 100ms from the Kinect V2 program to the PLC for processing. I want to use the RSLINX OPC to see if I can do this operation with out bogging down the program. My question is how do you move a program array into and OPC array. I can only get just 1 INT from the program to the OPC server at a time.

        Thanks

        • I didn’t make any test, but the property Value of ItemValue is an object, so I think that you can assign an array and you can transfer it.
          The problem with array is that you have to define the size, so if you want to transfer an array of 5 bits you must send exactly 5 bits and declare Sample[0],L5.
          Also you have to be sure that you are sending the correct bytes size, for example C# int is 32bit maps to Rockwell DINT that is 32 bit.

  18. thank you so much bro! From México!!! 🙂

  19. Hi Mesta!

    First of all thank you for this solution, it helped me a lot.

    I have developed an app which works good so far. I used RSLogix 5000 to develop PLC program and Visual Studio Community 2013 to develop C# application. And when the data is changed in PLC everything works perfectly. I even checked RSLinx OPC Server status using OPC Test Client and the Sub Quality is Good.

    Now there is a need for the same application to be used with MicroLogix 1100 so I need to use RSLogix 500. And here I have a problem. When my C# app is not running, OPC Test Client says Sub Quality is Good, but as soon as I start my C# app the Sub Quality becomes Bad and I can’t register data being changed in PLC.

    Do you know what could be the problem? I would really appreciate if you could come up with some solution or a hint. If you need more informations I would be glad to provide them to you.

    • When you create the group in C#, all items contained in the group must have the same name as the ones in the plc. I remember that with RsLogix 5000 you could name the variables with a name, but in RsLogix 500 they was like “[PLC name].[Group name].N7:0”.

      • Thanks for your reply. First I had my variables called like this: [PLC]N7:0.

        My OPC topic is called “PLC”.
        groupState.Name = “myReadGroup”;

        So I tried with [PLC].[myReadGroup].N7:0 and it didn’t work. I also tried [PLC][myReadGroup]N7:0 and that doesn’t work either (in OPC Test Client it says [RSLinx OPC Server]: The Item is no longer available on item [PLC]N7:0).

        Maybe another format?

        • The example was developed using a ML 1400, so I suppose it should work also with ML 1100. You have to try to keep only one address and adjust also other parameters, like refresh rate, and guess what’s wrong.
          Also are you using RsLinx classic or the free one ? Because OPC is supported only if you pay for RsLinx.

        • Thanks for the replies. I’ve managed to find the solution.

          I’m using RSLinx Gateway so that wasn’t a problem. I have many tags and since I have been testing the application I didn’t create all the Data Files in RSLogix 500. For example, I needed to check tag N130:0/4 and I didn’t create Data File N130 in RSLogix 500 (but I did that for 600 other tags and unfortunatelly I forgot about this one :D). I saw an error message in RSLinx by choosing DDE/OPC –> Active Topics/Items… and it came to my mind that I have forgotten to create that particular Data File.

  20. Hi sir, the sample code are no longer available, can you upload it again? Thank you.

Leave a Reply