网站标志
导航菜单
当前日期时间
当前时间:
购物车
购物车中有 0 件商品 去结算 我的订单
商品搜索
商品搜索:
文章正文
VC++6.0环境下的OPC通信设计及其在控制系统中的应用
作者:管理员    发布于:2015-08-02 18:42:20    文字:【】【】【
1 引言
随着计算机技术和控制技术的不断发展,现代工业过程控制系统逐渐发展成为现场设备管理,过程管理和商业管理三个层次组成的系统,然而它们之间却存在相互通信的问题,
 其主要问题是不同的计算机系统(DCS,MIS等)的接口不统一、不标准,过程控制系统和信息系统各有专用技术接口以及API(应用程序接口)。尽管可以编写定制的驱动程序和接口程序,但因不同类型硬件及软件包都需相互通信,使得驱动程序的种类迅速地增长,并且连接程序开发没有一个统一、开放的标准,不同程序间易相互冲突。这种情况不仅增加了用户的负担,而且在实际上并不能真正解决不同系统的互操作性[1~2]。出于对上述问题的考虑,1996年8月,一个由自动化领域的领先公司组成的工作组在Microsoft公司帮助下提出了一个基于微软OLE,COM,DCOM,XML,Internet及Net技术的开放的、灵活的、即插即用的工业标准OPC[3]。2 OPC技术简介
2.1 OPC背景
OPC(OLE for Process Control)是基于Microsoft公司的Distributed internet Application(DNA)构架和Component Object Model(COM)技术,根据易扩展性而设计的。OPC规范定义了一个工业标准接口,该标准使得COM技术适用与过程控制和制造自动化等应用领域。OLE原意即对象链接与嵌入,而现在的OLE包含了许多新的特征,如统一数据传输、结构化存储和自动化,已经成为独立于计算机语言、操作系统甚至硬件平台的一种规范。
2.2 OPC接口结构
OPC由两套接口组成:客户端和服务器程序员使用的OPC自定义接口(OPC COM Custom Interfaces);支持用高端商业应用开发的客户程序的OPC自动化接口(OPC OLE Automation Interfaces)。COM接口效率高,通过该接口,客户能够发挥OPC服务器的最佳性能,采用C++语言的客户一般采用COM接口方案;自动化接口使解释性语言和宏访问OPC服务器成为可能,采用VB语言的客户一般采用自动化接口。自动化接口简化客户应用程序的实现,但运行时需要进行类型检查,牺牲了程序的运行速度。OPC自定义接口是服务器必须提供的,而自动化接口则不一定提供。典型的OPC体系结构如图1所示:
图片点击可在新窗口打开查看

图1 典型的OPC体系结构图

2.3 OPC界面关系
OPC技术是实现控制系统现场设备与过程管理级进行信息交互,实现控制系统开放性的关键技术。OPC以OLE/COM机制作为应用程序级的通信标准,采用Client/ Server模式,把开发访问接口的任务放在硬件生产厂商或第三方厂家。以Server的形式提供给Client,并规定了一系列的接口标准,由Client负责创建Server的对象及访问Server支持的接口,从而把硬件生产厂商与软件开发人员有效的分离开来。在这种情况下,硬件制造商、软件供应商以及用户都可得到极大方便[3~4]。
2.4 OPC特点
OPC技术基于Microsoft公司组件对象模型COM(Component Object Modelcom)技术,是为工业标准定义的特殊COM接口, OPC继承了COM技术,具有以下特点:
(1) OPC不是一种计算机语言。它与运行的机器(只要互相连接), 机器的操作系统(只要支持COM)以及软件开发的语言无关,而是任意两个软件组件之间可以相互通信的二进制和网络标准。
(2) OPC服务器是根据COM客户的要求提供OPC SERVER的可执行程序,作为Windows上可执行的文件发布。
(3) COM组件可以以二进制发布给用户。
3 示例:基于OPC规范的连续碳酸化分解优化控制系统设计
连续碳酸化分解过程(以下简称碳分过程)是烧结法氧化铝生产过程的一个承前启后的环节,碳分过程优化控制系统以专家优化计算机EOC、实时监控计算机RMC、现场可编程控制器 PLC形成两级控制结构。专家优化机与实时监控机通过以太网连接,实现检测数据和操作信息的实时交换;现场可编程控制器通过DH+与实时监控机相连;而PLC通过输入模块(A/D、DI)实时采集碳分生产过程的检测信息,又通过输出模块(D/A、D/O)自动调节进料量、CO2通气量的电动阀门,达到稳定优化控制的目的,总体结构如图2所示:
图片点击可在新窗口打开查看

