一、 说明
ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。
当在一ModBus网络上通信时,此协议决定了每个控制器需要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用ModBus协议发出。在其它网络上,包含了ModBus协议的消息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。
此协议支持传统的RS-232、RS-422、RS-485和以太网设备。许多工业设备,包括PLC,DCS,智能仪表等都在使用ModBus协议作为他们之间的通讯标准。
Modbus根据串口与网口模式,分为RTU和TCP两种协议
《ModBus驱动用户手册》指导用户进行ModBus驱动的正确配置。内容可分为驱动配置和驱动测试,正确结果为ModBus驱动可以读写ModSim的值。
二、 ModBus驱动配置
《Modbus驱动配置》目的是本地的ModBusRTU和ModBusTCP能够读写通过ModBus服务端的数据
modbus驱动根据协议不同,分为两个驱动,请根据实际情况配置:
- modbusRTU,用于通过窗口通信
- modbusTCP,用于通过网口通信
1. ModSim和ModScan使用
ModSim是ModBus模拟器,用来模拟ModBus中的寄存器数值,可以通过ModScan读取到该寄存器值。
用到ModSim4中寄存器,分别是Coil Outputs(DO)、Digital Inputs(DI)、Analogue Inputs(AI)、Holding Registers (AO)
2. 驱动配置
系统驱动中需要包含ModBusRTU和ModBusTCP这两个驱动,并在t_device_driver中配置好驱动,注意id为主键,不可重复
驱动名称根据协议不同,请选择:modbustcp或者modbusrtu
3. 设备配置
- 通信连接配置
- modbustcp驱动
- 连接方式(conntype)请选择tcpclient方式
- 连接参数:
- 设备IP输入设备的实际IP
- 设备端口 (port)一般是502,除非特别指定
- 示例:添加设备,连接方式选择tcpclient,驱动ID为t_device_driver中配置的驱动的id,设备id为主键,连接参数格式为ip=xx.xx.xx.xx;port=xx
- modbusrtu驱动
- 连接方式, 请选择serial串口方式
- 连接参数:
- 对于网关,有4个串口,串口名称分别需要输入:/dev/ttyO1,/dev/ttyO2,/dev/ttyO3,/dev/ttyO4, 具体见:串口通讯参数配置
- 对于windows,串口为:COM1,COM2,COM3,COM4,以此类推。可通过设备管理器查看应该配置哪个串口
- 对于Linux,串口根据情况而定
- 配置串口波特率、奇偶校验位等
- modbustcp驱动
- 设备参数配置
- 设备参数1:站号或从级地址,通常用于modbusrtu以区分不同设备。如果设备未说明,可不输入
- 设备参数2:无或者0表示按正常指令;1表示多寄存器指令。通常不需要填写
- 设备参数3:每个数据块自动组块时的最大字节数。缺省为230个字节。通常不需要填写
- 例外情况包括:北辰模块有时候,只能取98个寄存器(196个字节),此时如果读取不到就需要调整这个值
- modbustcp,通过网络方式配置的数据库示例:
- modbusrtu,网关中配置示例,网关第一个串口为/dev/ttyO1:
- modbusrtu,windows中配置示例,windows第一个串口为COM1:
4. 变量配置
在表t_device_tag中配置点名。
- 点名格式为:数据类型:地址
- 数据块类型:AI、AO、DI、DO
- 地址从1开始,如AI:1表示ai类型地址为1的寄存器的值。
- 如果需要寄存器的一个位,则用AI:1.0
三、 测试
- modsim工具是一个可以模拟真实设备的程序。
- 打开ModSim,选择数据类型为Holding Registers, 对应数据库中的AO类型的点
- 启动bin\start_pkmemdb.bat,
- 启动bin\pknodeserver.exe,将点写入内存数据库中
- 启动bin\pktagmonitor.exe,用于检测点值
- 修改40001的点值,观察exe的值得变化
四、 功能码请求类型
读取寄存器功能码:
读取AI(输入寄存器):3
读取AO(保持寄存器):4
读取DO(线圈状态):1
读取DI(输入位寄存器):2
写入寄存器功能码:
写入DO(单个线圈):5
写入AO(单个寄存器):6
写入DO(多个线圈):15
写入AO(多个寄存器):16
五、 ModBusTCP协议分析
ModBusTCP无校验码,头部6个长度,数据区(pdu)读请求为6个字节,读应答根据请求寄存器长度而定。
- 从地址1开始读取10个AO寄存器的请求,固定12个字节,蓝色为请求头部,红色为数据负荷pdu:
03 6D 00 00 00 06 01 03 00 00 00 0A
解释:
03 6D两个字节是主机发出的检验信息(事务号)。从机(即设备)只需将这两个字节的内容copy以后再放到response的报文相应位置,头部
00 00 两个字节表示tcp/ip的协议是modbus协议,头部
00 06表示该字节以后的长度。读固定为6个字节,头部
01 站号,缺省为1,头部
03 功能码,读取AO为03,读取AI为04,读取DI为02,读取DO为01,头部
00 起始地址高字节,PDU部分数据
00 起始地址低字节,PDU部分数据
00 读取寄存器个数,高字节,PDU部分数据
0A 读取寄存器个数,低字节,PDU部分数据
设备返回的从地址1开始读取10个AO寄存器的请求的应答(29个字节)。蓝色为头部,红色为pdu数据负荷。AI和AO的正常长度应等于 6+3+寄存器个数*2。即寄存器个数=(总长度-9)/2
03 6D 00 00 00 17 01 03 14 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
03 6D检验信息,事务号,必须和请求相同
00 00 tcp/ip为modbus协议
00 17 表示该字节后的长度
01 设备地址
03 功能码
14 该字节后的字节数(20),10个寄存器共20个字节
- 向线圈地址DO:46写1。注意:控制时请求和应答内容可能相同。
请求:00 03 00 00 00 06 01 05 00 2D FF 00
应答:00 03 00 00 00 06 01 05 00 2D FF 00
- 向AO地址AO:3004写值42。
请求:1F 39 00 00 00 09 01 10 0B BC 00 01 02 00 2A
解析:1F 39(0x1F39事务号) 00 00(0x0000表示是modbus协议) 00 09(后面字节个数9个) 01(站号) 10(命令号,16,表示写入多个寄存器指令) 0B BC(起始地址,0x0BBC=3004) 00 01(寄存器个数,1个) 02(数据长度2个字节) 00 2A(控制值0x2A=42)
应答:1F 39 00 00 00 06 01 10 0B BC 00 01
解析:1F 39(0X1F39事务号) 00 00(0x0000表示是modbus协议) 00 06(后面字节个数9个) 01(站号) 10(命令号,16,表示写入多个寄存器指令) 0B BC(起始地址,0x0BBC=3004) 00 01(寄存器个数,1个)
抓包wireshark的控制命令的截图如下:
六、 ModBusRTU协议分析
ModBusRTU有校验码,请求的数据长度是8个字节。