【基础】OPC 通讯协议

这篇具有很好参考价值的文章主要介绍了【基础】OPC 通讯协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

OPC 通讯协议基础

OPC 简介

OPC 全称 OLE For Process Control,即用于控制过程的 OLE,是一个工业标准,管理该标准的国际组织是 OPC 基金会。

OPC 出现的目的是为不同的供应商设备与应用程序之间的接口标准化从而使其间的数据交换更加简单,因此,使我们可以开发不依靠于特定开发语言和开发环境的、可以自由组合的过程控制软件。

利用驱动器的系统连接
opc通讯协议,物联网,网络,java,网络协议
利用 OPC 控制的系统组成
opc通讯协议,物联网,网络,java,网络协议

OPC 的分层结构

OPC 对象中最上层的对象是 OPC 服务器,一个 OPC 服务器中可以设置一个以上的 OPC 组。OPC 服务器常对应于某种特定的控制设备,如 DCS 以及 PLC 等。

OPC 组是可以进行数据访问的多个 OPC 标签的集合,OPC 应用程序可以将需要的数据分组进行批量读取,也可以以组为单位启动或者停止数据访问。此外,OPC 组还提供组内 OPC 标签数据变化时向 OPC 应用程序通知的事件。

opc通讯协议,物联网,网络,java,网络协议

OPC 与 OPC UA

OPC DA 与 OPC UA 都是 OPC 协议的标准:

  • OPC 是一种通过微软 COM/DCOM 技术来实现自动化控制的协定,采用 C/S 架构。开发人员只需要按照 OPC 的标准编写 OPC-Client 访问 OPC-Server 进行读写操作即可实现与硬件设备的通信。OPC 的协定中包括:

    • DA (Data Access):访问数据的主要规范;

    • A&E (Alarm and Event):基于事件提供 Client 端订阅,事件触发后 Server 主动提交数据;

    • HDA (History Data Access):历史数据访问;

  • OPC UA 是 OPC 协议的新版,其不再依赖于 COM/DCOM 技术,这意味着其具有跨平台性,不再局限于 Windows 系统。OPC UA 提供了可靠的通信机制,接口简单一致。

举例说明两者之间的区别:

对传统的三种不同类型OPC服务器的访问:数据访问 DA、报警和事件 AE、历史数据访问 HDA,要获得一个温度传感器的当前值、一个高温度事件和温度的历史平均值,要依次使用不同的命令执行;

而使用 OPC UA,仅用一个组件就非常容易地完成了。配置和工程的时间也因此可以大大缩短。

OPC 逻辑对象模型

包括3类对象:OPC Server 对象、OPC Group 对象、OPC Item 对象,每类对象都包括一系列接口。

OPC Server 对象

主要功能:

  • 创建和管理 OPC Group 对象;

  • 管理服务器内部的状态信息;

OPC Group 对象

主要功能:

  • 创建和管理 OPC Item 对象;

  • 管理 OPC Group 对象的内部状态信息;

  • OPC Server 内部实时数据的读写服务;

属性:

  • name:组名,由客户端自定义;

  • active:组的激活状态,若为 false 则组失效,无法对服务器进行读写;

  • update rate:更新速率(该值应大于服务器设定的最小值);

  • percent data band:数据死区;

注意:

  • Group 分为公共组和私有组:公共组对所有连接到服务器的客户端都有效;而私有组仅对建立该组的客户端有效;

OPC Item 对象

主要功能:

  • 用以描述实时数据,代表了与服务器数据源的连接;

属性:

  • name:项名,在服务器中对应 Item ID;

  • active:项的激活状态;

  • value:项的数据值;

  • quality:项的品质,代表数值的可信度;

  • timestamp:时间戳,代表数据的存取事件;

注意:

  • Item 的存储类型为 VARIANT;Item 的数据类型为 VARTYPE;

  • 一个项不能被 OPC 客户端直接访问,因为 OPC 协议中没有对应于项的 COM 接口,对项的访问必须通过 OPC Group 实现;

  • Item 在服务端的定义对应于硬件的实际地址。客户端连接到服务器后创建并添加 OPC Group,并创建一系列的 OPC Item,将逻辑上等价的一组 OPC Item 添加到 OPC Group 中即可通过组对象对数据进行读写操作;

