C#使用OPC组件方式和AB的PLC通信

devtools/2024/9/30 6:23:37/

目录

PLC%E7%A1%AC%E4%BB%B6%E9%85%8D%E7%BD%AE-toc" style="margin-left:0px;">一、PLC硬件配置

PLC%E7%A8%8B%E5%BA%8F-toc" style="margin-left:40px;">1、创建PLC程序

(1)程序工程选择

(2)变量和程序

2、配置程序在模拟器中运行

(1)打开RSLkin Classic

(2)仿真器配置

PLC%E7%A8%8B%E5%BA%8F%E4%B8%8B%E8%BD%BD-toc" style="margin-left:80px;">(3)PLC程序下载

OPCTools%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7%E6%B5%8B%E8%AF%95-toc" style="margin-left:80px;">(4)使用OPCTools测试工具测试

OPC%E5%B7%A5%E5%85%B7%E6%B5%8B%E8%AF%95OK-toc" style="margin-left:80px;">(5)第三方OPC工具测试OK

二、C#上位机程序实现

1、创建C#工程

(1)界面创建

OPC%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93%E6%96%87%E4%BB%B6-toc" style="margin-left:80px;">(2)添加OPC动态链接库文件

2、关键代码实现

(1)全局变量定义

(2)刷新

(3)连接

(4)批量方式-同步读操作

(5)批量方式-同步写操作

3、软件测试

(1)测试环境设置

OPC%E6%9C%8D%E5%8A%A1%E5%99%A8-toc" style="margin-left:80px;">(2)搜索和连接OPC服务器

(3)读写操作

三、工程下载链接


PLC%E7%A1%AC%E4%BB%B6%E9%85%8D%E7%BD%AE">一、PLC硬件配置

PLC%E7%A8%8B%E5%BA%8F">1、创建PLC程序

(1)程序工程选择

没有PLC硬件,那么就创建模拟器程序

CPU的位置和模拟器要一致

(2)变量和程序

变量创建

PLC程序

2、配置程序在模拟器中运行

(1)打开RSLkin Classic

RSLkin Classic里链接控制器选择模拟器,然后连接

(2)仿真器配置

PLC%E7%A8%8B%E5%BA%8F%E4%B8%8B%E8%BD%BD">(3)PLC程序下载

然后在仿真器模块2上鼠标右击运行

3、应用RSLinx Classic建立OPC通信

(1)在RSLinx Classic中创建组和PLC程序关联

OPCTools%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7%E6%B5%8B%E8%AF%95">(4)使用OPCTools测试工具测试

安装了AB的Studio5000软件即自带OPCTools测试工具

测试工具根目录位置

OPC测试

Step1

Step2

Step3

Step4

OPC%E5%B7%A5%E5%85%B7%E6%B5%8B%E8%AF%95OK">(5)第三方OPC工具测试OK

第三方OPC工具测试OK后,说明硬件方面就没问题了,此时就可以较给C#上位机去操作了。

二、C#上位机程序实现

1、创建C#工程

创建C# Winform工程。

(1)界面创建

OPC%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93%E6%96%87%E4%BB%B6">(2)添加OPC动态链接库文件

2、关键代码实现

(1)全局变量定义

        /// <summary>/// 要操作的PLC变量个数/// </summary>int nVaribaleNum = 5;/// <summary>/// OPC服务器对象/// </summary>OPCServer opcServer;/// <summary>/// OPC组集合对象/// </summary>OPCGroups opcGroups;/// <summary>/// OPC组对象/// </summary>OPCGroup opcGroup;/// <summary>/// OPC多变量添加项目/// </summary>OPCItems opcItems;/// <summary>/// OPC单变量添加项目数组/// </summary>OPCItem[] opcItem;/// <summary>/// 主机名/// </summary>string strHostName = "";/// <summary>/// OPC服务器名/// </summary>string strOPCServerName = "";/// <summary>/// OPC服务器连接状态/// </summary>bool bIsConnect = false;

