8

【.NET6+Modbus】Modbus TCP协议解析、仿真环境以及基于.NET实现基础通信

 2 years ago
source link: https://www.cnblogs.com/weskynet/p/16121383.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【.NET6+Modbus】Modbus TCP协议解析、仿真环境以及基于.NET实现基础通信

 前言:随着工业化的发展,目前越来越多的开发,从互联网走向传统行业。其中,工业领域也是其中之一,包括各大厂也都在陆陆续续加入工业4.0的进程当中。

工业领域,最核心的基础设施,应该是与下位硬件设备或程序进行通信有关的了,而下位机市场基本上是PLC的天下。而PLC产品就像编程语言一样,类型繁多,协议也多种多样。例如,西门子PLC最常用的S7协议、施耐德PLC最常用的Modbus协议、以及标准工业通信协议CIP协议等等。而多种通信协议里面,基于以太网通信的居多。以太网通信的里面,通用协议除了CIP协议,就属于Modbus TCP协议了。

接下来的内容,我会以从头开发一个简单的基于modbus tcp通信的案例,来实现一个基础的通信功能。

有关环境:

开发环境: VS 2022企业版

运行环境: Win 10 专业版

.NET 环境版本: .NET 6

【备注】 源码在文末 

1、新建一个基于.NET 6带控制器的webapi项目,以及一个类库项目。如下图所示,新建以后的项目目录结构。

2、由于modbus tcp通信实际上就是一个socket通信,所以在类库项目下,先创建了一个Modbus服务类,并且提供一个基于socket通信连接的方法。socket连接以后,需要返回socket实例拿来使用。

3、为了方便一点,再新增一个通用的返回信息类,用于存储一些返回信息使用。

4、基于以上的返回信息类,咱对连接方法进行稍微改造一下,让它看起来更方便一点。这样可以用来验证连接是否正常,以及返回对应的异常信息,好做进一步处理。

5、Modbus TCP请求的报文规则,一些解析信息如下:

站地址:默认0x01, 除非PLC告诉我们其他站地址。

功能码:代表读写数据时候指定的读写方法等。例如读取线圈的功能码是0x01。

地址和读取长度:地址目前个人在施耐德物理的PLC环境上,不能超过30000。同时,单次读写长度不能超过248个byte,否则PLC可能会飘。当然,也可能将来一些PLC可以支持更长的批量数据读写,目前在施耐德PLC环境下不支持(具体型号忘记了,有点久了,当前身边没得PLC了,等下会使用仿真工具来做环境)。

头部校验(消息唯一识别码):0~65535,用于PLC服务端进行区分不同的客户端而使用的一组数据标识,不同的客户端必须保证标识码不重合。例如多个客户端同时存在时候,发起的通信请求,必须保持不一样的识别码,否则Modbus服务端有可能会因为不知是哪个客户端发起的请求而导致信息乱了。

无(协议标识):默认0,代表是Modbus协议。

数据长度:发送的报文的长度,刚好是6位,所以可以写成固定值0x06。(写入的规则不一样,此处固定值只当作读取时候使用)

6、根据协议的一些具体内容,写一个存储功能码和异常返回码的数据类,用于后期做通信时候传参和通信数据验证使用。有关协议具体内容,如下代码所示。

7、由于异常码是byte数据,直接验证可能会麻烦一点,为了可以直观一些,此处再新增一个用于解析Modbus返回的异常信息的方法,用于备用。

8、根据协议规则,提供一些参数,并先搭建一个简单的方法框架,用来可以进行读取线圈的功能。包含简单的报文数据拆分以及报文发送和接收。由于发送报文长度不能超过248byte(1 bool大小 == 1 byte,如果是其他类型,需要做其他长度换算),所以当长度超过时候,做个简单的算法进行拆分再发送,防止发生不必要的异常。以下做一个读取线圈(Bool类型数据)的简单方法。

9、根据上方提供的协议报文组装规则,进行开发一个通用的报文组织方法。有高低位之分,所以对于占用2byte的数据,需要进行"倒装"。

10、发送报文以后,返回的报文含有校验信息:发送的数据报文的第7位的数据,加上 0x80 以后,跟返回的报文的第7位byte数据如果一致,则代表当前通信上可能有异常。异常码在接收的响应报文的第8位。

所以可以继续写一个验证是否成功的校验方法:

11、由于返回的数据也都是byte数据,以上读取的线圈值(布尔值),就需要提供一个数据类型转换的功能用于把byte数组转换为bool数组。

12、对读取线圈的最开始的方法,进行一些完善以后的代码如下。响应报文长度是 发送数据长度*2+9 。

13、接下来做一个简单的测试。准备一下仿真环境,进行本地的测试,看看是否可以连通。先准备两个工具,一个是 modbus poll,另一个是modbus slave。一个用来模拟服务端环境,另一个可用来模拟数据收发验证。

备注】:由于网上存在很多爬虫爬取博客文章到各个地方的,所以如果有需要这俩工具的小伙伴,可以点击该文章的 原文链接:【https://www.cnblogs.com/weskynet/p/16121383.html】的最下方的QQ群号进行加群进行获取,或者在文章最后提供的个人微信号,加我个人微信私发也可以。