OPC 通信方式

  • 同步通信:OPC Client 对 OPC Server 进行读取操作时,OPC Client 必须等到 OPC Server 完成对应操作后才能返回,在此期间 OPC Client 处于一直等待的状态。

  • 异步通信:OPC Client 对 OPC Server 进行读取操作时,OPC Client 发送请求后立即返回,不用等待 OPC Server,当 OPC Server 完成操作后再通知 OPC Client 程序。

  • 订阅:需要 OPC Server 支持OPC A&E规范,由 OPC Client 设定数据的变化限度,如果数据源的实时数据变化超过了该限度,OPC Server 通过回调返回数据给OPC Client。

Java 实现 OPC 的方式

OPC Client 开发大致流程

  1. COM 组件初始化;
  2. 创建服务器 Server 对象;
  3. 创建组 Group 对象;
  4. 创建项 Item 对象;
  5. 添加 Item 到 Group 中;
  6. 添加 Group 到 Server 对象中;
  7. 连接服务器,完成相应操作;
  8. COM 组件关闭

OPC DA

Java 关于 OPC DA 的开源库只有 Utgard 和 Jeasyopc,两者区别如下:

Utgard Jeasyopc
Linux 支持 不支持
Windows 支持 不支持
用户名和密码 需要 不需要
组查询 支持 不支持
压力测试(单线程同步) 略快 7W 点约 4224ms 略慢 7W 点约 22540ms
DCOM 通过 DCOM 实现,需进行配置 不需要配置
开源库现状 作者删库跑路 只支持 32 位系统

OPC UA

推荐使用 Eclipse 的 milo 开源库

Java 实现 OPC-client

本测试使用的 OPC-Server 软件为 KEPServerEX6,具体下载与使用参考博客OPCServer:使用KEPServer

OPC-DA

因为开源库 Jeasyopc 不支持 windows 和 linux 系统,且只支持 32 位系统,因此此处使用 Utgard 库实现。本测试采用虚拟机实现,使用的系统为 Windows 10 专业版,版本号 1903。

Utgard 开源库通过 DCOM 技术实现,因此首先需要配置 DCOM,参考博客OPC和DCOM配置。

引入相应的依赖

        <dependency>
            <groupId>org.kohsuke.jinterop</groupId>
            <artifactId>j-interop</artifactId>
            <version>2.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.utgard</groupId>
            <artifactId>org.openscada.opc.lib</artifactId>
            <version>1.5.0</version>
        </dependency>

从 OPC-Server 读取数据

public class OPCRead {

    public static void main(String[] args) {
        // 配置连接信息
        final ConnectionInformation ci = new ConnectionInformation();
        ci.setHost("localhost");         // 本机IP
        ci.setDomain("");                // 域,为空就行
        ci.setUser("OPCServer");         // 用户名
        ci.setPassword("OPCServer");     // 密码

        // 配置 KEPServer
        ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729"); // KEPServer 的注册表ID,可以在“组件服务”里看到
        final String itemId = "通道 1.设备 1.标记 2";    // KEPServer 上配置的项的名字

        // 启动服务
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());

