进阶05:Labview与汇川PLC通过OPC UA通信(AM500系列)

本节目标:

1)编写汇川PLC程序,用于和Labview进行通信;

2)使用UaExpert,读取汇川PLC中的变量与OPCUA节点名称;

3)使用C#编写用于OpcUa通信的dll;

4)使用Labview对dll库进行打包使用;

5)编写Labview程序,读写服务器中变量值,创建订阅触发事件;

本节内容执行结果如下,连接后点击写入按钮可以将设定的值写入PLC中,点击读取可以读取写入的值,点击PLCStart,PLC中的程序运行,Y1-Y4依次点亮;

完整源码&答疑&系列文章,见个人简介链接

1.1 编写汇川PLC程序

1) 下载安装软件

下载链接:InoProShop中型PLC后台编程软件完整包

下载完成后,点击安装。本人使用的是V1.8.1.3版本。

2)创建程序

本次使用的时汇川的AM521,语言选择结构化文本,点击确定。

3)设置OpcUa

双击Device,鼠标左击OPC UA,选择模式1。

4)新建变量

保持默认名称,点击确定;

在GVL文件中添加变量;

复制代码
VAR_GLOBAL
	i_steps	:INT;
	start	:INT;
  value1:REAL;
	OutVal	:UINT;
	Y0		:BOOL;
	Y1		:BOOL;
	Y2		:BOOL;
	Y3		:BOOL;	
  Ton1	:TON;
END_VAR

5)添加程序

双击PLC_PRG,打开编辑框;

添加程序;

复制代码
Ton1(PT := T#1000MS);
CASE i_steps OF
10:
    if start=1 THEN
        start:=0;
        Y3:=FALSE;
        Y0:=TRUE;
        i_steps:=20;
    END_IF
20:
    Ton1.IN:=TRUE;
    IF Ton1.Q THEN
        Ton1.IN:=FALSE;
        Y0:=FALSE;
        Y1:=TRUE;
        i_steps:=30;
    END_IF
30:
    Ton1.IN:=TRUE;
    IF Ton1.Q THEN
        Ton1.IN:=FALSE;
        Y1:=FALSE;
        Y2:=TRUE;
        i_steps:=40;
    END_IF
40:
    Ton1.IN:=TRUE;
    IF Ton1.Q THEN
        Ton1.IN:=FALSE;
        Y2:=FALSE;
        Y3:=TRUE;
        i_steps:=0;
    END_IF
END_CASE

//赋值
OutVal:=0;
IF Y0 THEN
    OutVal := OutVal OR SHL(UINT#1, 0);
END_IF;
IF Y1 THEN
    OutVal := OutVal OR SHL(UINT#1, 1);
END_IF;
IF Y2 THEN
    OutVal := OutVal OR SHL(UINT#1, 2);
END_IF;
IF Y3 THEN
    OutVal := OutVal OR SHL(UINT#1, 3);
END_IF;

6)符号配置

添加这一步,OPC才可以读到标签;

添加符号配置;

默认名称,点击打开;

点击编译,等待编译完成;

编译完成后,选择需要向公网公开的变量,这里勾选整个GVL,点击导出;

7)编译完成后,下载运行

下面是运行状态下的变量状态;

1.2 UaExpert读取节点名称

打开UaExpert,此为OPC客户端,用于测试服务器

点击加号

输入URL

选择匿名登录

连接

将变量拉入到显示界面处。

可以看到变量的值,同时也可以修改值。

其中四个变量的节点名称如下:

ns=4;s=|var|Inovace-ARM-Linux.Application.GVL.i_steps

ns=4;s=|var|Inovace-ARM-Linux.Application.GVL.start

ns=4;s=|var|Inovace-ARM-Linux.Application.GVL.value1

ns=4;s=|var|Inovace-ARM-Linux.Application.GVL.OutVal

节点名称在后续的上位机编写时使用。

1.3 创建OPC UA通信dll

1)新建项目

2)现在依赖包

下载OpcUaHelper,用于OpcUa通信。

下载Costura.Fody包,可以将多个dll合并到一个dll中,让文件变得更加简洁。

3)添加程序

OpcUaConnector.cs中如下;

具体讲解可以参考博文:进阶01:Labview与OPC UA设备通信_labview opc ua-CSDN博客

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpcUaHelper;
using Opc.Ua;
using Opc.Ua.Client;

namespace OpcUaDll
{
    public class OpcUaConnector
    {
        private string ServerUrl;
        private OpcUaClient m_OpcUaClient;
        public event EventHandler<TEventArgs> OnSubscription;
        public struct TEventArgs
        {
            public string key;
            public object value;
        }
        public OpcUaConnector(string url)
        {
            ServerUrl = url;
            m_OpcUaClient = new OpcUaClient();
        }

