简单的OPC与C#通讯,别想复杂了

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OPCAutomation;
namespace OPC
{public partial class Form1 : Form{OPCServer ObjOPCServer;OPCGroups ObjOPCGroups;OPCGroup ObjOPCGroup;string OPCServerName;public Form1(){try{InitializeComponent();OPCServerName = "{Here comes your OPC server’s name,(OPC服务器名称)}";ObjOPCServer = new OPCServer();ObjOPCServer.Connect(OPCServerName, "";);ObjOPCGroups = ObjOPCServer.OPCGroups;ObjOPCGroup = ObjOPCGroups.Add("OPCGroup1");ObjOPCGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(ObjOPCGroup_DataChange);ObjOPCGroup.OPCItems.AddItem("{tag name or address,(标签名称或地址名) (like {plc name on server}!%mw0)}", 1);ObjOPCGroup.UpdateRate = 10;ObjOPCGroup.IsActive = true;ObjOPCGroup.IsSubscribed = true;}catch (Exception e){MessageBox.Show(e.ToString());}}private void button1_Click(object sender, EventArgs e){}private void ObjOPCGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps){for (int i = 1; i <= NumItems; i++){if ((Convert.ToInt32(ClientHandles.GetValue(i)) == 1)){textBox1.Text =  ItemValues.GetValue(i).ToString();}}}private void Form1_Load(object sender, EventArgs e){OPCServerClass GlobalOPCServer = new OPCServerClass();Array ServerList = (Array)GlobalOPCServer.GetOPCServers(""); for (int i = 1; i <= ServerList.Length; i++){comboBox1.Items.Add(ServerList.GetValue(i).ToString());}}}
}

在工业自动化领域,计算机早已成为必不可少的工具,计算机技术的不断发展,大大加速了工业自动化技术的进步,而各种各样的工业控制应用软件正是具体实现这一进程的最重要的工具。

往,应用软件开发商要为每一种硬件开发驱动程序,由于硬件的种类繁多,特征各异,软件开发商的负担异常繁重,尤其是如果硬件特征发生了变化,整个应用软件
相应的驱动程序也要相应地修改,这对软件开发商,对整个工程都是很不利的。而且由于驱动程序的不统一,不同应用程序访问同一硬件设备时常常发生冲突。
OPC(OLE for Process Control)技术标准正是在这种情况下产生的。OPC基于微软的OLE、COM和DCOM技术,而且它本身
就是一种特殊的COM,也正因为有微软的参与,以及以已经成熟的技术为基础,它比一般的工业标准制定的效率更高,它从开始制定到第一个可运行的规范开始运
行,只用了不到一年的时间。
二、OPC原理及应用

OPC技术为工业自动化软件面向对象的开发提供了统一的
标准。它大大减轻了软件开发商的负担,软件开发商不必再为每一硬件单独编写驱动程序,只要硬件的特征符合统一的OPC接口程序标准,或者硬件生产商提供
OPC服务器,如图一所示,不同的应用软件开发商都可以采用OPC标准设计工控软件,以标准规定的统一接口通过OPC服务器存取现场数据。

样,当现场设备发生变化或系统中加入新设备时,OPC服务器的提供商需要重新实现服务器接口,以适应硬件的变化,但由于服务器所提供的接口的一致性,工控
软件不作更改即可继续使用,只是某些情况下可能需要重新组态(如添加新的PLC站点等),这样,软件开发商可以节省大量的时间致力于工控软件的性能方面的
提高,不必再考虑硬件变化带来的影响,大大减小了软件维护的工作量。这正如OPC规范里所说,OPC将应用软件和硬件设备划清了界限。
2.1 OPC基本结构