(2)刷新

该功能实现:搜索OPC服务器、OPC服务器IP地址

        private void btnRefrush_Click(object sender, EventArgs e){//获取客户端名称和IPGetLocaIp();//获取OPC服务器GetLocalOPCServer();//初始化客户端名和OPC服务器名的选择this.cbClientName.SelectedIndex = 0;this.cbOPCServerName.SelectedIndex = 0;}
         /// <summary>/// 获取客户端名称和IP/// </summary>/// <param name="hostName"></param>/// <returns></returns>private void GetLocaIp(){//获取本地计算机名strHostName = Dns.GetHostName();this.cbClientName.Items.Add(strHostName);//获取本机IP地址try{IPHostEntry ipHostEntry = Dns.GetHostEntry(strHostName);for (int i = 0; i < ipHostEntry.AddressList.Length; i++){//从IP地址列表中筛选出IPv4类型的IP地址//AddressFamily.InterNetwork表示此IP为IPv4,//AddressFamily.InterNetworkV6表示此地址为IPv6类型if (ipHostEntry.AddressList[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork){cbClientName.Items.Add(ipHostEntry.AddressList[i].ToString());}}}catch (Exception ex){MessageBox.Show("获取本地IP出错:" + ex.Message);}//添加空字符串作为客户端名实现与OPC服务器的连接if (!this.cbClientName.Items.Contains("")){this.cbClientName.Items.Add("");}}
        /// <summary>/// 获取OPC服务器/// </summary>private void GetLocalOPCServer(){try{opcServer = new OPCServer();object opcServerList = opcServer.GetOPCServers(strHostName);foreach (string server in (Array)opcServerList){cbOPCServerName.Items.Add(server);}}catch (Exception ex){MessageBox.Show("获取OPC服务器出错:" + ex.Message);}}

(3)连接

        private void btnConnect_Click(object sender, EventArgs e){if (bIsConnect == false){try{//连接选择的OPC服务器strOPCServerName = this.cbOPCServerName.Text;opcServer.Connect(strOPCServerName, strHostName);//服务器先行断开opcServer.ServerShutDown += OPCServerShutDown;btnConnect.Text = "断开";btnConnectState.BackColor = Color.Lime;//创建组集合对象CreateGroups();bIsConnect = true;}catch (Exception ex){bIsConnect = false;btnConnectState.BackColor = Color.Red;MessageBox.Show("OPC服务器连接出错:" + ex.Message);}}else{                                opcServer.Disconnect();bIsConnect = false;btnConnect.Text = "连接";btnConnectState.BackColor = Color.Red;}}
         /// <summary>/// 创建组集合/// </summary>/// <returns></returns>private bool CreateGroups(){try{//获取OPC服务器的组集合opcGroups = opcServer.OPCGroups;//获取OPC服务器组集合的组opcGroup = opcGroups.Add("测试1");        //名字可以随便取//设置组集合属性opcGroups.DefaultGroupIsActive = true;  //激活组集合opcGroups.DefaultGroupDeadband = 0;     // 死区值,设为0时,服务器端该组内任何数据变化都通知组。opcGroups.DefaultGroupUpdateRate = 200; // 默认组集合的刷新频率为200ms//设置组属性opcGroup.UpdateRate = 1;                //刷新频率为1秒。opcGroup.IsSubscribed = true;           //使用订阅功能,即可以异步,默认false//设置组的读写事件opcGroup.DataChange += OpcGroup_DataChange;opcGroup.AsyncWriteComplete += OpcGroup_AsyncWriteComplete;opcGroup.AsyncReadComplete += OpcGroup_AsyncReadComplete;//组对象添加项目AddGroupItems();}catch (Exception ex){MessageBox.Show("创建组出错:" + ex.Message);return false;}return true;}
        /// <summary>/// //组对象添加项目/// </summary>private void AddGroupItems(){//组对象的项目集合opcItems = opcGroup.OPCItems;//[aaa]Program:MainProgram.bTest1//opcItems.AddItems()//多个变量一起添加//项目集合中的项目opcItem[0] = opcItems.AddItem("[aaa]Program:MainProgram.bTest1", 0);    //boolopcItem[1] = opcItems.AddItem("[aaa]Program:MainProgram.bTest2", 1);    //boolopcItem[2] = opcItems.AddItem("[aaa]Program:MainProgram.Temp1", 2);     //intopcItem[3] = opcItems.AddItem("[aaa]Program:MainProgram.Temp2", 3);     //intopcItem[4] = opcItems.AddItem("[aaa]Program:MainProgram.Temp3", 4);      //int//组内项目句柄:由于Array和数组的索引值差1,所以数组的第一个元素用0填充占位int[] temp0 = new int[] { 0, opcItem[0].ServerHandle };int[] temp1 = new int[] { 0, opcItem[1].ServerHandle };int[] temp2 = new int[] { 0, opcItem[2].ServerHandle };int[] temp3 = new int[] { 0, opcItem[3].ServerHandle };int[] temp4 = new int[] { 0, opcItem[4].ServerHandle };//移除组内项目Array serverHandle = temp3.ToArray();Array errors;opcItems.Remove(1, ref serverHandle, out errors);//重新添加删除的项目opcItem[3] = opcItems.AddItem("[aaa]Program:MainProgram.Temp2", 3);     //int}

(4)批量方式-同步读操作

        /// <summary>/// 同步-读/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSynRead_Click(object sender, EventArgs e){if (this.opcServer == null || bIsConnect == false){MessageBox.Show("请先连接服务器!");return;}//组的同步读取string[] itemId = { "","[aaa]Program:MainProgram.bTest1","[aaa]Program:MainProgram.bTest2", "[aaa]Program:MainProgram.Temp1","[aaa]Program:MainProgram.Temp2" ,"[aaa]Program:MainProgram.Temp3" };                                //""用于占位int[] clientHandle = { 0, 1, 2, 3, 4, 5 };  Array itemIds = itemId.ToArray();Array clientHandles = clientHandle.ToArray();Array serverHandles;Array errors;Array values;object qualities;object timeStamps;opcGroup.OPCItems.AddItems(nVaribaleNum, ref itemIds, ref clientHandles, out serverHandles, out errors);opcGroup.SyncRead(2, nVaribaleNum, ref serverHandles, out values, out errors, out qualities, out timeStamps);//第一个参数为2才可以object[] valueList = new object[nVaribaleNum];for (int i = 1; i <= nVaribaleNum; i++){valueList[i - 1] = values.GetValue(i);}txt_bTest1.Text = valueList[0].ToString();txt_bTest2.Text = valueList[1].ToString();txt_Temp1.Text = valueList[2].ToString();txt_Temp2.Text = valueList[3].ToString();txt_Temp3.Text = valueList[4].ToString();}

(5)批量方式-同步写操作

        /// <summary>/// 同步-写/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSyncWrite_Click(object sender, EventArgs e){if (this.opcServer == null || bIsConnect == false){MessageBox.Show("请先连接服务器!");return;}//组的同步写入int[] temp = new int[] { 0,opcItem[0].ServerHandle, opcItem[1].ServerHandle,opcItem[2].ServerHandle,opcItem[3].ServerHandle,opcItem[4].ServerHandle };                          //0用于占位Array serverHandles = temp.ToArray();object[] tempValue = new object[]{ "",txt_bTest1.Text == "1" ? true : false,txt_bTest2.Text == "1" ? true : false,Convert.ToInt16(this.txt_Temp1.Text),Convert.ToInt16(this.txt_Temp2.Text),Convert.ToInt16(this.txt_Temp3.Text),};                                     //""用于占位Array values = tempValue.ToArray();Array errors;opcGroup.SyncWrite(nVaribaleNum, serverHandles, values, out errors);}

3、软件测试

(1)测试环境设置

Step1:设置本地Ip固定地址192.168.1.33

Step2:PLC程序在本地模拟器上处于运行模式。

Step3:PLC程序中给OPC客户端访问的量在RSLinkClassic中已成功配置,并且RSLink Classic软件打开处于运行中

OPC%E6%9C%8D%E5%8A%A1%E5%99%A8">(2)搜索和连接OPC服务器

点刷新,然后如图所示依次选择,成功连接服务器

(3)读写操作

读操作

写操作

三、工程下载链接

包括PLC程序、C#程序、OPC动态链接库文件

https://download.csdn.net/download/panjinliang066333/89598823

参考:

https://blog.csdn.net/zlbdmm/article/details/108574133

C#之OPC通信_c# opc-CSDN博客


http://www.ppmy.cn/devtools/88909.html

相关文章

【网络安全】大小写绕过速率限制

未经许可,不得转载。 文章目录 正文正文 某目标存在登录页面,对登录处进行爆破,但在我发出 17 次请求后就屏蔽了我。 我尝试了多种方法绕过速率限制,例如: X-Originating-IP:127.0.0.1 X-Forwarded-For:127.0.0.1 X-Remote-IP:127.0.0.1 X-Remote-Addr:127.0.0.…

【C语言】《C语言基础指南!》- 史上最全!

目录 C语言基础精讲1. C语言简介1.1. C语言的历史1.2. C语言概述1.3. C语言的特点 2. 基本语法2.1. 程序结构2.2. 数据类型 3. 变量和常量3.1. 变量声明与初始化3.2. 常量定义 4. 控制结构4.1. 条件语句4.2. 循环语句 5. 函数5.1. 函数定义5.2. 函数调用 6. 数组和字符串6.1. 数…

从根儿上学习spring 十一 之run方法启动第四段(5)

图15-AbstractAutowireCapableBeanFactory#doCreateBean方法 我们接着讲doCreateBean方法&#xff0c;之前对循环依赖做了些解释&#xff0c;我们接着往下看populateBean(beanName, mbd, instanceWrapper)方法 图15-572行 这行就是调用populateBean(beanName, mbd, instanceW…

Conditional Detr

encoder和detr相同&#xff0c;只修改了decoder部分。

总线学习3--UART(TODO)

&#xff08;TODO&#xff09; import machine import utime# 定义 UART 参数 baudrate 9600 bit_time 1 / baudrate# 定义 GPIO 引脚 tx_pin machine.Pin(0, machine.Pin.OUT) rx_pin machine.Pin(1, machine.Pin.IN)# 初始化 TX 引脚为高电平&#xff08;空闲状态&#x…

评估生成分子/对接分子的物理合理性工具 PoseBusters 评测

最近在一些分子生成或者对接模型中&#xff0c;出现了新的评估方法 PoseBusters&#xff0c;用于评估生成的分子或者对接的分子是否符合化学有效性和物理合理性。以往的分子生成&#xff0c;经常以生成分子的有效性、新颖性、化学空间分布&#xff0c;与口袋的结合力等方面进行…

Python面试题汇总

Python面试题汇总 说明&#xff1a;下面的内容源于GitHub上名为interview_python的项目&#xff0c;对其内容进行了修订和补充。 [TOC] Python语言特性 1 Python的函数参数传递 看两个例子: a 1 def fun(a):a 2 fun(a) print a # 1 a [] def fun(a):a.append(1) fun(a…

60_2JSP核心技术、EL、JSTL

JSP核心技术 什么是JSP JSP全称是Java Server Pages&#xff0c;它和servle技术一样&#xff0c;都是SUN公司定义的一种用于开发动态web资源的技术。JSP/Servlet规范。JSP实际上就是Servlet JSP这门技术的最大的特点在于&#xff0c;写jsp就像在写html&#xff0c;但它相比htm…