大数跨境
0
0

C# 轻量级工业通信:基于 HslCommunication 实现配置驱动的 PLC 数据采集

C# 轻量级工业通信:基于 HslCommunication 实现配置驱动的 PLC 数据采集 dotNET跨平台
2025-12-05
15
导读:前言工业自动化领域,上位机软件常常需要对接多种品牌、多种协议的 PLC 设备。传统做法是为每台设备硬编码通信

前言

工业自动化领域,上位机软件常常需要对接多种品牌、多种协议的 PLC 设备。传统做法是为每台设备硬编码通信参数和数据解析逻辑,一旦设备增减或配置变更,就得重新编译发布,维护成本高、灵活性差。有没有一种方式,能让设备接入像"搭积木"一样简单?

本文推荐一个基于成熟的 HslCommunication 通信库,通过 XML 配置文件驱动设备连接与数据采集,让 PLC 接入变得可配置、可扩展、可视化。

项目介绍

一个开源的 C# 类库,专注于工业设备(尤其是 PLC)的配置管理与数据读取。它不重复造轮子,而是深度整合 HslCommunication.dll 的能力,将设备类型、IP 地址、寄存器地址、数据解析规则等信息抽象为结构化的 XML 配置。

我们只需维护一份配置文件,即可动态加载任意数量的设备节点,并自动启动数据轮询、解析与分发服务。

项目功能

1、支持多层级设备组织

通过 NodeClass 构建"工厂-车间-设备"的树形结构,便于管理复杂现场。

2、灵活的设备配置

支持 Modbus TCP、西门子 S7、三菱 MC 等主流协议,可配置 IP、端口、站号、字节序等参数。

3、自定义数据解析规则

通过 RegularNode 定义数据块中各字段的名称、偏移、数据类型(如温度、转速、开关量),实现原始字节到业务对象的映射。

4、内置服务器能力

启动后自动按 CaptureInterval 轮询设备,并将解析后的数据以 JSON 形式提供给客户端。

5、多后端集成示例

除基础 SampleServer 外,还提供 Redis 数据持久化、OPC UA 服务发布等高级场景。

项目说明

一个设备及节点配置类库,基于 HslCommunication.dll 深度整合创建,用来实现对 PLC 配置信息的存储和加载解析,同时支持可配置化的 PLC 数据读取与数据显示。

服务器示例如下:

SampleServer

简单的演示了如何启动一个服务器程序。虽然示例是基于 Console 的应用程序,你也可以实现 WinForm 或 WPF 应用程序。

RedisServer

演示了如何创建一个服务器,并将读取到的数据存入 Redis。详细说明见下文。

OpcUaServer

由于 OPC UA 在工控界相当火爆,此处也集成了该示例,采用最新 1.4.354.0 版本的库实现。主要难点在于数据解析并创建节点,具体参照下文说明。

可通过 NuGet 安装:

Install-Package SharpNodeSettings

How to use

服务器和客户端均围绕一个 XML 配置文件构建。

示例 XML 内容如下:

<?xml version="1.0" encoding="utf-8"?>
<Settings>
<NodeClass Name="Devices" Description="所有的设备的集合对象">
    <NodeClass Name="分厂一" Description="">
      <NodeClass Name="车间一" Description="">
        <DeviceNode Name="测试空设备" Description="此设备安装在角落,编号0001" DeviceType="0" ConnectTimeOut="2000" CreateTime="2018/8/12 9:26:27" InstallationDate="2018/8/12 9:26:27">
          <DeviceRequest Name="数据请求" Description="一次完整的数据请求" Address="0" Length="10" CaptureInterval="1000" PraseRegularCode="B" />
        </DeviceNode>
      </NodeClass>
      <NodeClass Name="车间二" Description="">
        <DeviceNode Name="ModbusTcp客户端" Description="这是描述" DeviceType="10" ConnectTimeOut="1000" CreateTime="2018/8/9 19:58:49" InstallationDate="2018/8/9 19:58:49" IpAddress="127.0.0.1" Port="502" Station="1" IsAddressStartWithZero="true" IsWordReverse="false" IsStringReverse="false">
          <DeviceRequest Name="数据请求" Description="一次完整的数据请求" Address="0" Length="30" CaptureInterval="1000" PraseRegularCode="ABCD" />
        </DeviceNode>
      </NodeClass>
    </NodeClass>
    <NodeClass Name="分厂二" Description="位于西南方">
      <NodeClass Name="车间三" Description="">
        <DeviceNode Name="测试设备二" Description="这是测试设备二的描述" DeviceType="10" ConnectTimeOut="1000" CreateTime="2018/8/10 23:01:28" InstallationDate="2018/8/10 23:01:28" IpAddress="127.0.0.1" Port="502" Station="1" IsAddressStartWithZero="true" IsWordReverse="false" IsStringReverse="false">
          <DeviceRequest Name="数据请求" Description="一次完整的数据请求" Address="100" Length="10" CaptureInterval="500" PraseRegularCode="B" />
        </DeviceNode>
      </NodeClass>
    </NodeClass>