OPC
服务器有两类接口:定制接口(Custom Interface) 、自动化接口(Automation Interface),定制接口比较低级,它提
供更多的功能,效率也比后者高,可以用C++语言调用此类接口,自动化接口主要用于VB、DELPHI等开发工具。按照OPC规范,定制接口是服务商必须
提供的,而自动化接口则是可选的,不过,OPC基金会(管理OPC标准的国际组织)提供了一个叫做“自动化包装器”的动态连接库,用于在两者间转换。如图
二所示:
在OPC的早期规范里主要包括OPC数据存取规范、OPC报警和事件、OPC历史数据存取规范。OPC数据存取规范详细规定了客户程序
和服务器程序进行数据通信的机制,其它类型的OPC服务器往往是在数据存取服务器的基础上通过增加对象、扩展接口而来的,所以该规范也是其它OPC规范的
基础。OPC数据存取规范规定的基本对象有三类:OPC Server、OPC Group和OPC Item,OPC Server包含服务器的所有信
息,也是OPC Group的容器,OPC Group除了包含它自身信息外,还负责管理OPC Item。它们的结构如图三所示。每一个
OPC Item代表到数据源的一个连接,但它没有提供外部接口,客户端程序无法对OPC Item直接进行操作,应用程序必须依靠OPC Item的容
器OPC Group来对它进行操作,这在下面的程序中会有具体说明。
2.2 OPC数据访问方式

OPC客户程序对
OPC服务器中数据的存取方式分为同步读写方式和异步读写方式。客户程序可按照一定的周期调用OPC Group对象的IOPCSyncIO接口对服务器
程序进行数据同步存取操作,此时客户方的调用函数一直运行到所有数据读写完成,然后才能执行其它操作,因此,这种方法适合与读取少量数据,如果数据多的
话,会使系统处于假死状态,无法进行操作。IOPCSyncIO2是从3.0版才出现的,是对IOPCSyncIO的增强。IOPCAsyncIO2和
IOPCAsyncIO3是异步方式中使用的接口,异步访问时,当客户端对服务器提出访问要求后,立即返回到OPC应用程序执行其它操作,无须等待,当
OPC服务器完成数据读取后通知OPC应用程序,应用程序从而得到数据。其中前者是在2.0版本中新定义的,具有较高的通信性能;后者则是在3.0版本中
才刚刚出现,同IOPCSyncIO2类似,IOPCAsyncIO3是对IOPCAsyncIO2的增强。在异步方式下,服务器程序收到读请求后,调用
客户程序方的IOPCDataCallback接口,将数据发送给客户程序。异步方式中允许服务器将读写操作进行排队,使客户方的调用函数可立刻返回,当
服务器读写操作完成后再通知客户程序。显然,异步通报方式的通信效率更高,这种方式也是本文所要讨论的方式,但有多个客户程序与服务器相连时,同步读写方
式更具时效性。对于每个组对象,客户程序可根据需要采用其中一种数据存取方式,而不能两者都使用。
异步读取还有一种特殊的方式,叫做订阅方式(Subscribe)这种情况下,应用程序不需要发出读请求,OPC服务器在定期更新数据的时候,如果发现数据有一定变化,则自动向应用程序发出通知和传输变化的数据。
2.3 编写OPC客户端应用程序

VB
简单实用,是比较理想的OPC应用程序快速开发工具,若要用VB开发OPC应用程序,必须要使用OPC自动化包装器,这在前文已经提过,这种包装器一般由
OPC服务器的供应商以DLL形式提供,下面就以SIEMENS提供的sopcdaauto.dll为例,介绍如何开发OPC应用程序,这也正是笔者在最
近的工程中实际应用到的,这是基于DA2.0的版本。
首先,新建VB工程后,作图四所示的引用:
2.3.1 建立OPC对象

首先申明OPC对象:
Option Base 1
Dim WithEvents ServerObj As OPCServer ''OPC Server对象,连接OPC服务器
Dim GroupsObj As OPCGroups ''OPC Groups对象,添加OPC组
Dim WithEvents GroupObj As OPCGroup ''OPC Group对象
Dim ItemsObj As OPCItems ''OPC Item集合
Dim ServerHandles() As Long ''服务器端OPC Item的句柄
Dim ClientHandles() as Long ''客户端OPC Item的句柄
Dim ItemId(2) As String
Dim Errors() As Long
接下来,生成各个对象:
If ServerObj Is Nothing Then Set ServerObj = New OPCServer
''连接OPC服务器
If ServerObj.ServerState = OPCDisconnected Then
ServerObj.Connect ("OPC.SimaticNET") ''假设OPC服务器运行在本机
End If
If GroupsObj Is Nothing Then Set GroupsObj = ServerObj.OPCGroups
If GroupObj Is Nothing Then Set GroupObj = GroupsObj.Add
If ItemsObj Is Nothing Then Set ItemsObj = GroupObj.OPCItems
GroupObj.IsActive = True ''设置组为活动状态
''假设有两个数据源,一个是8位开关量输入,一个是8位开关量输出
ItemId(1) = "S7:[S7 connection_1]IB0"
ItemId(2) = "S7:[S7 connection_1]QB0"
ClientHandles(1) = 1
ClientHandles(2) = 2
''添加组项目,ServerHandles数组的值为各个OPC Item的服务器句柄,
'' ClientHandles数组的值为各个OPC Item的客户端句柄,由应用程序设定
Call ItemsObj.AddItems(2, ItemId, ClientHandles, ServerHandles, Errors)

