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

文章目录

  • 1. 搭建ModbusTCP仿真环境
    • 1.1 PLC仿真环境搭建
      • 1.1.1 S7-PLCSIM Advanced V3.0设置与程序下载
      • 1.1.2 创建虚拟PLC并进行通讯
      • 1.1.3 PLC通讯中常见问题
    • 1.2 搭建ModbusTCP仿真环境
      • 1.2.1 PLC中ModbusTCP通讯程序编写
      • 1.2.2 上位机与PLC的ModbusTCP通讯测试
      • 1.2.3 使用到的寄存器与PLC中的映射关系
  • 2. ModbusTCP通信协议报文格式
    • 2.1 报文格式
    • 2.2 关于03(读取保持寄存器)功能码的说明
  • 3. 写一个简单的通信读取PLC数据
  • 5. 下篇将会介绍如何使用Qt创建一个基于ModbusTCP的通信软件
  • 6. 施耐德Modicon M262的ModbusTCP通信
    • 6.1 施耐德Modicon M262
    • 6.2 PLC中MX、MB、MW、MD的含义和长度
    • 6.2 Qt上位机程序与地址表的对应关系

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有四个存储区(输入线圈、输出线圈、输入寄存器、输出寄存器),但是这个程序块中只写了一个存储区,这是因为西门子觉得某些是非必要的。

  • 输入线圈与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”测试软件就得自己用程序去写,去写的前提是需要知道协议,知道如何去发和解析

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

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

  • 事务处理标识符:占两个字节,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

发送报文格式如下:

  • 事务/协议标识符:不用管,不用自增,全部用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

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上位机程序与地址表的对应关系

待续…

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

  1. Spring Data JPA 从入门到精通~Naming命名策略详解及其实践

    Naming 命名策略详解及其实践 用 JPA 离不开 @Entity 实体,我都知道实体里面有字段映射,而字段映射的方法有两种: 显式命名:在映射配置时,设置的数据库表名.列名等,就是进行显式命名, ...

  2. spark从入门到精通spark内存管理详解- 堆内堆外内存管理

    前言 Spark作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解Spark内存管理的基本原理,有助于更好地开发Spark应用程序和进行性能调优.本文将详细介绍两部 ...

  3. Java快速入门到精通— Java break语句详解

    所有流行的编程语言中都有循环语句.JAVA 中采用的循环语句与C语言中的循环语句相似,主要有 while.do-while 和 for! 那么在某些时候需要在某种条件出现时强行终止循环,而不是等到循环 ...

  4. Spring Data JPA 从入门到精通~Auditing及其事件详解

    Auditing 及其事件详解 Auditing 翻译过来是审计和审核,Spring 的优秀之处在于帮我们想到了很多繁琐事情的解决方案,我们在实际的业务系统中,针对一张表的操作大部分是需要记录谁什么时 ...

  5. TCP/IP详解--第五章

    第5章 RARP:逆地址解析协议 5.1   引言   具有本地磁盘的系统引导时,一般是从磁盘上的配置文件中读取  I P地址.但是无盘机, 如X终端或无盘工作站,则需要采用其他方法来获得 IP地址. ...

  6. 用LabVIEW编写上位机

    要点: 1.安装VISA 2.底层通过串口转USB与PC相连,数据通过串口传输.串口名称即对应的串口号.当你插上USB后,LabVIEW会自动的识别可用的串口号. 总结:用Labview写通用板子的上 ...

  7. 以太网采集欧姆龙PLC DM数据并存入ACCESS 使用C#编写上位机程序

    以太网采集欧姆龙PLC DM数据并存入ACCESS 使用C#编写上位机程序,通过以太网使用FinsTCP协议读取欧姆龙PLC DM区数据. 附图是程序界面,只要输入PLC IP地址.DM区起始地址号和 ...

  8. TCP/IP详解--第十七章

     第17章 TCP:传输控制协议 17.1    引言   本章将介绍 TCP为应用层提供的服务,以及 TCP首部中的各个字段.随后的几章我们在了 解TCP的工作过程中将对这些字段作详细介绍. 对TC ...

  9. TCP/IP详解--第一章

    说明:专栏中的内容是<TCP/IP详解>这本书,博主分享在此. 第1章概     述 1.1   引言 很多不同的厂家生产各种型号的计算机,它们运行完全不同的操作系统,但  TCP/IP协 ...

最新文章

  1. 数学——函数极限知识以及sympy库的limit
  2. InfluxDB:cannot use field in group by clause
  3. android获取wifi连接状态,获取android设备wifi连接状态
  4. 【理论】红黑树的实现原理
  5. c++string替换指定位置字符_Excel数据分析:如何替换字符串中的指定字符?
  6. Servlet3.0下配置Servlet
  7. Android 编译系统分析(一)
  8. 使用Google Guice消除实例之间的歧义
  9. lorenz系统simulink仿真_simulink控制系统仿真之控制系统的分析方法(2)(频域分析法)...
  10. 卷积神经网络CNN(Convolutional Neural Network)原理与代码实现 Le-Net5
  11. cocos2dx 3.0 触摸机制
  12. 【Axure RP8.1】一款专业的快速原型设计工具
  13. cm agent主机异常Error, CM server guid updated, expected
  14. Neo4j 下载安装
  15. Ruby学习-Ruby语言的一些特点
  16. 美国第二位CTO Todd Park将离职
  17. Android 分享到LINE
  18. 实现动画切换渐进渐出效果
  19. STM32———高级定时器的死区时间计算方法
  20. linux 略过目录,Linux命令-----grep不查找隐藏文件夹(或者跳过某些文件夹)的方法...

热门文章

  1. 通过命令查看linux 密码,linux查看用户密码(linux查看用户密码命令)
  2. python发送邮件脚本
  3. liveplayer免费网页直播|点播播放器-页面动态多播放器添加代码示例
  4. 服务器实践002 -- 裸跑一个flask程序
  5. unity Image/RawImage贴图透明度渐变/融合 正片叠底
  6. 《Guiding Deep Learning System Testing using Surprise Adequacy》论文笔记
  7. Mit6.006-problemSession04
  8. 蓝桥杯题目——带分数
  9. 北京有这些互联网公司,你都知道么?
  10. 如何查看镜像nginx的版本号