图2 碳分过程优化控制系统总体结构示意图

3.1 连续碳酸化分解系统结构简介
优化控制软件与现场控制器的数据通信流程如图3所示。监控机通过罗克韦尔公司提供的通信软件Rslink直接与现场控制器的A/D模块进行数据交换;优化机与监控机通过以太网相连,两者都安装了 组态软件Rsview,优化机通过组态软件Rsview的OPC规范向监控机读写数据,实时监控软件同样利用OPC规范向优化机的Rsview读写数据,最终实现实时监控软件对现场参数的读取,同时可以调节CO2、进料量以及提料风等电动阀门的开度,实现过程参数调节。
图片点击可在新窗口打开查看

图3 优化软件与现场可编程逻辑控制器数据通信示意图

3.2 实时监控机设置
设置监控机作为OPC服务器:打开Rsview工程,首先设置节点类型。在编辑模式下点击“系统”→“节点”;节点设置时将数据源设置成“直接驱动”的方式,节点名为Rsview的项目工程名,如本项目中Rsiew工程名为“tf.rsv”;其它为缺省项[5]。
然后设置允许数据读取命令:在“编辑模式”下选择“系统”选项,双击“系统”选项,双击“命令行”选项,选择系统命令,弹出图4所示对话框。拉动图4右边滑动条,找到“RTDataWriteEnbable”命令,如图5所示。点击“下一步”按钮。选择“宁静-不显示对话框(Q)”选项,再单击“完成(F)”命令,完成参数设置。
图片点击可在新窗口打开查看

图4 命令行选择对话框

图片点击可在新窗口打开查看

图5 命令行选择对话框

3.3 专家优化机设置
设置优化机作为OPC客户端:打开Rsview工程,在编辑模式下点击“系统”→“节点”;节点设置时将数据源设置成“远程”的方式;节点名为Rsview项目工程名,服务器名为RSI.RSView32OPCTagServer, 服务计算机名或地址填服务器的网络名,如在连续碳酸化分解系统中服务计算机名或地址为“USER”, 其它为缺省项[5]。
3.4 客户端应用程序的实现
在Visual C++环境中实现OPC客户应用程序,首先必须从OPC国际基金会官方网站下载OPC头文件("opcda_i.c"、"opcda.h" 、"opccomn_i.c"、"opccomn.h"),并在Visual C++工程的“Tool”→“Options”→“Directories”加载头文件。然后再进行登陆COM、连接服务器、数据读写等操作。在实际开发中,本文创建一个OPC通信类COPCComm,在需要通信的地方定义COPCComm类对象,然后进行相应的读写操作,其实现流程如图6所示:
图片点击可在新窗口打开查看

图6 基于OPC规范的客户端应用程序的实现流程