2.3.2异步数据读取

'' OPC Item的服务器句柄,添加OPC Item时由服务器分配
Dim TempServerHandles(1) As Long
''事务标志符,由客户端产生,它包含的信息提供给OnReadComplete事件
Dim TransactionID As Long
''取消标志符,服务器端产生,用于操作需要被取消的时候
Dim CancelID As Long
''包含读取每个OPC Item时返回的信息
Dim ErrorNr() As Long
TempServerHandles(1) = ServerHandles(1) ''对应第一个OPC Item
GroupObj.AsyncRead 1, TempServerHandles, ErrorNr, TransactionID, CancelID
第一个参数是要读的OPC Item的个数,这里只含有一个OPC Item。读取的结果由OPC服务器通过IconnectionPointContainer接口配合IOPCDataCallback接口反调用应用程序的事务处理程序:

Private Sub GroupObj_AsyncReadComplete(ByVal TransactionID As Long, ByVal NumItems As Long, ClientHandles() As Long, ItemValues() As Variant, Qualities() As Long, TimeStamps() As Date, Errors() As Long)
这里的参数ClientHandles和AddItems方法中的ClientHandles是对应的,用于判断哪一个OPC Item在被读取。其它参数的说明如下:
TransactionID:客户端自由使用,应用程序开发商自定义;
NumItems:表示读取的OPC Item的个数;
ItemValues():各个OPC Item连接的数据源的值,类型为Variant;
Qualities():OPC Item的品质值;
TimeStamps():时间戳;
Errors():记录服务器返回的信息。
2.3.3 异步数据写入

Dim TempServerHandles (1) As Long
Dim VValue(1) As Variant
Dim ErrorNr() As Long
Dim TransactionID As Long
Dim CancelID As Long
TempServerHandles(1)=ServerHandles(2)
VValue(1)=1''假设要将“1”写入ClientHandle为2的OPC Item
GroupObj.AsyncWrite 1,TempServerHandles,VValue, ErrorNr, TransactionID, CancelID

同样,AsyncWrite也对应一个事务处理程序:
Private Sub groupObj_AsyncWriteComplete(ByVal TransactionID As Long, ByVal NumItems As Long, ClientHandles() As Long, Errors() As Long)
它的参数的含义和AsuncReadComplete中的含义是类似的,这里一般需要处理的是写数据之后的返回状态,这里不再赘述。
2.3.4断开与服务器的连接

ItemsObj.Remove ItemsObj.Count,ServerHandles, Errors ''清除OPC Item
Set ItemsObj = Nothing ''释放资源,下同
If Not GroupObj Is Nothing Then
GroupsObj.Remove GroupObj.ServerHandle ''删除组
End If
If Not GroupsObj Is Nothing Then
Set GroupsObj = Nothing
End If
If Not ServerObj Is Nothing Then
If ServerObj.ServerState <> OPCDisconnected Then
ServerObj.Disconnect ''断开与服务器的连接
End If
Set ServerObj = Nothing
End If