        try {
            // 连接服务器
            server.connect();
            // 创建 Group,用于对 Item 的访问
            final Group group = server.addGroup("test");
            // 将要访问的 Item 加入创建的 Group
            final Item item = group.addItem(itemId);
            // 读取 Item 状态
            ItemState itemState = item.read(true);
            // 获取 Item 的数据类型,该类型使用常量定义,见 JIVariant 类
            int type = 0;
            try {
                type = itemState.getValue().getType(); // 类型实际是数字,用常量定义的
            } catch (JIException e) {
                e.printStackTrace();
            }
            // 打印 Item 相应状态
            System.out.println(">>>监控项的数据类型是:" + type);
            System.out.println(">>>监控项的时间戳是:" + itemState.getTimestamp().getTime());
            System.out.println(">>>监控项的详细信息是:" + itemState);
            // 若读到是 short 类型(对应数字 2)
            if (type == JIVariant.VT_I2) {
                short value = 0;
                try {
                    value = itemState.getValue().getObjectAsShort();
                } catch (JIException e) {
                    e.printStackTrace();
                }
                System.out.println(">>>short类型值: " + value);
            }
            // 删除 Group
            server.removeGroup(group, true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

从 OPC-Server 写入数据

public class OPCWrite {

    public static void main(String[] args) {
        // 配置连接信息
        final ConnectionInformation ci = new ConnectionInformation();
        ci.setHost("localhost");         // 本机IP
        ci.setDomain("");                // 域,为空就行
        ci.setUser("OPCServer");         // 用户名
        ci.setPassword("OPCServer");     // 密码

        // 配置 KEPServer
        ci.setClsid("7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729"); // KEPServer 的注册表ID,可以在“组件服务”里看到
        final String itemId = "通道 1.设备 1.标记 2";    // KEPServer 上配置的项的名字

        // 启动服务
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());

        try {
            // 连接服务器
            server.connect();
            // 创建 Group,用于对 Item 的访问
            final Group group = server.addGroup("test");
            // 将要访问的 Item 加入创建的 Group
            final Item item = group.addItem(itemId);
            // 写入前:打印 Item 状态及对应数据
            printRead(item);
            // 写入数据
            item.write(new JIVariant("100"));
            // 写入后:打印 Item 状态及对应数据
            printRead(item);
            // 删除 Group
            server.removeGroup(group, true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取 Item 状态、数据
     * @param item item
     * @throws JIException
     */
    public static void printRead(Item item) throws JIException {
        // 读取 Item 状态
        ItemState itemState = item.read(true);
        int type = 0;
        try {
            type = itemState.getValue().getType(); // 类型实际是数字,用常量定义的
        } catch (JIException e) {
            e.printStackTrace();
        }
        // 打印 Item 相应状态
        System.out.println(">>>监控项的数据类型是:" + type);
        System.out.println(">>>监控项的时间戳是:" + itemState.getTimestamp().getTime());
        System.out.println(">>>监控项的详细信息是:" + itemState);
        // 若读到是 short 类型(对应数字 2)
        if (type == JIVariant.VT_I2) {
            short value = 0;
            try {
                value = itemState.getValue().getObjectAsShort();
            } catch (JIException e) {
                e.printStackTrace();
            }
            System.out.println(">>>short类型值: " + value);
        }
    }

}

OPC-UA

OPC-UA 是目前比较流行的协议,采用开源库 milo 实现,引入相应依赖:

        <dependency>
            <groupId>org.eclipse.milo</groupId>
            <artifactId>sdk-client</artifactId>
            <version>0.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.milo</groupId>
            <artifactId>sdk-server</artifactId>
            <version>0.6.3</version>
        </dependency>

使用 opc-ua 实现数据读写:

public class OpcUaDemo {

    public static void main(String[] args) throws Exception {
        // 创建OPC UA客户端
        OpcUaClient opcUaClient = createClient();

        // 开启连接
        opcUaClient.connect().get();

        // 遍历节点
        browseNode(opcUaClient, null);

        // 读
        readNode(opcUaClient);

        // 写
        writeNodeValue(opcUaClient);
        readNode(opcUaClient);

        // 关闭连接
        opcUaClient.disconnect().get();
    }

    /**
     * 创建 opc-ua 客户端
     * @return OpcUaClient
     * @throws Exception
     */
    private static OpcUaClient createClient() throws Exception {
        String endPointUrl = "opc.tcp://127.0.0.1:49320";
        Path securityTmpdir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
        Files.createDirectories(securityTmpdir);
        if (!Files.exists(securityTmpdir)) {
            throw new Exception("unable to create security dir: " + securityTmpdir);
        }
        return OpcUaClient.create(endPointUrl,
                endpoints ->
                        endpoints.stream()
                                .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
                                .findFirst(),
                configBuilder ->
                        configBuilder
                                .setApplicationName(LocalizedText.english("KEPServerEX/UA Client Driver"))
                                .setApplicationUri("urn:Thinkbook-ZQF:Kepware.KEPServerEX.V6:UA%20Client%20Driver")
                                //访问方式
                                .setIdentityProvider(new AnonymousProvider())
                                .setRequestTimeout(UInteger.valueOf(5000))
                                .build()
        );
    }

    /**
     * 遍历树形节点
     * @param client 客户端
     * @param uaNode 节点
     * @throws Exception
     */
    private static void browseNode(OpcUaClient client, UaNode uaNode) throws Exception {
        List<? extends UaNode> nodes;
        if (uaNode == null) {
            nodes = client.getAddressSpace().browseNodes(Identifiers.ObjectsFolder);
        } else {
            nodes = client.getAddressSpace().browseNodes(uaNode);
        }
        for (UaNode nd : nodes) {
            //排除系统行性节点,这些系统性节点名称一般都是以"_"开头
            if (Objects.requireNonNull(nd.getBrowseName().getName()).contains("_")) {
                continue;
            }
            System.out.println("Node= " + nd.getBrowseName().getName());
            browseNode(client, nd);
        }
    }

    /**
     * 读取节点数据
     *
     * @param client OPC UA客户端
     * @throws Exception
     */
    private static void readNode(OpcUaClient client) throws Exception {
        int namespaceIndex = 2;
        String identifier = "通道 1.设备 1.标记 1";
        //节点
        NodeId nodeId = new NodeId(namespaceIndex, identifier);
        //读取节点数据
        DataValue value = client.readValue(0.0, TimestampsToReturn.Neither, nodeId).get();
        //标识符
        System.out.println(identifier + ": " + String.valueOf(value.getValue().getValue()));
    }

    /**
     * 写入节点数据
     *
     * @param client
     * @throws Exception
     */
    private static void writeNodeValue(OpcUaClient client) throws Exception {
        //节点
        NodeId nodeId = new NodeId(2, "通道 1.设备 1.标记 1");
        short i = 3;
        //创建数据对象,此处的数据对象一定要定义类型,不然会出现类型错误,导致无法写入
        DataValue nowValue = new DataValue(new Variant(i), null, null);
        //写入节点数据
        StatusCode statusCode = client.writeValue(nodeId, nowValue).join();
        System.out.println("结果:" + statusCode.isGood());
    }

}

模拟数据进行代码测试

OPC-DA 代码验证

使用 KEPServerEX 6 作为 OPC-Server 进行测试,百度网盘下载链接如下:

链接:https://pan.baidu.com/s/1pigppR62xTsE_4ecXx9m8Q?pwd=3aig 
提取码:3aig

在界面上可以右键单击标记名称进行数据格式的设置

opc通讯协议,物联网,网络,java,网络协议
单击工具栏最后一个,创建一个 OPC Quick client,可以观察到,此时通道 1.设备 1.标记 2的值为 0

opc通讯协议,物联网,网络,java,网络协议
修改 opc-da 写入程序,写入数值为 300

opc通讯协议,物联网,网络,java,网络协议
执行写入程序,查看 client 中的对应值,写入成功

opc通讯协议,物联网,网络,java,网络协议
使用读取程序对数据进行读取,同样可以读取到对应的数值

opc通讯协议,物联网,网络,java,网络协议

OPC-UA 代码验证

在验证之前首先右键项目,选择属性,修改 OPC-UA 属性中的”允许匿名登录“为是

opc通讯协议,物联网,网络,java,网络协议

配置写入数据的方法,将对应的数值从 300 修改为 3

opc通讯协议,物联网,网络,java,网络协议

执行代码,查看输出结果

opc通讯协议,物联网,网络,java,网络协议文章来源地址https://www.toymoban.com/news/detail-766606.html

到了这里,关于【基础】OPC 通讯协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 通讯协议054——全网独有的OPC HDA知识一之接口(九)IOPCHDA_AsyncUpdate

    本文简单介绍OPC HDA规范的IOPCHDA_AsyncUpdate(可选)接口方法,更多通信资源请登录网信智汇(wangxinzhihui.com)。 此调用使用ENUM作为返回参数;这对于位掩码值是不正确的,并且排除了服务器指定多个支持的方法。为了避免对此次维护更新的IDL进行更改,对此的更正将推迟到2.0版

    2024年02月10日
    浏览(39)
  • 通讯协议048——全网独有的OPC HDA知识一之接口(三)IOPCHDA_Server

    本文简单介绍OPC HDA规范的IOPCHDA_Server接口方法,更多通信资源请登录网信智汇(wangxinzhihui.com)。 1)HRESULT   GetItemAttributes (pdwCount , ppdwAttrID, ppszAttrName, ppszAttrDesc, ppvtAttrDataType) 此函数返回服务器支持的项属性。也支持供应商特定的属性。供应商提供的属性可用于允许客户端访问

    2024年02月11日
    浏览(38)
  • PLC物联网网关BL104实现PLC协议转MQTT、OPC UA、Modbus TCP

    随着物联网技术的迅猛发展,人们深刻认识到在智能化生产和生活中,实时、可靠、安全的数据传输至关重要。在此背景下,高性能的物联网数据传输解决方案——协议转换网关应运而生,广泛应用于工业自动化和数字化工厂应用环境中。 无缝衔接工业4.0时代 尽享数字工厂

    2024年01月21日
    浏览(68)
  • Java 001:通过OPC UA协议连接KepServerEx进行读、写、订阅操作

    参考前辈的踩坑记录https://blog.csdn.net/weixin_45411740/article/details/124275985?spm=1001.2014.3001.5502,我Hyb在2023-3-15调通了自己的JavaOpcUaDemo。具体Java代码和KepServerEX延时补丁都在资源中。 第1步:安装激活KepServer,补丁在资源中,不详述。 第2步:在KepServer中做OpcUa配置。 2.1 先看桌面右下

    2024年02月08日
    浏览(48)
  • 通讯编程006——NodeJS OPC UA Client开发简单教程

    本文介绍如何在NodeJS环境下开发OPC UA Client,通过本文可以对OPC UA的基本概念有所了解,掌握OPC UA的本质。相关软件请登录网信智汇(wangxinzhihui.com)。 开发步骤如下: 1)首先需要安装nodejs,要求版本至少是12。 2)创建项目目录,在cmd下进入项目目录下,执行如下指令: 1)n