14、两边都设置为读写单个线圈的功能,用于测试以上线圈读取的代码的功能。

15、两边都设置为modbus tcp连接方式。Slave站点启动以后,默认为本地,poll工具上的IP地址选择本地即可。如果是真实PLC环境,则填写真实PLC地址。

16、测试两边是否通信上。给任意一个地址写入一个true,可以看到另一边也同步更新,说明通信是通的了。

【注意】modbus工具,poll和slave工具默认占用了消息唯一标识码,大概是1~5左右的固定值,所以使用该工具期间,建议程序上的唯一消息识别码设置为5以上,以防止通信干扰。

17、接下来就可以继续完善代码进行验证了。先新增ModbusService的接口IModbusService,用于实现依赖注入。然后在program.cs文件里面进行服务注册。

18、新建一个控制器,用来进行模拟实验。有关代码和注释如图所示。

19、进行读取一个长度试试效果。结果是数据不支持,说明报文有问题。

20、通过断点,找到问题所在,上面的代码里面,length经过简单算法计算以后等于0,此处需要用的应该是newLength变量的值。

21、再次测试,地址从1开始,读取两个地址,结果符合预期。

22、再测试一下,从0开始读取30个,并随即设置若干个是True的值。

23、其他的写入、以及其他类型读写,基本类似。由于篇幅有限,就不继续进行一步一步操作的截图了。读取的,选好类型,报文格式都是一样的,唯一有差别的是写入的报文。下面是写入单个线圈值的报文。线圈当前仅支持一个一个写入。

24、写入寄存器的规则会有些偏差,协议规则如下图。

【备注】以上图的标题,我写错了,应该是 “写入寄存器”报文协议,懒得换图了,大佬们看的时候自己辨别哈~

 读取线圈当作引导,其他类型也都异曲同工,大佬们可以自行尝试。

 另外说点,如果是生产环境下使用,建议把客户端连接做成【长连接】,不然重复创建连接比较耗费资源,耗时也会因为新建连接而占用一大半。同时,如果是多线程访问,使用同一个客户端连接,必须加锁,否则会干扰数据;如果是多线程,不同客户端,就要保证每个消息识别码必须不同,如果存在同一个识别码,很容易发生数据异常等情况。

有关源码:

ModbusService源码:

ContractedBlock.gifExpandedBlockStart.gif

View Code

控制器源码:

ContractedBlock.gifExpandedBlockStart.gif

View Code

功能码和异常码:

ContractedBlock.gifExpandedBlockStart.gif

View Code

好了,以上就是该文章的全部内容。如果觉得有帮助,欢迎一键三连啊~~ 如果有兴趣,也可以加我私人微信,欢迎大佬来我微信群做客。私人微信:【WeskyNet001】


Recommend

  • 48

    使用Python的modbus_tk模块包来连接Modubs Slave

  • 51
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    Modbus 调试助手的使用(一)

    点击上方蓝字可直接关注呦~ 记得当时还百度来着,然鹅并没有找到自己想要的东西,鉴于此,写一个对初学者友好的教程。 上一篇文章提到 Modbus 协议包括 ASCII、RTU、TCP...

  • 24

    前言 工业控制已从单机控制走向集中监控、集散控制,如今已进入网络时代,工业控制器连网也为网络管理提供了方便。Modbus 就是工业控制器的网络协议中的一种。在2004年,中国国家标准委员会正式把Modbus作为了...

  • 30

    前言: Modbus 是由Modicon公司1979年发行的,已经被广泛应用于工业控制现场的应用层协议,如Modbus协议已被广泛应用于在监控和控制现场设备。Modbus协议最初是通过串行数据进行通信的,也...

  • 16

    前言: 如今工业控制系统设计的领域包括交通运输、能源行业、装备制造、机械制造等多个国家关键基础领域。工业控制系统的信息安全问题关系到国家安全和社会稳定。Modbus 协议是一种典型的工...

  • 25
    • www.freebuf.com 4 years ago
    • Cache

    Modbus安全:M340停启和流量分析

    前言 随着施耐德(Schneider)新款的Modicon M340可编程控制器集各种强劲功能和创新设计于一身,为复杂设备制造商和中小型项目提供各种自动化功能的最佳技术和高效、灵活、经济性的解决方案。且Modicon M340充...

  • 15

    ``` docker pull microsoft-azureiotedge-modbus ``` # Featured Tags `docker pull mcr.microsoft.com/azureiotedge/modbus:1.0` + 1.0 [comment]: (# Featured Repos) [comment]: (Please, provide the information for this section and un...

  • 7
    • blog.51cto.com 2 years ago
    • Cache

    Modbus协议详解#yyds干货盘点#

    Modbus协议详解 ?作者介绍:中国DBA联盟(ACDU)成员。目前从事工业自动化软件开发工作。擅长C#、Java、机器视觉、底层算法等语言。2019年成立柒月软件工作室,2021年注册苏州凯捷智能科技有限公司 ?如果文章对你有帮助,欢迎关注、点赞、...

  • 4

    物联网平台Modbus协议采样命令下发并发性能测试方法 作者:张鹏飞 2023-02-09 18:30:27 移动开发 Modbus已经成为工业领域通信协议的业界...

  • 7

    想了解更多关于开源的内容,请访问:

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK