百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

简单实用的Modbus类库,支持从站和DTU

suiw9 2025-04-01 22:09 7 浏览 0 评论

一、简介


ThingsGateway.Foundation.Modbus 用于Modbus协议通讯,支持主站/从站、ModbusTcp/ModbusRtu,通讯链路支持串口/Tcp/Udp、被动连接(Dtu)

优势:

1、通讯链路与协议解析类松耦合设计

2、支持被动连接(Dtu)设备

3、内置打包算法

4、实体通讯结果映射,并支持打包连读

二、nuget安装

三、使用指南

3.1、创建通道

var clientConfig = new TouchSocketConfig();

//tcp服务

//var clientChannel = clientConfig.GetTcpServiceWithBindIPHost("tcp://127.0.0.1:502");

//串口

//var clientChannel = clientConfig.GetSerialPortWithOption("COM1");

//udp

//var clientChannel = clientConfig.GetUdpSessionWithIPHost("127.0.0.1:502",);


//tcp客户端

var clientChannel = clientConfig.GetTcpClientWithIPHost("127.0.0.1:502");


3.2、创建协议类

modbus主站

ModbusMaster modbusMaster = new(clientChannel)

{

//modbus协议格式

ModbusType = Modbus.ModbusTypeEnum.ModbusRtu,

//ModbusType = Modbus.ModbusTypeEnum.ModbusTcp,


//默认站号

Station = 1,

//默认数据格式

DataFormat = DataFormatEnum.ABCD,

//读写超时

Timeout = 3000,

};

modbus从站

ModbusSlave modbusSlave = new(clientChannel)

{

//modbus协议格式

ModbusType = Modbus.ModbusTypeEnum.ModbusRtu,

//ModbusType = Modbus.ModbusTypeEnum.ModbusTcp,


//默认站号

Station = 1,

//默认数据格式

DataFormat = DataFormatEnum.ABCD,

};

3.3、读写

读取

//单独读取Int16类型,其他类型操作类似

var data = await modbusMaster.ReadInt16Async("40001");

//批量读取Int16类型,其他类型操作类似

var data = await modbusMaster.ReadInt16Async("40001", 10);

//对于4字节的解析规则,可在协议类中设置 ``DataFormat`` 属性,也可以读取方式时传入字符串

var data = await modbusMaster.ReadSingleAsync("40001;data=ABCD");

//传入的寄存器地址规则,可以通过文档查看,或者调用GetAddressDescription方法

//查看modbus驱动地址说明

Console.WriteLine(modbusMaster.GetAddressDescription());

//批量读取字节数组

var data = await modbusMaster.ReadAsync("40001", 10);

//也可以直接通过字节数组,获取需要的数据类型

if(data.IsSuccess)

{

ValueByteBlock valueByteBlock = new(data.Content);

//读取float

valueByteBlock.ReadFloat(EndianType.LittleSwap);

}

写入

//调用WriteAsync方法

var result = await modbusMaster.WriteAsync("40001",(ushort)1);


3.4、打包读取

IVariable接口实现

1、实现IVariable接口

2、实现IVariableSource接口

3、调用LoadSourceRead,返回打包封装类

4、调用ReadAsync读取数据,并调用PraseStructContent解析数据

5、解析数据后,可以通过IVariable获取解析后的数据


//通过数据库等方式获取寄存器/数据类型等配置

List variableClasses = new()

{

new VariableClass()

{

DataType=DataTypeEnum.Int16,

RegisterAddress="40001",

IntervalTime=1000,

},

new VariableClass()

{

DataType=DataTypeEnum.Int32,

RegisterAddress="40011",

IntervalTime=1000,

},

};

//调用LoadSourceRead,返回打包封装类

var deviceVariableSourceReads = modbusMaster.LoadSourceRead(variableClasses, 100, 1000);


//IVariableSource列表,调用ReadAsync读取字节数据,并调用PraseStructContent解析数据

foreach (var item in deviceVariableSourceReads)

{

var result = await modbusMaster.ReadAsync(item.RegisterAddress, item.Length);

if (result.IsSuccess)

{

try

{

var result1 = item.VariableRunTimes.PraseStructContent(modbusMaster, result.Content, exWhenAny: true);

if (!result1.IsSuccess)

{

//失败日志

item.LastErrorMessage = result1.ErrorMessage;

item.VariableRunTimes.ForEach(a => a.SetValue(, isOnline: false));

modbusMaster.Logger.Warning(result1.ToString());

}

}

catch (Exception ex)

{

modbusMaster.Logger.Exception(ex);

}

}

else

{

//通讯失败日志

item.LastErrorMessage = result.ErrorMessage;

item.VariableRunTimes.ForEach(a => a.SetValue(, isOnline: false));

modbusMaster.Logger.Warning(result.ToString());

}

}

VariableObject实体类实现

