当前位置:   article > 正文

Modbus通信从入门到精通_2_Modbus TCP通信详解及仿真(搭建ModbusTCP仿真环境:创建虚拟PLC并进行ModbusTCP通讯;寄存器与PLC中映射关系;适合理解如何编写上位机)

modbus tcp

本篇将会以西门子PLC软件搭建ModbusTCP仿真环境,并通过仿真环境,介绍基础知识及模拟实际应用中写一个简单的通信读取PLC数据方法,并简介了编写上位机的方法。

由于具有TCP/IP栈协议,通常在Modbus TCP通讯的上位机开发中,上位机是作为客户端,控制器作为服务器。Modbus TCP使用基于客户端-服务器的模式,其中 客户端是发送请求的设备,服务器是响应请求的设备 。客户端发送称为"Modbus报文"的请求到服务器,服务器对请求进行解析并返回相应的数据。这种模式允许多个客户端同时与服务器通信。这在上篇中已做解释,本篇中的案例也是采用上位机是作为客户端,控制器作为服务器的方式。

1. 搭建ModbusTCP仿真环境

搭建ModbusTCP仿真环境可以采用以下两种方式

  • 怎么快速搭建一个ModbusTCP服务器? ModbusSlave。
  • 可以用西门子PLC来做ModbusTCP仿真环境

先搭建西门子PLC的仿真环境,写ModbusTCP的程序才能实现ModbusTCP仿真环境

1.1 PLC仿真环境搭建

1.1.1 S7-PLCSIM Advanced V3.0设置与程序下载

先安装博图软件(安装环境需要纯净,也可以使用虚拟机),安装授权完成之后启动以下软件来仿真PLC(不需要实际的PLC),设置如下图所示:IP为:192.168.1.166,黄色代表准备状态
在这里插入图片描述
由于是第一次创建实例,需要使用博图下载程序进去,首先创建一个解决方案
在这里插入图片描述
解决方案中还没有项目存在
在这里插入图片描述
创建新项目->“添加新设备”
在这里插入图片描述
因为是要做仿真,必选选择1500的PLC,一般选择如下图所示:
在这里插入图片描述
创建之后,需要改IP地址为与第一张截图中的IP地址一致,即:192.168.1.166

PLC有两个网卡,三个pn/dp,下图显示的是1段的也就是第二个网卡的信息,而我们一般使用的时默认的0段也就是第一个网卡
在这里插入图片描述
修改第一个网卡的IP地址为192.168.1.166,修改完之后会发现报错,这是因为网口1和网卡2是在一个网段,因此需要将网卡2的网段进行修改
在这里插入图片描述
将网卡2的网段进行修改到另一个网段就正常了
在这里插入图片描述
点击上方的“保存项目”
按照下图方式,尝试进行程序的下载
在这里插入图片描述
选择接口为“Siemens PLCSIM Virtual Ethernet Adapter”,后点击“开始搜索”
在这里插入图片描述
搜索之后找到了我们创建的虚拟的PLC的地址,但是无法下载
在这里插入图片描述
按下图进行编译之后,选择“下载到设备”->“硬件配置”->“开始搜索”,“下载按钮”就显示正常
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击“下载”之后
在这里插入图片描述
点击“装载”
在这里插入图片描述
如下图选择“启动模块”->“完成”,重启模块
在这里插入图片描述
此时一直无法装载成功,重新编译下载还是会报如下错误:
在这里插入图片描述
进行如下设置,细节如下:
在这里插入图片描述
在这里插入图片描述
重新编译下载之后进行装载成功
在这里插入图片描述
此时再查看软件界面,状态为绿色,代表程序下载成功
在这里插入图片描述

1.1.2 创建虚拟PLC并进行通讯