    2024年02月09日
    浏览(40)
  • Node-Red如何与OPC UA服务器通讯

    本篇内容主要介绍Node-Red如何通过插件node-red-contrib-opcua来从OPC UA服务器读写数据,仍然用KEPServer来模拟OPC UA服务器,UaExpert用来测试连接和获取变量NodeId。 KEPServer的安装参考文章Node-Red如何与OPC DA服务器通讯。 安装UaExpert没有太多要注意的地方,依次下一步就行了 接下来安装

    2024年03月17日
    浏览(59)
  • 在 .NET 中使用 OPC UA 协议

    目录 什么是 OPC UA UaExpert 的使用 下载 UaExpert 首次启动 添加 OPC UA 服务器 连接 OPC UA 服务器 查看 PLC 数据 使用 C# 读写 OPC UA 数据 连接到 OPC UA 服务器 获取节点的值 写入节点的值 OPC UA (OPC Unified Architecture,开放平台通信统一架构)是 OPC 基金会应用在自动化技术的机器对机器

    2024年03月25日
    浏览(40)
  • 通讯网关软件014——利用CommGate X2HTTP实现HTTP访问OPC Server

    本文介绍利用CommGate X2HTTP实现HTTP访问OPC Server。CommGate X2HTTP是宁波科安网信开发的网关软件,软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示,SCADA系统配置OPC Server,现在上位机需要通过Http Client软件来获SCADA的数据。 【解决方案】设置网关机,与OP

    2024年02月07日
    浏览(53)
  • 通讯网关软件003——利用CommGate X2Mbt实现Modbus TCP访问OPC Server

    本文介绍利用CommGate X2Mbt实现Modbus访问OPC Server。CommGate X2MBT是宁波科安网信开发的网关软件,软件可以登录到网信智汇(wangxinzhihui.com)下载。 【案例】如下图所示,SCADA系统配置OPC Server,现在上位机需要通过Modbus主站软件来获SCADA的数据。 【解决方案】设置网关机,与OP CServ

    2024年02月07日
    浏览(51)
  • OPC通信从入门到精通_2_OPC通信详解和C#客户端编程(OPC基础概念;OPC通信仿真(KepServer作为OPC服务器;使用Modbus Slave和另外软件仿真2个PLC设备);C#程序)

    OPC诞生缘由:OPC诞生之前,软件工程师是不了解硬件和协议的 OPC解决的是软件和硬件之间的问题,让软件工程师无需了解协议及底层硬件,例如串口协议等 OPC起到了桥梁的作用:软件工程师对接OPC,OPC对接硬件 OPC是一种通讯方式,落到实处就是一个软件,就需要开发相应的

    2024年02月05日
    浏览(75)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包