下面详细介绍通信类COPCComm的创建过程,并给出关键源代码:
3.4.1 创建OPCComm.h
第一步:在OPCComm.h中预定义_WIN32_DCOM,
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif
包含如下头文件:"opcda_i.c"、"opcda.h"、 "opccomn_i.c"、"opccomn.h"
第二步:申明Iunknown、IOPCServer、IOPCItemMgt、IOPCSyncIO等关键变量为公共变量(public):
IUnknown *pUnknown;
IOPCServer *pServer;
IOPCItemMgt *pOPCItemMgt;
IOPCSyncIO *pOPCSync;
HRESULT *pErrors;
3.4.2创建OPCComm.cpp
第一步:在构造函数COPCComm::COPCComm()中登录COM。
函数CoInitislize()可以完成此功能。从函数CoGetMalloc()得到一个指向COM内存管理接口的指针。
HRESULT rl;
rl =CoInitialize(NULL);
rl =CoGetMalloc(MEMCTX_TASK,&g_pIMalloc);
第二步:添加函数HRESULT COPCComm::ConnectToServer(LPOLESTR ProgID, BOOL IsRemote, IUnknown **ppUnknown),并在函数中实现两个功能:
(1) 将ProgID变换CLSID,每COM服务器有一个字符串类型的ProgID,通过它可以得到全球唯一CLISID。用CLSIDFromProgID()函数可以实现该转换。
CLSID OPCCLSID;
HRESULT hRet=CLSIDFromProgID(ProgID,&OPCCLSID);
//如本系统中ProgID的值是“RSI.RSView 32OPCTagServer”。
(2) 建立与OPC服务器的连接,CoCreateInstance()函数创建一个OPC Sever类实例,其CLSID值设定如下:
hRet=CoCreateInstance(OPCCLSID,NULL,CLSCTX_LOCAL_SERVER,IID_IUnknown,(void **)ppUnknown);
return hRet;
该段程序的结果是得到一个指向服务器对象Iunkown接口的指针变量ppUnknown。
第三步:添加函数int COPCComm::Initial Communication(),并在函数中实现如下几步:
(1) 请求其他接口指针:
从Iunkown接口,通过QueryInterface()方法得到一个指向服务器对象IOPCSever接口的指针变量pServer:
hRet=pUnknown->QueryInterface(IID_IOPCServer,(void **)&pServer);
// 得到一个指向服务器对象IOPCSVerser接口的指针(变量pServer)。
(2) 创建OPC组,
用IOPCSever接口方法AddGroup()实现:
hRet=pServer->AddGroup(L"",TRUE,500,1235,&lTimeBias,&fTemp,0,&hOPCServerGroup, &dwActualRate,IID_IUnknown,&pUnknown);
// 创建一个有指向名称和属性的组。在返回的参数中,有一个指向所需要的进程组对象IOPCItemMgt接口的指针(变量pUnknown )。
(3) 添加项:用IOPCItemMgt接口的AddItems()方法添加具有特殊属性的指定数量的项:
hRet=pOPCItemMgt->AddItems(ItemNumber,ItemArray,(OPCITEMRESULT**)&pItemResult,(HRESULT **)&pErrors);
(4) 用OPC项执行所需的操作,本系统采用同步通信,就需要指向IOPCSyncIO接口指针。
hRet=pUnknown->QueryInterface(IID_IOPCSyncIO,(void **)&pOPCSync);
第四步:添加COPCComm::ReadFromRsview(int AIItemNumber, float fData[]),实现读取数据。
HRESULT hRet;
hRet=pOPCSync->Read(OPC_DS_CACHE, AIItemNumber, hServerAI, &pItemValue, &pErrors);
// OPC项的数据被送到客户程序的IadviseSink接口。
for(int i=0;i<AIItemNumber;i++)
fData[i]=V_R4(&pItemValue[i].vDataValue);
其中,AIItemNumber为一次读入数据的总个数,pItemValue为服务器保存数据的数组,fData为客户端读取数据的数组。
第五步:添加COPCComm::WriteRsview(CString strSend, int iMark),实现数据写入。
COleVariant WriteValue;
HRESULT hRet;
WriteValue = strSend;// strSend为待写的数据
WriteValue.ChangeType(VT_R4);
hRet=pOPCSync->Write(1, &hServerAO[iMark], WriteValue, &pErrors);
//写一个值,iMark表示执行器标号,可由用户自己定义。
第六步:在析构函数~COPCComm()中销毁对象,释放内存,在程序停止运行之前,必须删除已创建的OPC对象并释放内存。
pOPCSync->Release();
pOPCItemMgt->Release();
pServer->Release();
pUnknown->Release();
创建完通讯类后,则可以在需要通信的地方,调用相应的函数(方法)即可。
4 结束语
OPC规范把硬件供应系统和软件开发者分离开来,使得软件开发者不需要过多的了解硬件的实质和操作过程,只要遵循OPC规范进行开发,就可以访问OPC服务器的数据。本文介绍的VC++环境下的客户端应用程序,能够发挥OPC的最佳性能,完全满足过程控制领域对数据实时、高效的要求。如果读者需要全部源代码,可与笔者联系(Email:zhyly805701@163.com)。
浏览 (55) | 评论 (0) | 评分(0) | 支持(0) | 反对(0) | 发布人:管理员
将本文加入收藏夹
新闻详情
脚注栏目
|
脚注信息
机电工程网(C) 2015-2020 All Rights Reserved.    联系我们