下载成功还是不能与虚拟的PLC进行通讯
可以进行一下尝试
利用以下软件创建一个西门子的PLC
在这里插入图片描述
设置如下:
在这里插入图片描述
创建一个组即M存储区
在这里插入图片描述
在这里插入图片描述
“保存配置”->“启动”
在这里插入图片描述
但仍显示“未连接”
在这里插入图片描述
还需进行操作:勾选“PUTGET”,并对设置进行保存,重新下载PLC
在这里插入图片描述
重新启动,显示已经连接
在这里插入图片描述
此时可以看到“MW0”的值为0
在这里插入图片描述
通过“组对象变量”->“修改变量”,将其修改为“33”
在这里插入图片描述
PLC程序中进行监控,监控方法如下,可以看到“MW0”的值变为33
在这里插入图片描述
上述的过程就可以实现一个虚拟的PLC与程序之间的通讯。“新阁教育配置一体化软件”扮演的角色就是实体PLC,“S7-PLCSIM Advanced V3.0”可能起到的一个中间环境配置的作用,具体后期可以查查官网资料。

在上面的基础上,增加一个“DB1”的“组对象”,同时将“MW0”的组对象禁止(双击组对象,“Active”取消勾选),启动之后发现无法连接
在这里插入图片描述
这是因为PLC程序中不存在“DB1”,所以也就无法连接进行读取
PLC中添加“DB1”
在这里插入图片描述
创建变量
在这里插入图片描述
创建变量值之后,点击“启动”还是无法访问,这是因为需要做以下设置
在这里插入图片描述
“优化的块访问”取消勾选
在这里插入图片描述
保存下载,重新启动,显示连接成功
在这里插入图片描述
修改值成功
在这里插入图片描述
在这里插入图片描述

1.1.3 PLC通讯中常见问题

有些时候还会碰到如下问题
有人将读取长度改为“100”个字节,但是最大只有28个字节,这也会导致无法连接成果
在这里插入图片描述
在这里插入图片描述

下面再给大家分享,如果出现PLC通信不上的问题之后,我们如何快速定位问题,解决问题?
1、我们首先要Ping一下PLC的IP地址,保证物理网络是正常的,一定要记住Ping通只能证明网络没问题,并不能代表一定可以通信。
2、西门子S7协议是基于TCP的,所以我们接下来可以用网络调试助手去连接PLC,IP地址填写PLC的IP地址,端口号填写102(表示端口开放)。
3、用通信测试平台测试变量,记住这里最好先测试M存储区,如MD100(M区是自带就有的,M区能读到后边主要就是优化的问题)。
4、如果通信测试平台可以,说明PLC端设置基本上都没问题了,但是如果这时候配置软件仍然有问题,可以先删除所有的组,只创建一个通信组,并且把存储区选择M存储区
5、如果上面的单个M存储区可以,一般就是你通信组配置的问题了,可以将所有的通信组的Active激活都取消然后逐个开启,定位是哪个或者哪几个通信组的问题,然后再找原因。

1.2 搭建ModbusTCP仿真环境

1.2.1 PLC中ModbusTCP通讯程序编写

需要写些程序来进行通讯,使得PLC成为ModbusTCP服务器
选择“MB_SERVER_DB”程序块
在这里插入图片描述
在这里插入图片描述

需要查看“帮助文档”对接口所需的进行配置,创建一个DB块,改名如下:
在这里插入图片描述
“InterfaceId”查看方式如下
在这里插入图片描述
PLC作为Modbus TCP通讯的服务器也就是local,连接PLC的客户端就是Remote,需要通过设置“RemoteAddress”设置可以连接PLC的IP地址。当你想要实现凡是知道PLC的IP地址和端口号就可以连接,无所谓客户端是谁,采用默认的“0”的设置即可(下图既是)。“LocalPort”是PLC的端口,最终的设置如下图所示:(相关的设置都可以查看帮助文档)
在这里插入图片描述
下载之后进行测试

1.2.2 上位机与PLC的ModbusTCP通讯测试

先用“网络调试助手”测试“502”端口有没有开
在这里插入图片描述
再利用“Modbus Poll”进行测试
在这里插入图片描述
在这里插入图片描述
“Modbus Poll”可以读取到PLC中DB1的值
在这里插入图片描述
也可以实现对DB1中某一个地址的值进行修改
在这里插入图片描述
这就实现PLC的通讯