        public bool Connect()
        {
            m_OpcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());//匿名链接
            try
            {
                m_OpcUaClient.ConnectServer(ServerUrl);//链接服务器               
            }
            catch (Exception ex)
            {
                Console.WriteLine("Connect failed!!");
                return false;
            }
            return true;
        }
        public object ReadTag(string tag)
        {
            object val;
            try
            {
                val = m_OpcUaClient.ReadNode<object>(tag);
            }
            catch
            {
                return false;
            }            
            return val;
        }
        public object[] ReadTags(string[] tags)
        {
            List<object> val1 = m_OpcUaClient.ReadNodes<object>(tags);
            object[] result = new object[val1.Count];
            int i = 0;
            foreach(object obj in val1)
            {
                result[i] = obj;
                i++;
            }
            return result;
        }
        public bool WriteTag(string tag, object val)
        {
            try
            {
                var var1 = m_OpcUaClient.WriteNode<object>(tag, val);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Write failed!!");
                return false;
            }
            return true;
        }
        public bool WriteTags(string[] tags, object[] vals)
        {
            try
            {
                var var1 = m_OpcUaClient.WriteNodes(tags, vals);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Write failed!!");
                return false;
            }
            return true;
        }
        public bool AddSubscription(string key,string tag)
        {
            if (m_OpcUaClient.Connected)
            {
                m_OpcUaClient.AddSubscription(key, tag, SubCallback);
                return true;
            }
            else
                return false;
        }
        public bool AddSubscriptions(string[] keys, string[] tags)
        {
            if (m_OpcUaClient.Connected)
            {
                for (int i = 0; i < tags.Length;i++ )
                    m_OpcUaClient.AddSubscription(keys[i], tags[i], SubCallback);
                return true;
            }
            else
                return false;
        }
        private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
        {
            MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
            //notification.Value.WrappedValue.Value;
            TEventArgs ww = new TEventArgs();
            ww.key = key;
            ww.value = notification.Value.WrappedValue.Value;
            OnSubscription.Invoke(this, ww);
        }
        public bool RemoveSubscription(string key)
        {
            if (m_OpcUaClient.Connected)
            {
                m_OpcUaClient.RemoveSubscription(key);
                return true;
            }
            else
                return false;
        }
        public bool RemoveAllSubscription()
        {
            if (m_OpcUaClient.Connected)
            {
                try
                {
                    m_OpcUaClient.RemoveAllSubscription();
                }
                catch
                {
                    return false;
                }
                return true;
            }
            else
                return false;
        }
        public bool Disconnect()
        {
            if (m_OpcUaClient.Connected)
            {
                m_OpcUaClient.RemoveAllSubscription();
                m_OpcUaClient.Disconnect();
            }
            return true;
        }

    }
}

程序编辑完成后,编译,可在debug文件夹中生成dll文件。

1.4 Labview创建OpcUaHelper类

新建OpcUaHelper类如下,在类中新建多个子vi,该类用于集成OpcUa的通信。

将OpcUaDll.dll拷贝到类的文件夹OpcUaDll下。

1)新建OpcUaConnect.vi

用于连接OpcUa服务器;

其中,构造器中内容如下;

2)新建OpcUaDisconnect.vi

用于断开OpcUa通信,同时可以将订阅等关掉;

3)新建OpcUaReadNode.vi

读取一个节点的变量值;

4)新建OpcUaReadNodes.vi

用于读取多个节点的值;

5)新建OpcUaWriteNode.vi

用于写入单个节点的值;

6)新建OpcUaWriteNodes.vi

用于写入多个节点的值;

7)新建OpcUaAddSubscription.vi

用于添加多个订阅;

回调SubCallback.vi

8)新建OpcUaRemoveSubscription.vi

去除单个节点订阅;

1.5 Labview调用OpcUa通讯类

1)新建main.vi,前面板如下

2)程序框图

主界面的程序流程图如下所示:

3)连接事件

点击连接按钮触发该事件,如果是true,先连接OPC服务器,在注册OutVal订阅事件,如果OutVal值变化会触发注册的用户事件,将变量值传递过来;

如果是假,关闭OPC连接;

4)读取事件

使用读取vi读取节点中的值,并显示在界面上;

5)写入事件

将界面上输入的值写入到节点中;

6)停止按钮

断开OPC连接,程序停止运行;

7)用户事件

将读取到的OutVal值分解成四个bool量,显示在界面上;

8)PLC Start事件

向i_steps变量写10,向start变量写1,触发PLC开始运行程序,请结合上面的PLC程序进行学习;

1.6 运行

PLC程序下载成功后,运行Labview程序;

点击连接按钮,没有报错即连接成功;

连接后点击写入按钮可以将设定的值写入PLC中;

点击读取可以读取写入的值;

点击PLCStart,PLC中的程序运行,Y1-Y4依次点亮;

上面的内容是Labview与汇川PLC通讯的简单示例,基于该简单示例可以开发更为复杂的程序,用于自动化开发。

相关推荐
Kay.Wen5 天前
LabVIEW 转换 XML文本
xml·labview
星野云联AIoT技术洞察6 天前
OPC UA、MQTT、Modbus 应该如何分层:工业 IoT 接入架构新思路
mqtt·modbus·opc ua·边缘网关·设备接入·协议分层·工业iot
LabVIEW开发10 天前
LabVIEW插值应用
算法·labview·labview知识·labview功能·labview程序
LabVIEW开发11 天前
LabVIEW控制阀性能测试评估系统
人工智能·labview·labview知识·labview功能·labview程序
尊治12 天前
再谈工控知识的学习方法
学习方法·汇川plc·esim电工仿真·电工仿真软件·电工仿真·电气原理图模拟仿真
LabVIEW开发12 天前
LabVIEW振动信号采集分析
fpga开发·labview·labview知识·labview功能·labview程序
LabVIEW开发14 天前
LabVIEW PID VI 温控参数全解与应用
labview·labview知识·labview功能·labview程序
俊俊谢17 天前
LabVIEW如何排查和修复dll缺失问题
驱动开发·.net·labview·dll
慧都小妮子17 天前
PLC数据采集怎么做?三种主流采集方案对比:OPC Server / 网关 / SDK
opc ua·kepware·kepserver·opc da·takebishi·dxpserver·opc server
unicrom_深圳市由你创科技17 天前
LabVIEW和C#在工业控制中的应用差异是什么?
fpga开发·c#·labview