简单的OPC与C#通讯,别想复杂了相关推荐

  1. Spring Boot 接入支付宝完整流程实战,网友:看完后秒懂,原来是我想复杂了!...

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 作者:李秀才 blog.csdn.net/qq_33556185/article/details/110445827 ...

  2. opc服务器状态红叉,西门子S7-300与上位机通过OPC服务器的通讯设置分解.pdf

    通过PROFIBUS 建立SIMATIC NET OPC 服务器与PLC 的S7 连接 一.基本相关信息 1. SIMATIC NET PC 软件简介 SIMATIC NET 是西门子在工业控制层面上 ...

  3. Labview2019,通讯三菱plc,用opc和mc通讯协议,sqlite数据库,labview标准框架jki状态机,加上数组队列,实现多线程交互。

    Labview2019,通讯三菱plc,用opc和mc通讯协议,sqlite数据库,labview标准框架jki状态机,加上数组队列,实现多线程交互. _:4550670508310561加菲猫眼

  4. tigase集群配置搭建官方方法-xmpp通讯协议配备tigase集群开发简单省事-哇谷即时通讯IM源码服务-哇谷即时通讯源码

    tigase集群配置搭建官方方法-xmpp通讯协议配备tigase集群开发简单省事-哇谷即时通讯IM源码服务 哇谷即时通讯IM云-即时通讯源码-音视频会议-直播-短视频-企业即时通讯办公-聊天app- ...

  5. opc服务器连接plc断开显示,如何判断OPC与PLC通讯失败

    通过PCACCESS或者通过NET方式,连接S7200或者S71200PLC到WinCC,在实际使用过程中,经常出现OPC服务器与PLC连接中断了,可WinCC与OPC服务器的连接确是正常的,唯一能判 ...

  6. 如果是能简单解决的问题,就不用想得太复杂了

    有个朋友在MSN问我说,有没有关于Emit的资料,它想生成一个类的动态代理.他抱怨Emit还是很麻烦,不过交谈过后知道他是想要做什么.他希望为一个对象的某个属性作延迟加载,这样可以避免一些无谓的消耗. ...

  7. rj45接口引脚定义_简单修复数控主机网络接口通讯故障

    中国电路板维修人关注平台:技术分享.学习交流.案例视频.行业招聘资讯 [案例:某品牌数控主机网络接口无法通讯故障维修] 故障现象:网络接口无法使用,IP地址为192.168.1.101 解决方法: 此 ...

  8. MFC:通过代码简单理解进程间的通讯机制——共享内存

    下面用共享映射文件的方式实现进程间通信,代码可以运行. 一.浅理解 每个进程有自己独立的空间,一个进程无法访问其他进程的数据.就好像两个是互不干涉的个体,想让它们进行通信(交换数据),就必须有一段它们 ...

  9. 一个简单的基于socket的通讯处理程序

    2019独角兽企业重金招聘Python工程师标准>>> 这几天看书看得java网络编程,看到一个不错的,适合新手的,部分代码借鉴书上的,可能有地方还不是很成熟,不过可以借鉴一下,分为 ...

最新文章

  1. 31万奖金算法赛事来了!
  2. 智能车竞赛技术报告 | 智能车视觉 - 西安邮电大学 - AI小布丁
  3. 第十六届智能车竞赛创意组比赛-筹划初稿
  4. 神策数据与 UCloud 达成战略合作,开启高效企业服务新模式
  5. 博客园Logo创意之我的朋友弄的
  6. Delta Lake——数据湖的可靠性
  7. leetcode 877. Stone Game | 877. 石子游戏(递归/动态规划/数学解法)
  8. RuoYi-Cloud 部署篇_03(linux环境 Oracle +nginx版本)
  9. 云计算运维累不累_要做好云计算运维管理,一定要注意这3个要点
  10. 20.第一个Netcat的实现
  11. 蓝桥杯2017年第八届C/C++省赛B组第一题-购物单
  12. Java 一维数组 二维数组 三维数组
  13. 二 、 搭建Android 开发环境读书笔记
  14. java 视频上传_java实现大视频上传
  15. er studio mysql逆向生成
  16. MBR分区表详解(SD卡)
  17. Flutter第一天
  18. Unity特效基础:粒子效果面板
  19. 在电脑上下载 Youtube 的视频
  20. 荣耀Magic5 Pro屏幕参数怎么样? 荣耀Magic5 Pro摄像头参数

热门文章

  1. java log4jhelper_log4j的使用
  2. java 线程交替输出,[java]java经典问题之线程交替打印数字
  3. java timer暂停继续_JavaScript暂停和继续定时器的实现方法
  4. 基于python的人脸识别技术_用Python写个简单但强大的人脸识别系统
  5. 下周开幕,给深圳的电子工程师准备的展会!
  6. 单片机的几种数字滤波算法
  7. 推荐一个硬核嵌入式的原创公众号
  8. 聊了一个小时,一名电子专业研究生的困惑
  9. flutter获取Android照片地址,Flutter项目安卓配置启动图片
  10. linux如何移动数据到文件系统,怎么把数据文件从文件系统移动到asm?