1.2.3 使用到的寄存器与PLC中的映射关系

“MB_SERVER_DB”程序块是西门子提供,其中只写到了“MB_HOLD_REG”,但是我们知道Modbus有四个存储区(输入线圈、输出线圈、输入寄存器、输出寄存器),但是这个程序块中只写了一个存储区,这是因为西门子觉得某些是非必要的。

MB_HOLD_REG 指向Modbus TCP保持寄存器,可以是M存储区或者DB数据块 ,此处可以看到我们使用全局DB数据块为读写 Modbus 从站提供数据存储位置,当然如果使用M存储区也是可以的,看起来只能读写一类存储区
(问题:如果PLC程序中既使用了M区,又使用了DB数据块怎么处理?还是说只能控制PLC程序不要使用两类存储区?后期需要研究!)

在这里插入图片描述

这里把DB1开始的28个字节映射PLC中了

  • 输入线圈与I区进行映射,读输入的话也就读的是I区;
  • 输出线圈与Q区映射

使用“Modbus Poll”进行读取的方法如下:“Setup”->“Read/Write Definition”,读已采输入

在这里插入图片描述
下图是读到的I区,如果接的按钮就可以读到按钮的状态
在这里插入图片描述
同理,“Setup”->“Read/Write Definition”选择“01 Read Coils(0x)” 读取线圈,输入不可改,但是输出是可以修改的,下图将值变为1
在这里插入图片描述
在这里插入图片描述
通过PLC进行监控的话,上面修改为1的点为Q0.0,如果实际中这个点接个风扇或者电机就可以进行操作了
在这里插入图片描述

  • 输入寄存器映射PIW区

上面三个存储区,西门子都不太重视,主要重视的是输出寄存器即保持型寄存器,原因是:利用输出寄存器就可以实现Modbus tcp通信功能
既能表示读取和写入;又能表示bool、数值、寄存器
因此从某种角度说明,只使用输出寄存器就可以实现Modbus tcp通信功能

如何去做对应关系:
PLC中地址偏移量是以字节为单位,而Modbus是以寄存器为单位,一个寄存器存储两个字节

40001开始到40014 映射关系 P#DB1.DBX0.0 BYTE28:
P#DB1.DBX0.0 BYTE28是以指针形式表示的DB1的DBX0.0开始(在使用的西门子Modbus tcp的程序块中设置的“MB_HOLD_REG”输出寄存器),其有28个字节(28个字节对应14个寄存器),4001是第一个寄存器,往后数14个即可

“Modbus Poll”中“Setup”->“Read/Write Definition”选择“03 Read Holding Registers(4x)” 读取保持型寄存器
在这里插入图片描述
当想读取某个bool量,需要读取后做进一步的解析,将寄存器变为一个个的位,通过位做对应关系
这样写最大的问题在于bool的操作,不仅是读取,如何写入是很麻烦的
如果想操作DB1.DBX2.0怎么办?后边会讲

为什么通过“Modbus Poll”可以读取到这些数据呢?
答案是通过发报文
在这里插入图片描述
可以看到内部是在发报文和回收报文
在这里插入图片描述
如果没有“Modbus Poll”测试软件就得自己用程序去写,去写的前提是需要知道协议,知道如何去发和解析

一定不要错过的优秀博文: C#–通过Modbus TCP与西门子1200PLC通讯

2. ModbusTCP通信协议报文格式

对于Modbus基础的这里就不涉及了,直接讲协议

ModbusTCP 与 ModbusUDP 的报文格式是一样的,它们之间的区别其实就是 TCP 与 UDP 的区别,因此下面就针对 ModbusTCP 的协议进行分析,ModbusTCP 与 ModbusRTU (ModbusASCII)之间的区别如下图:
在这里插入图片描述
图中右上为串口协议,下为Modbus TCP的协议。从上图可以看出,ModbusTCP 在 Modbus 串行通信的基础上,去除了校验(由于 TCP 本身就带有校验)和设备地址 (ModbusTP 弱化了设备地址,用IP 地址来取代),再加上 MBAP 报文头(占7bytes)。