1、实现VariableObject虚类,添加业务属性,业务属性需添加VariableRuntime特性,指定寄存器地址、特定数据类型(不填默认为C#属性类型)、读写表达式(原始值为raw,可填:raw*100+10,做一些数学转换))

2、实例化业务实体类,需传入协议对象与连读打包的最大数量

3、可以看到源代码生成器已经自动生成了写入方法,可直接调用WriteAlarmLimitAsync法写入数据

4、调用MultiReadAsync方法执行连读,结果会自动解析到业务实体类的属性中

实体类配置属性VariableRuntime特性


[GeneratorVariable]

public partial class ModbusVariable : VariableObject

{

[VariableRuntime(RegisterAddress = "400051",ReadExpressions ="raw*10")]

public ushort AlarmLevel { get; set; }


[VariableRuntime(RegisterAddress = "400061;len=10")]

public string AlarmText { get; set; }


[VariableRuntime(RegisterAddress = "400071")]

public float AlarmLimit { get; set; }


public ModbusVariable(IProtocol protocol, int maxPack) : base(protocol, maxPack)

{

}

}

//构造实体类对象,传入协议对象与连读打包的最大数量

ModbusVariable modbusVariable = new(modbusMaster, 100);


//读取,成功结果会映射到实体属性中

var result= await modbusVariable.MultiReadAsync();


//写入

//源生成器自动生成了``(Write{属性名称})Async``方法,直接调用即可

await modbusVariable.WriteAlarmLimitAsync(100);

//输出实体json查看

Console.WriteLine(modbusVariable.ToJsonString());

四、性能测试

下面可以看到与HslCommunication的基准测试对比

采集100个连续寄存器,采用ModSim32作为测试模拟设备端

[Benchmark]

public async Task ThingsGateway()

{

for (int i = 0; i < Program.NumberOfItems; i++)

{

var result = await thingsgatewaymodbus.ReadAsync("40001", 100);

if (!result.IsSuccess)

{

throw new Exception(result.ToString());

}

}

}


[Benchmark]

public async Task HslCommunication()

{

for (int i = 0; i < Program.NumberOfItems; i++)

{

var result = await modbusTcpNet.ReadAsync("0", 100);

if (!result.IsSuccess)

{

throw new Exception(result.Message);

}

}

}

得益于字节池与Socket异步,虽然都采用字符串解析寄存器地址的方式,但ThingsGateway的内存耗用比较低,并且采集通讯速度更快

五、总结


ThingsGateway.Foundation.Modbus,非常好用的modbus协议库,尤其是实体通讯类以及自动打包的功能,非常适用于上位机业务使用。

Gitee仓库地址
https://gitee.com/diego2098/ThingsGateway

Github仓库地址
https://github.com/kimdiego2098/ThingsGateway


相关推荐

10款超实用JavaScript音频库(js播放音频代码)

HTML5提供了一种新的音频标签实现和规范用一个简单的HTML对象而无需音频插件来控制音频。这只是一个简单的整合这些新的HTML5音频特征及使用JavaScript来创建各种播放控制。下面将介绍10款...

Howler.js,一款神奇的 JavaScript 开源网络音频工具库

o...

PROFINET转Modbus网关——工业协议融合的智能枢纽

三格电子SG-PNh750-MOD-221,无缝连接Profinet与Modbus,赋能工业物联产品概述...

简单实用的Modbus类库,支持从站和DTU

一、简介...

[西门子PLC] S7-200 SMART PROFINET :通过GSD组态PLC设备

从S7-200SMARTV2.5版本开始,S7-200SMART开始支持做PROFINETIO通信的智能设备。从而,两个S7-200SMART之间可以进行PROFINETI...

Modbus(RTU / TCP)有什么异同(modbus tcp和tcp)

Modbus是一种广泛使用的工业自动化通信协议,它支持设备之间的数据交换。Modbus协议有两个主要的变体:ModbusRTU(二进制模式)和ModbusTCP(基于TCP/IP网络的模式)。尽管...

Modbus通信调试步骤详解(modbus调试工具怎么用)

Modbus通信调试步骤详解  Modbus通信分为串口和以太网,无论是串口还是以太网,只要是标准Modbus,就可以用Modbus模拟器进行调试。按以下几步进行调试。...

理解Intel手册汇编指令(intel 汇编指令手册)

指令格式...

「西门子PLC」S7-200 SMART的Modbus RTU通讯

S7-200SMART集成的RS485端口(端口0)以及SBCM01RS485/232信号板(端口1)两个通信端口可以同时做MODBUSRTU主站,或者一个做MODBUSRTU主站一个做MO...

InfiniBand网络运维全指南:从驱动安装到故障排查

一、InfiniBand网络概述InfiniBand(直译为“无限带宽”技术,缩写为IB)是一种用于高性能计算的计算机网络通信标准,具有极高的吞吐量和极低的延迟,用于计算机与计算机之间的数据互连。它...

一加回归 OPPO,背后的秘密不可告人

有这样一个手机品牌,它诞生于互联网品牌。在大众群体看来,它的身世似乎模糊不清,许多人以为它是国外品牌。它的产品定位是极客群体,深受国内发烧友,甚至国外极客玩家喜爱。...

[西门子PLC] S7-200SMART快速高效的完成Modbus通信程序的设计

一、导读Modbus通信是一种被广泛应用的通信协议,在变频器、智能仪表还有其他一些智能设备上都能见到它的身影。本文呢,就把S7-200SMART系列PLC当作Modbus主站,把...

狂肝10个月手搓GPU,他们在我的世界中玩起我的世界,梦想成真

梦晨衡宇萧箫发自凹非寺量子位|公众号QbitAI自从有人在《我的世界》里用红石电路造出CPU,就流传着一个梗:...

[西门子PLC] 博途TIA portal SCL编程基础入门:1-点动与自锁

一、S7-SCL编程语言简介...

工作原理系列之:Modbus(modbus工作过程)

MODBUS是一种在自动化工业中广泛应用的高速串行通信协议。该协议是由Modion公司(现在由施耐德电气公司获得)于1979年为自己的可编程逻辑控制器开发的。该协议充当了PLCS和智能自动化设备之间的...

取消回复欢迎 发表评论: