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

一、简介

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

优势:

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

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

3、内置打包算法

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

二、nuget安装

<PackageReference Include="ThingsGateway.Foundation.Modbus" Version="6.0.3.47" />

三、使用指南

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",null);

 //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<VariableClass> 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<VariableSourceClass>(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(null, 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(null, 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值