OPCUA简介

更新时间:2023-07-02 13:54:43 阅读: 评论:0

OPCUA简介
OPC是应⽤于⼯业通信的,在windows环境的下⼀种通讯技术,原有的通信技术难以满⾜⽇益复杂的环境,在可扩展性,安全性,跨平台性⽅⾯的不⾜⽇益明显,所以OPC基⾦会在⼏年前提出了⾯向未来的架构设计的OPC 统⼀架构,简称OPC UA,截⽌⽬前为⽌,越来越多公司将OPC UA作为开放的数据标准,在未来⼯业4.0⾏业上也将⼤放异彩。
在OPC UA的服务器端。会公开⼀些数据节点,或是⽅法等信息,允许第三⽅使⽤标准的OPC协议来进⾏访问,在传输层已经安全的处理所有的消息,对于客户端的访问来说,应该是⾮常清楚简单的。
2.0版本说明
斗鸟更加详细的代码说明可以参照GitHub上的readme⽂件
前期准备
准备好开发的IDE,⾸选Visual Studio2017版本,新建项⽬,或是在你原有的项⽬上进⾏扩展。注意:项⽬的 Framework版本最低为4.6
1Install-Package OpcUaHelper
或者:
然后在窗体的界⾯新增引⽤:
1using OpcUaHelper;
接下就可以愉快码代码了。
OPC UA服务器准备
此处有⼀个供⽹友测试的服务器:p://118.24.36.220:62547/DataAccessServer
当然,⼀般的⽹友都会使⽤Kepware软件,在此处介绍⼀个我⾃⼰开发的OPC UA⽹关服务器,⽀持三菱,西门⼦,欧姆龙,modbustcp 客户端转化成OPC UA服务器,⽀持创建modbus服务器,异形服务器,地址是
节点浏览器
我们在得到⼀个OPC UA的服务器之后,第⼀件事就是使⽤节点浏览器对所有的节点进⾏访问,不然你根本就不知道服务器公开了什么东西,此处我使⽤了⼀个测试服务器,该地址为云端地址,不保证以后会不会继续⽀持访问,⽬前来说还是可以访问的。
⽐如这个地址:p://118.24.36.220:62547/DataAccessServer
OK,然后我们可以使⽤代码来显⽰这个服务器到底有什么数据了!在窗体上新增⼀个按钮,双击它进⼊点击事件,写上
1 2 3 4 5 6 7private void button1_Click(object nder, EventArgs e)
{
using(FormBrowServer form = new FormBrowServer())    {
q版男生form.ShowDialog();
}
}
然后就会显⽰如下的界⾯:在地址栏输⼊上述地址,点击连接(此处能连接上的条件是服务器配置为允许匿名登录):
左边区域可以随便点击看看,可以看到所有公开的数据,⽐如点击⼀个数据节点,下⾯图⽚中的Name节点,右边编辑框会显⽰该节点的ID
标识,这个标识很重要,关系到等会的读写操作。
客户端实例化
洋葱拌木耳的家常做法1
2
3
4
5
6
7
8
9
10
11private  OpcUaClient opcUaClient = new  OpcUaClient(); private  async void  Form1_Load(object  nder, EventArgs e){    await opcUaClient.ConnectServer("p://118.24.36.220:62547/DataAccessServer");} private  void  Form1_FormClosing(object  nder, FormClosingEventArgs e){    opcUaClient.Disconnect();}
如上所⽰,在窗体载⼊的时候实例化,在窗体关闭的时候断开连接。下⾯的节点操作和其他操作使⽤的实例都是这个opcUaClient,如果你连接的服务器是需要⽤户名和密码的,那么修改Load中的代码如下:
1
2
3private  async void  Form1_Load(object  nder, EventArgs e)        {            opcUaClient.UrIdentity = new  Opc.Ua.UrIdentity("admin", "123456");
1await opcUaClient.ConnectServer("p://118.24.36.220:62547/DataAccessServer");
1}
节点读取操作
我们要读取⼀个节点数据,有两个信息是必须知道的
节点的ID标识,就是在上述节点浏览器中的编辑框的信息("ns=2;s=Machines/Machine A/Name")
节点的数据类型,这个是必须知道的,不然也不好读取数据。(“string”)
上⾯的两个信息都可以通过节点浏览器来获取到信息,现在,我们已经获取到了这两个信息,就上⾯的括号⾥的数据,然后我们在新增⼀个按钮,来读取数据:
1 2 3 4 5 6 7 8 9 10 11 12 13private void button2_Click(object nder, EventArgs e)
{
try
{
string value = opcUaClient.ReadNode<string>("ns=2;s=Machines/Machine A/Name");        MessageBox.Show(value); // 显⽰测试数据
}
catch(Exception ex)
{
// 使⽤了opc ua的错误处理机制来处理错误,⽹络不通或是读取拒绝
ClientUtils.HandleException(Text, ex);
}什么真什么作文
}
可以看到,真正的读取数据的操作只有⼀⾏代码,但是此处展⽰了⼀个良好的编程习惯,使⽤atch..,关于错误捕获的使⽤以后会专门开篇⽂章讲解。在展⽰⼀个读取float数据类型的⽰例
护字开头的成语1 2 3 4 5 6 7 8 9 10 11 12 13private void button2_Click(object nder, EventArgs e)
{
try
{
float value = opcUaClient.ReadNode<float>("ns=2;s=Machines/Machine B/TestValueFloat");        MessageBox.Show(value.ToString()); // 显⽰100.5
}
catch(Exception ex)
{
// 使⽤了opc ua的错误处理机制来处理错误,⽹络不通或是读取拒绝
ClientUtils.HandleException(Text, ex);
}
}
其他的类型参照这种写法就⾏,哪怕是数组类型也是没有关系的。
类型未知节点读取操作
我们要读取⼀个节点数据,假设我们只知道⼀个节点的ID,或者说这个节点的类型是可能变化的,那么我们需要读取到值的同时读取到这个数据的类型,那么代码参照下⾯
节点的ID标识,就是在上述节点浏览器中的编辑
节点的数据类型最终由 value.WrappedValue.TypeInfo 来决定,有两个属性,是否是数组和基础类型,下⾯的代码只有int类型进⾏了严格的数组判断,其他类型参照即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40    private void button3_Click(object nder, EventArgs e)
{
Opc.Ua.DataValue value = opcUaClient.ReadNode("ns=2;s=Robots/RobotA/RobotMode");        // ⼀个数据的类型是不是数组由 value.WrappedValue.TypeInfo.ValueRank 来决定的
// -1 说明是⼀个数值
// 1  说明是⼀维数组,如果类型BuiltInType是Int32,那么实际是int[]
// 2  说明是⼆维数组,如果类型BuiltInType是Int32,那么实际是int[,]
if(value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int32)
{
if(value.WrappedValue.TypeInfo.ValueRank == -1)
{
int temp = (int)value.WrappedValue.Value;              // 最终值
}
el if(value.WrappedValue.TypeInfo.ValueRank == 1)
{
int[] temp = (int[])value.WrappedValue.Value;          // 最终值
}
el if(value.WrappedValue.TypeInfo.ValueRank == 2)
{
int[,] temp = (int[,])value.WrappedValue.Value;        // 最终值
}
}
el if(value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt32)
{
uint temp = (uint)value.WrappedValue.Value;                // 数组的情况参照上⾯的例⼦
}
el if(value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Float)
{
float temp = (float)value.WrappedValue.Value;              // 数组的情况参照上⾯的例⼦
}
el if(value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.String)
{
string temp = (string)value.WrappedValue.Value;            // 数组的情况参照上⾯的例⼦
}
猪血圆子el if(value.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.DateTime)
{
DateTime temp = (DateTime)value.WrappedValue.Value;        // 数组的情况参照上⾯的例⼦        }
}
格姆女神}
批量节点读取操作
批量读取节点时,有个⿇烦之处在于类型不⼀定都是⼀致的,所以为了⽀持更加⼴泛的读取操作,只提供Opc.Ua.DataValue的读取,读取到数据后需要⾃⼰做⼀些转换,根据类型来⾃⼰转,参照上⾯类型未知的节点操作代码。
1 2 3 4try
{
// 添加所有的读取的节点,此处的⽰例是类型不⼀致的情况
List<NodeId> nodeIds = new List<NodeId>( );
快板台词nodeIds.Add( new NodeId( "ns=2;s=Devices/分⼚⼀/车间⼆/ModbusTcp客户端/温度") );

本文发布于:2023-07-02 13:54:43,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1064626.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:节点   类型   服务器   读取   数据   数组   操作   参照
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图