当前位置:网站首页>C#开发OPC客户端
C#开发OPC客户端
2022-04-22 19:22:00 【平山CP3】
背景:做一个系统要对接OPC,所以要学习一下OPC客户端的开发。
解决:OPC实际上是为了给工业控制系统应用程序之间提供一种接口规范。作为使用最多的对接技术,OPC具有它的优势,硬件供应商只需提供符合OPC标准的server,安装到windows服务器上,软件提供商编写OPC的客户端,只需对接业务中OPC项对应的数据项即可完成对接。
C#开发OPC客户端,采用的是自动化接口(即OPCDAAuto.dll这个引用集);当然开发的话需要在机器上注册需要的程序集。

然后配置DCOM的权限,可以搜一下OPC下DCOM的权限设置。
然后就是在程序上进行开发了。
OPC客户端流程(当然这是我们这业务的流程,具体可以按OPC的属性方法增删过程)

Demo:
using OPCAutomation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace OpcClient
{
class Demo
{
#region 变量
//OPCServer的IP
private String strHostIP;
//OPCServer名称
private String strOpcServerName;
//OPCServer的主机名
private String strHostName;
//是否和OPCServer建立连接
private Boolean opc_connected;
//建立的OPCServer对象
private OPCServer myServer;
//OPCServer节点浏览器
private OPCBrowser myOPCBrowser;
//分组集合
private OPCGroups myGroups;
//分组实例
private OPCGroup myGroup;
//分组的TAG节点
private OPCItems myItems;
//服务端句柄
int itmHandleServer = 0;
//要写入的叶子节点
private OPCItem[] myItemArray;
//tag点集合
private Dictionary<string, string[]> dictitems = new Dictionary<string, string[]>();
#endregion
private void Connect()
{
//通过IP来获取OPC服务器主机名
IPHostEntry ipHostEntry = Dns.GetHostEntry(strHostIP);
strHostName = ipHostEntry.HostName.ToString();
//实例化OPC服务
myServer = new OPCServer();
//获取OPCServer列表
object serverList = myServer.GetOPCServers(strHostName);
//根据选择的OPCServer进行连接
myServer.Connect(strOpcServerName, strHostIP);
//实例化Tag浏览器
myOPCBrowser = myServer.CreateBrowser();
//展开分组
myOPCBrowser.ShowBranches();
List<string> liststr = new List<string>();
foreach (object turn in myOPCBrowser)
{
liststr.Add(turn.ToString());
}
liststr.Sort((x, y) => -x.CompareTo(y));
myGroups = myServer.OPCGroups;
//添加自定义分组
myGroup = myGroups.Add("TestGroup");
//设置缺省的组属性
myServer.OPCGroups.DefaultGroupIsActive = true;
myServer.OPCGroups.DefaultGroupDeadband = 0;
myGroup.UpdateRate = 2000;//
myGroup.IsActive = true;
myGroup.IsSubscribed = true;
//定位需要发送数据的目标项
myItems = myGroup.OPCItems;
//实例化组内标签
myItemArray = new OPCItem[1];
//监听组内数据变化
myGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(myGroup_DataChange);
myGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(myGroup_AsyncWriteComplete);
for (int i = 0; i < liststr.Count; i++)
{
//填充项目组
//myItemArray[0] = myItems.AddItem(lstItems.Text, 4148120);
myItemArray[0] = myItems.AddItem(liststr[i], i);
//获取服务端句柄
itmHandleServer = myItemArray[0].ServerHandle;
string[] strarr = new string[3];
strarr[0] = itmHandleServer.ToString();
strarr[1] = i.ToString();
strarr[2] = "";
dictitems.Add(liststr[i], strarr);
lstItems.Items.Add(liststr[i]);
}
}
/// <summary>
/// 每当项数据有变化时执行的事件
/// </summary>
/// <param name="TransactionID">处理ID</param>
/// <param name="NumItems">项个数</param>
/// <param name="ClientHandles">项客户端句柄</param>
/// <param name="ItemValues">TAG值</param>
/// <param name="Qualities">品质</param>
/// <param name="TimeStamps">时间戳</param>
void myGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
for (int i = 1; i <= NumItems; i++)
{
string value = ItemValues.GetValue(i).ToString();
string clienthandle = ClientHandles.GetValue(i).ToString();
string timestamp = TimeStamps.GetValue(i).ToString();
string quality = Qualities.GetValue(i).ToString();
foreach (string key in dictitems.Keys)
{
if (dictitems[key][1] == clienthandle)
{
dictitems[key][2] = value;
break;
}
}
}
//为方便测试,显示到状态栏输出
Console.WriteLine("TransactionID:" + TransactionID.ToString() + "--" + "NumItems:" + NumItems.ToString() + " " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
/// <summary>
/// 写入TAG值时执行的事件
/// </summary>
/// <param name="TransactionID">处理ID</param>
/// <param name="NumItems">项个数</param>
/// <param name="ClientHandles">项客户端句柄</param>
/// <param name="Errors">服务器返回的错误信息</param>
void myGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
//为方便测试,显示到状态栏输出
for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("TransactionID:" + TransactionID.ToString() + "--" + "ClientHandle:" + ClientHandles.GetValue(i).ToString() + "--" + "ErrorValue: " + Errors.GetValue(i).ToString());
}
}
}
}
再附OPC类库的说明:
版权声明
本文为[平山CP3]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_33277597/article/details/104592367
边栏推荐
猜你喜欢

Can fire doors apply for BS 476-21 fire resistance test?

Vs 2022 installing VLD memory leak detection tool

10-Streaming Query

Understanding of string constant pool and intern method

10.4.4 51单片机控制系统8个LED“跑马灯”实验

08-UDFs

07-Complex Types

高德Flutter官方组件amap_flutter_map在地图上画圆

数据库索引

项目实训- 基于unity的2D多人乱斗闯关游戏设计与开发(五、利用AudioMixer控制音量大小)
随机推荐
Introduction to Alibaba micro service component Sentinel
09-Partitioning
mmocr DBLoss
【Appium踩坑】Failed to capture a screenshot. Does the current view have ‘secure‘ flag set?
Youth training camp - swipe questions and punch in - control the number of goroutines executed concurrently
Configure interceptor not to intercept swagger
The 14th issue of HMS core discovery reviews the long article | enjoy the silky clip and release the creativity of the video
Vs 2022 installing VLD memory leak detection tool
Cannot proceed because system tables used by Event Scheduler were found damaged
Project training - Design and development of 2D multiplayer fighting game based on unity (v. use audiomixer to control the volume)
Huawei equipment configuration policy routing to the side hanging firewall
mysql alter 最佳实践总结
Error c4996 'fopen': this function or variable may be unsafe Consider using fopen_ s instead. To disabl
leetcode:642. Design search automatic completion system
团队工作原则
多开关、多业务线设计思考和总结
13-Set Time Zone
System Analyst - paper writing framework construction
The third job analysis
第三次作业解析