当前位置: 移动技术网 > IT编程>开发语言>c# > C#开发OPC客户端

C#开发OPC客户端

2020年01月10日  | 移动技术网IT编程  | 我要评论
第一个随笔,使用了OPEN Live Write,作为客户端.最近使用c#开发一个小软件,主要功能是OPC客户端.以后会开发各类别的协议,作为,协议的转发栈.因为我本人是搞自动化的,所以搞自动化小伙伴像我这样喜欢编程的可能有,但是一般是逻辑思维强,但是底子相对还是弱的.1,C# 开发OPC的准备工作... ...

第一个随笔,使用了open live write,作为客户端.最近使用c#开发一个小软件,主要功能是opc客户端.以后会开发各类别的协议,作为,协议的转发栈.

因为我本人是搞自动化的,所以搞自动化小伙伴像我这样喜欢编程的可能有,但是一般是逻辑思维强,但是底子相对还是弱的.

1,c# 开发opc的准备工作

            软件:vs2019;

            dll:c:\program files (x86)\common files\matrikonopc\common\opcdaauto.dll

            并且将其拷贝到c:\windows\syswow64中,并且使用dll注册.(记得注册必须在这个文件夹中)

            然后在,vs2019的引用添加引用

2, 查看opc手册,不过是英文的vb版本的,以上资料可以在我的百度网盘里面下载.或者私信我.

3, 如何查询 opc服务器数量和连接服务器

 private void btgetlist_click(object sender, eventargs e)
        {
            kepserver = new opcserver();

            messagebox.show(environment.machinename);

            object serverlist = kepserver.getopcservers();



            //枚举网络所有opc服务器并写入combobox控件



            foreach (string turn in (array)serverlist)



            {



                cmbservername.items.add(turn);



            }
        }

4,连接服务器(可以去下载一个matrikonopcsimulation)
 private void form1_load(object sender, eventargs e)
        {
            kepserver = new opcserver();
            kepserver.connect("matrikon.opc.simulation.1");
            if (kepserver.serverstate == (int)opcserverstate.opcrunning)



            {


                tsslserverstate.text = "已连接到-" + kepserver.servername + "   ";
                opcbrowser = kepserver.createbrowser();

            }
            treenode root = treeview1.nodes.add(kepserver.servername);
            root.tag = kepserver;
            opcbrowser.movetoroot();
            showintreeview(opcbrowser,root);
        }

其中主要函数说明:

其同时支持ip或者计算机名的方式

本地计算机第二个参数.第一个参数是服务器名称.

5,对于opcbrower 对象.

          从上面可以看到opcbrowser 来自 opcserver.createbrower(),其主要用来查看服务器相关信息.

         其本身是一个集合(collection),但是,这个时候,其items=0;

        showbranchs():该函数用于将当前节点的名称集合写入到collection中.

        showleafs():该函数用于将当前节点的tags 写入到collection中.

        showleafs(true):将显示该节点下面所有的itemsid--------------很重要,在添加item时可以用到.

private void showintreeview(opcbrowser brower,treenode node)
        {
            treenode childnode = null;
            brower.showbranches();
            int branchcount = brower.count;
            list<string> lst = null;
            if (brower.count>0)
                //回溯的添加branch
            {
                lst = new list<string>();
                foreach (string t in brower)
                    lst.add(t);

                foreach (string branch in lst)
                {
                     childnode = new treenode(branch);
                     childnode.tag = brower.getitemid(branch);
                     node.nodes.add(childnode);
                     brower.movedown(branch);
                     showintreeview(brower, childnode);
                     brower.moveup();

                 }
            }

            brower.showleafs();
            int leafscount = brower.count;
            foreach (string leaf in brower)
            {
                childnode = new treenode(brower.getitemid(leaf));
                childnode.tag = brower.getitemid(leaf);
                node.nodes.add(childnode);


            }


        }

这样就可以把服务器的信息读取到树里面了.

brower对象主要作用就是可以知道服务器里面的信息了.

6,group对象及item对象.

首先:需要创建group对象:

 private void button3_click(object sender, eventargs e)
        {
            kepgroups = kepserver.opcgroups;
            kepgroups.defaultgroupisactive = true;
            kepgroups.defaultgroupupdaterate = 200;
            kepgroups.defaultgroupdeadband = 0;
            kepgroup = kepgroups.add("mxb");
            kepgroup.issubscribed = true;
            kepgroup.datachange += new diopcgroupevent_datachangeeventhandler( datachangehandlerfunc);
            kepitems = kepgroup.opcitems;
            //
            kepitem = kepitems.additem("random.arrayofreal8", 1);
            textbox1.text = kepitem.serverhandle + ":" + kepitem.requesteddatatype;





        }

说明:

如果该参数是issubscribed=true;则其支持订阅功能:也就是当改组中的参数有改变的时候,其会触发datachange事件.

其中:itemid是一个关键的参数,可以通过 opcbrower.showleafs(true)查看.

additem(string itemid,int clienthandle):其中client handle是客户端自行填写的.

一个item 有一个serverhandle,由服务器提供,itemid:由服务器提供;clienthandle:由客户端提供.

事件处理函数

 private void datachangehandlerfunc(int transactionid, int numitems, ref array clienthandles, ref array itemvalues, ref array qualities, ref array timestamps)
        {
            //
                for(int i = 1;i<=numitems;i++)
            {
                if((int)clienthandles.getvalue(i) == kepitem.clienthandle)
                {

                    dynamic t = itemvalues.getvalue(i);
                    object[] ary;
                    ary = array.convertall<double, object>(t, new converter<double, object>((x) =>x));
                    listbox1.items.clear();
                    listbox1.items.addrange(ary);


                                    }
            }

         }

使用该函数可以快速定位数据变更的item.注意:所有的array都是1开头的,所以不能直接转换成int[]或者double[];需要编写一个转换

的函数,转换成object[].另外,需要注意到 clienthandles虽然是一个int数组,但是是无法直接转换到int[]的,因为首先,其起始index=1.

其他还有一些异步写入啊,什么的,可以参考手册.

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网