赞
踩
本篇将会以西门子PLC软件搭建ModbusTCP仿真环境,并通过仿真环境,介绍基础知识及模拟实际应用中写一个简单的通信读取PLC数据方法,并简介了编写上位机的方法。
由于具有TCP/IP栈协议,通常在Modbus TCP通讯的上位机开发中,上位机是作为客户端,控制器作为服务器。Modbus TCP使用基于客户端-服务器的模式,其中 客户端是发送请求的设备,服务器是响应请求的设备 。客户端发送称为"Modbus报文"的请求到服务器,服务器对请求进行解析并返回相应的数据。这种模式允许多个客户端同时与服务器通信。这在上篇中已做解释,本篇中的案例也是采用上位机是作为客户端,控制器作为服务器
的方式。
搭建ModbusTCP仿真环境可以采用以下两种方式
先搭建西门子PLC的仿真环境,写ModbusTCP的程序才能实现ModbusTCP仿真环境
先安装博图软件(安装环境需要纯净,也可以使用虚拟机),安装授权完成之后启动以下软件来仿真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的地址,但是无法下载
按下图进行编译之后,选择“下载到设备”->“硬件配置”->“开始搜索”,“下载按钮”就显示正常
点击“下载”之后
点击“装载”
如下图选择“启动模块”->“完成”,重启模块
此时一直无法装载成功,重新编译下载还是会报如下错误:
进行如下设置,细节如下:
重新编译下载之后进行装载成功
此时再查看软件界面,状态为绿色,代表程序下载成功
下载成功还是不能与虚拟的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”
创建变量
创建变量值之后,点击“启动”还是无法访问,这是因为需要做以下设置
“优化的块访问”取消勾选
保存下载,重新启动,显示连接成功
修改值成功
有些时候还会碰到如下问题
有人将读取长度改为“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激活都取消然后逐个开启,定位是哪个或者哪几个通信组的问题,然后再找原因。
需要写些程序来进行通讯,使得PLC成为ModbusTCP服务器
选择“MB_SERVER_DB”程序块
需要查看“帮助文档”对接口所需的进行配置,创建一个DB块,改名如下:
“InterfaceId”查看方式如下
PLC作为Modbus TCP通讯的服务器也就是local,连接PLC的客户端就是Remote,需要通过设置“RemoteAddress”设置可以连接PLC的IP地址。当你想要实现凡是知道PLC的IP地址和端口号就可以连接,无所谓客户端是谁,采用默认的“0”的设置即可(下图既是)。“LocalPort”是PLC的端口,最终的设置如下图所示:(相关的设置都可以查看帮助文档)
下载之后进行测试
先用“网络调试助手”测试“502”端口有没有开
再利用“Modbus Poll”进行测试
“Modbus Poll”可以读取到PLC中DB1的值
也可以实现对DB1中某一个地址的值进行修改
这就实现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中了
使用“Modbus Poll”进行读取的方法如下:“Setup”->“Read/Write Definition”,读已采输入
下图是读到的I区,如果接的按钮就可以读到按钮的状态
同理,“Setup”->“Read/Write Definition”选择“01 Read Coils(0x)” 读取线圈,输入不可改,但是输出是可以修改的,下图将值变为1
通过PLC进行监控的话,上面修改为1的点为Q0.0,如果实际中这个点接个风扇或者电机就可以进行操作了
上面三个存储区,西门子都不太重视,主要重视的是输出寄存器即保持型寄存器
,原因是:利用输出寄存器就可以实现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通讯
对于Modbus基础的这里就不涉及了,直接讲协议
ModbusTCP 与 ModbusUDP 的报文格式是一样的,它们之间的区别其实就是 TCP 与 UDP 的区别,因此下面就针对 ModbusTCP 的协议进行分析,ModbusTCP 与 ModbusRTU (ModbusASCII)之间的区别如下图:
图中右上为串口协议,下为Modbus TCP的协议。从上图可以看出,ModbusTCP 在 Modbus 串行通信的基础上,去除了校验(由于 TCP 本身就带有校验)和设备地址 (ModbusTP 弱化了设备地址,用IP 地址来取代),再加上 MBAP 报文头(占7bytes)。
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
以上面截取到的报文进行分析
00 03
就是事务处理标识符,通过截取一段时间的报文可以看到它是依次递增的,也就是一个序号而已,没有实质意义00 00
00 06
后边有6个字节,00 17
(16进制的,对应十进制为23)后面有3+10*2=23个字节,代表了它后面还有多少字节01
,也可以是其他值,是否可以设置为其他值是与服务器相关的,西门子是支持改为其他值的03
代表读取保持寄存器Tx:00 03 00 00 00 06 01 03 00 00 00 0A
发送报文格式如下:
从哪读,读多少个
,但是其整体的长度是不会变的发送报文含义:读取服务器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
00 7B
对应的就是DB1.DBW0
的值,01 4E
对应的就是DB1.DBW2
的值,上面的“14”代表十进制20个字节,即返回20个字节数据
看到所谓的协议,基本上也就可以理解为不同的通讯格式
如果没有“Modbus Poll”测试软件,只有网络调试助手,在懂协议的情况下就可以任意读取数据,例如想要读取下图框选的DB1.DBW14处的值:
读取和返回对应如下图:上面的偏移量是PLC中地址偏移量是以字节为单位,而Modbus是以寄存器为单位,一个寄存器存储两个字节
通讯就是自己组织报文并发出,解析回的东西中的数据,这样就实现了与PLC的通讯
这个过程就称为封装通讯库
,后期将会介绍如何手写通讯库
4.学习地址:Modbus TCP通信详解
注:文章中涉及的软件均可以在doNet公众号中下载
参考博文:QT下的Modbus TCP 通讯
在使用施耐德Modicon M262作为server,上位机作为client中,在server中功能码读取存储区位置的对应关系如下:
待续…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。