</NodeClass>
<NodeClass Name="Server" Description="所有挂载的服务器">
    <ServerNode Name="异形服务器" Description="这是一个异形服务器" CreateTime="2018/8/8 13:29:30" Port="1234" ServerType="2" Password="" />
</NodeClass>
<NodeClass Name="Regular" Description="所有的解析规则的信息">
    <RegularNode Name="ABCD" Description="">
      <RegularItemNode Name="温度" Description="" Index="0" TypeCode="3" TypeLength="1" />
      <RegularItemNode Name="风俗" Description="" Index="2" TypeCode="9" TypeLength="1" />
      <RegularItemNode Name="转速" Description="" Index="14" TypeCode="9" TypeLength="1" />
      <RegularItemNode Name="机器人关节" Description="" Index="18" TypeCode="9" TypeLength="6" />
      <RegularItemNode Name="cvsdf" Description="" Index="42" TypeCode="9" TypeLength="1" />
      <RegularItemNode Name="条码" Description="条码信息" Index="6" TypeCode="11" TypeLength="8" />
      <RegularItemNode Name="开关量" Description="设备的开关量信息" Index="368" TypeCode="1" TypeLength="8" />
    </RegularNode>
    <RegularNode Name="B" Description="">
      <RegularItemNode Name="温度" Description="" Index="0" TypeCode="3" TypeLength="1" />
      <RegularItemNode Name="压力" Description="" Index="2" TypeCode="3" TypeLength="1" />
    </RegularNode>
</NodeClass>
</Settings>

只要创建好这个 XML 文件,就可以调用 SharpNodeServer 创建服务器应用,自动生成节点信息,并根据配置自动请求设备、更新数据。

创建服务器的代码如下:

SharpNodeServer sharpNodeServer = new SharpNodeServer();
sharpNodeServer.LoadByXmlFile("settings.xml");
sharpNodeServer.ServerStart(12345);

这样就启动了一个最简单的服务器,主要包含实例化、加载配置、启动服务器三个步骤。注意:加载配置必须放在服务器启动之前。

怎样查看服务器的数据?

内置了一个默认的 SimplifyNet 服务器。

基于 NetSimplifyClient 实现了一个通用的数据节点查看器,需指定服务器 IP 和端口:

SharpNodeSettings.View.FormNodeView form = new SharpNodeSettings.View.FormNodeView("127.0.0.1"12345);
form.ShowDialog();

如果想访问单个数据,也可使用 NetSimplifyClient 的 Demo 工具。注意:此处请求的数据均为序列化的 JSON 字符串。

手动配置如此复杂的 XML 结构将是灾难性的,因此本库提供了一个可视化界面配置工具,代码如下:

Form nodeSettings = new SharpNodeSettings.View.FormNodeSetting("settings.xml");
nodeSettings.ShowDialog();

上述代码将打开配置窗口,加载当前目录下的 settings.xml 文件。

你也可以这样写,以获取用户配置后的数据,用于远程配置场景:

using (SharpNodeSettings.View.FormNodeSetting form = new SharpNodeSettings.View.FormNodeSetting(XElement.Load("settings.xml")))
{
    if (form.ShowDialog() == DialogResult.OK)
    {
        // 配置好的数据信息,在这种方式下可以实现远程配置操作
        XElement xElement = form.XmlSettings;
        MessageBox.Show("success");
    }
    else
    {
        MessageBox.Show("failed");
    }
}

在实际开发中,如果你不需要完整配置功能,只想让某个 PLC 设备信息可配置,也可以通过本组件实现:

SharpNodeSettings.View.FormSelectDevice selectDevice = new View.FormSelectDevice();
if (selectDevice.ShowDialog() == DialogResult.OK)
{
    XElement xmlDevice = selectDevice.DeviceXml;
    // 设备配置对象可用于存储、网络传输等操作
【声明】内容源于网络
0
0
dotNET跨平台
专注于.NET Core的技术传播。在这里你可以谈微软.NET,Mono的跨平台开发技术。在这里可以让你的.NET项目有新的思路,不局限于微软的技术栈,横跨Windows,
内容 883
粉丝 0
dotNET跨平台 专注于.NET Core的技术传播。在这里你可以谈微软.NET,Mono的跨平台开发技术。在这里可以让你的.NET项目有新的思路,不局限于微软的技术栈,横跨Windows,
总阅读14.5k
粉丝0
内容883