2.1 报文格式

Modbus TCP报文格式: MBAP +功能码+数据

MBAP分解为四个部分:事务处理标识符+协议标识符+长度+单位标识符
在这里插入图片描述

Tx:00 03 00 00 00 06 01 03 00 00 00 0A
Rx:00 03 00 00 00 17 01 03 14 00 7B 01 4E 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  • 1
  • 2

以上面截取到的报文进行分析

  • 事务处理标识符:占两个字节,00 03就是事务处理标识符,通过截取一段时间的报文可以看到它是依次递增的,也就是一个序号而已,没有实质意义
    在这里插入图片描述
  • 协议标识符:占两个字节,固定值,00 00
  • 长度:00 06后边有6个字节,00 17(16进制的,对应十进制为23)后面有3+10*2=23个字节,代表了它后面还有多少字节
  • 单位标识符(站地址(音译)):占一个字节,一般都设置为01,也可以是其他值,是否可以设置为其他值是与服务器相关的,西门子是支持改为其他值的
  • 功能码:干什么的,03代表读取保持寄存器
    Modbus 协议同时规定了二十几种功能码,但是常用的只有 8 种,用于针对上述存储区的读写如下表所示:
    在这里插入图片描述
  • 数据:是一个变化的,要读数据就配起始地址、长度,要写数据的话配写入的地址和数据

2.2 关于03(读取保持寄存器)功能码的说明

Tx:00 03 00 00 00 06 01 03 00 00 00 0A
  • 1

发送报文格式如下:
在这里插入图片描述

  • 事务/协议标识符:不用管,不用自增,全部用0
  • 长度:固定为6,这是因为读取保持寄存器,只有两个参数会变:从哪读,读多少个,但是其整体的长度是不会变的

发送报文含义:读取服务器1号从站(单元标识符0x01)保持寄存器,起始地址为0x6B=107(相对地址),对应地址为 40108(绝对地址),寄存器数量为 0x02=2,即读取1号从站保持寄存器,地址从 40108-40109,共 2个寄存器的数值。

返回报文格式如下:
在这里插入图片描述
返回报文含义:返回服务器1 号从站保持寄存器 40108-40109,共 2个寄存器的数值,返回字节数为4个,分别为02 2B 01 06,40108 对应数值为 0x022B,40109 对应数值为 0x0106。

Rx:00 03 00 00 00 17 01 03 14 00 7B 01 4E 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  • 1

00 7B对应的就是DB1.DBW0的值,01 4E对应的就是DB1.DBW2的值,上面的“14”代表十进制20个字节,即返回20个字节数据

看到所谓的协议,基本上也就可以理解为不同的通讯格式

3. 写一个简单的通信读取PLC数据

如果没有“Modbus Poll”测试软件,只有网络调试助手,在懂协议的情况下就可以任意读取数据,例如想要读取下图框选的DB1.DBW14处的值:
在这里插入图片描述
读取和返回对应如下图:上面的偏移量是PLC中地址偏移量是以字节为单位,而Modbus是以寄存器为单位,一个寄存器存储两个字节
在这里插入图片描述
通讯就是自己组织报文并发出,解析回的东西中的数据,这样就实现了与PLC的通讯

这个过程就称为封装通讯库,后期将会介绍如何手写通讯库

4.学习地址:Modbus TCP通信详解

注:文章中涉及的软件均可以在doNet公众号中下载

5. 下篇将会介绍如何使用Qt创建一个基于ModbusTCP的通信软件

参考博文:QT下的Modbus TCP 通讯

6. 施耐德Modicon M262的ModbusTCP通信

6.1 施耐德Modicon M262

在使用施耐德Modicon M262作为server,上位机作为client中,在server中功能码读取存储区位置的对应关系如下:
在这里插入图片描述
在这里插入图片描述

6.2 PLC中MX、MB、MW、MD的含义和长度

在这里插入图片描述

6.2 Qt上位机程序与地址表的对应关系

待续…

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/671465
推荐阅读
相关标签
  

闽ICP备14008679号