ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

FX5U ModbusTCP调试指南:主从站角色与参数配置详解

FX5U ModbusTCP调试指南:主从站角色与参数配置详解 说实话我第一次用FX5U调ModbusTCP的时候差点被软件名字带沟里去。当时在现场连了一台变频器PLC程序写好了通信指令也发了结果对端设备怎么都不响应。后来才知道我把“Modbus Slave”当成了主站工具在用——这名字确实容易让人误会Slave翻译过来是从站可很多第一次接触的人下意识觉得“我拿这软件去连接别人”它应该是主站。其实恰恰相反。后来用FX5U搭配Modbus Slave软件反复试过好几轮把主从站两种角色都跑通了也踩了不少坑。这篇文章就把我实际调试中觉得最值得注意的细节整理出来从角色关系、参数配置、软件设置到故障排查尽量让看完的人能直接对着操作。1. 搭建调试环境前先把ModbusTCP的角色关系理清楚调试ModbusTCP最容易犯的错误不是参数填错而是压根没分清谁是主站、谁是从站。这个关系一旦搞反后面所有操作都是白费。1.1 主站和从站千万别被软件名字带偏ModbusTCP是典型的“一主多从”请求响应模型。主站主动发请求从站收到后回复响应从站之间不能互相通信从站也不会主动往外发数据。以FX5U和Modbus Slave软件的组合来说最常用的调试模式是FX5U作为主站Modbus Slave软件在电脑上模拟一个ModbusTCP从站。PLC主动去读这个虚拟从站的寄存器或者向它写入数据用来验证自己的通信程序和网络链路是否正常。Modbus Slave软件的全名就叫“Modbus Slave”它模拟的是从站设备。你如果真想拿它当主站去连PLC那是做不到的。想验证FX5U作为从站的场景得用Modbus Poll这类主站模拟软件或者自己写一段Socket客户端程序这个后面会单独讲。1.2 为什么调试阶段推荐用软件模拟从站现场调试如果一上来就接真实的从站设备比如变频器、仪表、温控器会面临几个问题设备地址和寄存器表不一定有现成文档参数可能已经被别人改过甚至设备本身有故障这种情况下根本分不清是通信链路的问题还是设备侧的问题。用软件模拟从站好处是可控性极强。Modbus Slave里可以随意设置单元ID、功能码、寄存器起始地址和长度还能手动填充任意数据值。这样PLC侧发起读请求后返回的数据就是你预先填好的测试值一眼就能判断PLC程序里的数据落点对不对。写操作也一样PLC写进去的值在软件里能立刻看到变化两端对照起来非常直观。1.3 本次调试需要用到的软硬件清单先列一份我常用的调试环境方便你对照准备。项目推荐配置备注PLC三菱FX5U系列如FX5U-32MT/ES具备内置以太网口编程软件GX Works3需确认固件版本支持相关功能从站模拟软件Modbus Slave即Modbus Slave演示模式也能用高级功能需授权主站模拟软件Modbus Poll反向验证时使用电脑Windows系统有线网口无线网卡容易有延迟和干扰网线超五类及以上屏蔽网线调试建议直连不经过交换机辅助工具Wireshark或网络调试助手抓包分析定位故障的最强手段这里有个经验调试阶段能直连就直连不要贪图方便去插办公室交换机。交换机上如果开了VLAN或者端口隔离很容易出现“电脑能PING通PLC但ModbusTCP报文就是过不去”的诡异现象。先直连排除中间设备干扰等通信稳定了再往现场网络里接。2. FX5U做ModbusTCP主站GX Works3里这几个参数必须核对很多人在电脑上把Modbus Slave软件装好参数也设了却发现PLC根本发不出报文。问题多半出在GX Works3侧不是软件没装对而是PLC的以太网参数和通信指令没配对。2.1 内置以太网口的IP地址设置位置GX Works3里打开工程后导航窗口找到“参数”→“FX5U CPU”→“内置以太网端口设置”。这里要填的IP地址是PLC作为ModbusTCP设备在网络中的身份。调试时我习惯把PLC设置成192.168.3.250电脑设置成192.168.3.10子网掩码统一255.255.255.0。这样设置的目的就是避免跟现场其他设备冲突同时方便记忆。有个坑容易踩FX5U有的型号除了内置以太网口还可以扩展以太网模块。如果你工程里同时挂了以太网模块参数设置界面会多出对应的选项卡。别把IP填错地方填到扩展模块上去了。判断方法很简单看看你实际插网线的那个口是CPU本体上的还是扩展模块上的对应着填就行。2.2 ModbusTCP功能的启用和连接属性IP设好还不够。FX5U的内置以太网口默认情况下是可以进行MELSOFT连接的也就是GX Works3上下载程序、监控那种连接。但要让PLC作为ModbusTCP主站主动向外部发送报文你必须在程序里用Socket通信指令或者用专门的ModbusTCP功能块。我在调试中用得最多的方案是Socket通信指令指令包括SP.SOCOPEN打开连接、SP.SOCSND发送数据、SP.SOCRCV接收数据、SP.SOCCLOSE关闭连接。FX5U作为客户端去连接Modbus Slave软件时本质就是建立一个TCP客户端连接目标IP是电脑的IP目标端口是502。如果你不想手拼ModbusTCP报文GX Works3里也提供了ModbusTCP通信功能块比如MB_READ、MB_WRITE之类。不同固件版本里功能块的名称可能略有差异但参数逻辑一致。第一次用功能块的记得先看功能块的引脚定义特别是“Unit ID”和“Address”这两个引脚特别容易填错。2.3 通信指令里的报文结构手拼Socket帧时别漏字节如果选择用SP.SOCSND手写报文必须清楚ModbusTCP的报文格式。一个完整的读保持寄存器请求帧长这样00 00 00 00 00 06 01 03 00 00 00 0A这12个字节的含义依次是事务处理标识符2字节、协议标识符2字节Modbus固定为0000、后续字节长度2字节表示从单元ID开始到帧尾的字节数、单元ID1字节、功能码1字节、起始地址2字节、寄存器数量2字节。这里最容易漏掉的是“后续字节长度”这个字段。很多人第一次手拼报文直接从01 03开始写忘了前面还有一个00 06。PLC发送的数据长度就会短6个字节从站收到后要么不响应要么直接返回异常帧。我后来养成了一个习惯所有Socket发送报文先做成十六进制数组然后用指令自带的长度计算功能核对一次确保每个字节都在。3. Modbus Slave软件配置从站参数要和PLC侧严丝合缝PLC这边准备好了电脑上的Modbus Slave软件也要配对好。很多调试问题出在两边参数“各说各话”比如PLC报文里请求的起始地址是0Modbus Slave里起始地址却设成了1你怎么发它都不响应但实际上只是差了一个地址。3.1 新建从站时协议、端口和单元ID怎么选打开Modbus Slave在“Connection”里选择“Modbus TCP/IP”默认端口502不用改。然后点“Setup”创建一个从站或者直接双击Slave Definition设置单元ID和功能码。单元ID必须和PLC报文里的单元ID一致。我通常两边都填1。如果填错了典型现象是PLC连接能建立成功但从站收到请求后不返回任何数据或者直接返回Exception Response。这里说的Exception Response是指从站返回的异常响应帧后面排查章节会展开讲。功能码的选择取决于你要测读操作还是写操作。调试读功能就选03读取保持寄存器调试写功能就选16写多个保持寄存器或06写单个保持寄存器。如果PLC程序里同时有读有写可以在Modbus Slave的一个从站里同时勾选多个功能码但要注意每个功能码对应的寄存器范围。3.2 寄存器起始地址和长度的设置逻辑Modbus Slave设置从站地址时界面上填的是“0”到“65535”之类的数字这个0对应PLC报文里的起始地址0。但在很多PLC程序块里地址显示为40001、40002这种。这里其实是一个约定俗成的映射关系Modbus协议报文里的地址0对应数据模型里的40001地址编号。也就是说PLC功能块里要读40001发送报文里的起始地址应该是0要读40002报文起始地址是1。如果PLC侧填了40001那就意味着起始地址是40001明显超出了Modbus报文的16位地址范围从站自然不认。这个换算关系新手至少踩三次。我在Modbus Slave里测地址偏移时的做法是先把从站起始地址设为0寄存器长度设为100然后把0号寄存器的值写成一个特殊数字比如12345。PLC侧从0地址读10个寄存器如果读回来的第一个数字是12345说明地址映射完全正确如果第一个读到的是别的寄存器马上就能看出偏移差了多少。3.3 演示模式够不够用高级功能要不要付费Modbus Slave软件没激活的时候是演示模式可以正常建立从站、模拟寄存器读写但使用时间有限制而且高级功能比如多从站并发、报文记录导出这些需要授权码解锁。对于单纯验证FX5U和ModbusTCP通信链路演示模式完全够用不用一上来就找授权。软件下载和授权激活这些事我只是提个醒去官网下载别在来路不明的网站下容易被捆绑乱七八糟的东西。我见过好几个同事电脑上装了带后门的“破解版”调试软件轻则系统卡顿重则工程文件被加密勒索。调试工具这种东西安全第一。4. 从PING不通到读写正常完整验证过程记录这个章节我给你完整走一遍从零开始的验证流程。假设你刚拿到一台FX5U电脑上装好了Modbus Slave网线已经直连接下来可以按我的顺序操作。4.1 第一步先PING通再谈ModbusTCP打开Windows的命令提示符输入ping 192.168.3.250 -t这里192.168.3.250是我的PLC地址你改成自己的。能PING通说明物理链路和IP地址没问题PING不通后面什么都别谈。如果PING不通按顺序检查电脑网卡的IP地址和子网掩码是否正确网线是否插紧直连线两头有没有松动电脑防火墙是否拦截了ICMP协议FX5U的以太网参数下载到PLC后有没有复位重启需要特别注意的是GX Works3修改了IP参数并写入PLC后CPU必须重新上电或者复位新IP地址才会生效。我遇到过好几次这种情况参数下载显示成功结果PING不通最后发现是PLC还用的旧IP。所以下载完参数重启一下PLC能省很多时间。4.2 第二步Modbus Slave里建立从站并打开报文监视PING通之后在Modbus Slave软件中新建一个TCP从站Unit ID填1功能码勾选03和16。然后在Display菜单里找到“Communication Traffic”选项并打开这个窗口会实时显示PLC发过来的请求帧和软件返回的响应帧非常有用。这时候去PLC里触发一次通信请求。如果一切正常你会看到Communication Traffic窗口里出现了类似这样的内容Tx: 00 00 00 00 00 06 01 03 00 00 00 0A Rx: 00 00 00 00 00 0F 01 03 14 00 01 ... ...Tx是PLC发来的请求Rx是Modbus Slave软件返回的响应。能看到这两个帧说明通信链路已经通了接下来要关心的是数据对不对。如果Tx一直不出现说明PLC的程序根本没有发请求问题在PLC侧。如果Tx出现了但Rx是异常帧比如看到83 02或者83 03问题多半在地址和寄存器范围上参见后面第五部分。4.3 第三步数据验证环节两边对照填数通信通了只是第一步数据对得上才算真正打通。我先在Modbus Slave里把0号寄存器的值改成123451号寄存器改成54321。然后在FX5U程序里用监控表看对应的D寄存器如果PLC读回来的正是这两个数说明读功能验证完成。写功能验证反过来操作在PLC里给D100写入一个测试值比如999然后看Modbus Slave里对应地址的寄存器值变成了999说明写功能也正常。这一步看着简单却是最容易被忽略的一环。很多人通信通了就撒手不管结果到现场才发现读回来的数据全是错位的或者高位低位反了。花两分钟做一次双向数据验证后面能省大半天的排查时间。5. 高频故障排查这几个问题占据了90%的调试时间我把自己这几次调试里遇到的高频问题做了个归类基本能覆盖大多数ModbusTCP不通或数据异常的情况。每次调不通按着这个顺序过一遍效率很高。5.1 Exception Response异常响应从站到底在拒绝什么ModbusTCP报错时最常见的异常响应是“Modbus Exception Response”。它的典型特征是响应帧中的功能码比请求功能码高0x80比如请求功能码是0x03异常响应功能码就是0x83。从站返回异常码的原因主要有这几类异常码含义常见原因01非法功能码PLC请求的功能码从站不支持02非法数据地址请求的起始地址数量超出从站寄存器范围03非法数据值写入的数据值超出允许范围04从站设备故障从站内部异常或硬件故障排查时优先看地址范围。比如Modbus Slave里设置了100个寄存器地址从0到99而PLC一次请求了从0开始的200个寄存器从站就会返回02异常。把PLC请求的寄存器数量改小或者把Modbus Slave里的寄存器长度改大问题立刻消失。5.2 Socket超时时间设太短通信时通时断另一个高频坑是通信不稳定时好时坏。这个在Socket通信方案里尤其常见。FX5U的SP.SOCOPEN指令里有一个超时参数有些人的习惯是设成100毫秒。这在局域网直连的时候可能没问题但如果电脑某个时刻CPU忙了一下或者Windows防火墙弹了个通知延迟稍微超了一点Socket连接就被强制关掉了。下一次通信又要重新建立连接于是表现为“第一次能通后面就不通了”。我后来把超时时间统一调到1000毫秒并且增加了连接状态的判断如果连接断开先执行SP.SOCCLOSE清理残留连接等待100毫秒后再重新SOCOPEN。这一个改动解决了我至少三个现场问题。不是说100毫秒不行而是调试阶段没必要给自己找麻烦。5.3 大小端和字序问题数据读回来了但不对数据能读回来但数值看起来完全不对这是最后一个高频问题。典型的场景是PLC读回来一个32位浮点数比如应该在35.5附近结果读回来一个天文数字或者0.0001。这通常不是通信问题而是大小端字节序不一致。ModbusTCP里一个16位寄存器的高字节在前、低字节在后这是标准。但PLC内部存储32位数据时高16位字和低16位字的存储顺序不同厂家不一样。FX5U的D寄存器连续两个字表示32位数据时D0存高16位、D1存低16位而很多上位机或从站设备默认低16位在前。这就导致字序反了。验证方法很简单在Modbus Slave里往连续两个寄存器写入0x1234和0x5678然后看PLC读回来的D0和D1分别是什么。如果D0读到0x5678、D1读到0x1234说明字序反了需要在PLC程序里做个高低字交换或者调整上位机解析的顺序。这种问题不抓包很难看出来但做一次双向验证就能定位。5.4 Windows防火墙拦截502端口软件收不到请求这个坑常见但特别隐蔽。表现是PLC侧显示连接已建立发送指令也执行了但Modbus Slave的通信监视窗口里一条Tx都看不到。网络和参数全查遍了没问题最后发现是Windows防火墙把502端口的入站请求拦了。解决方法是在Windows防火墙的高级设置里添加入站规则放行TCP端口502。或者更简单调试阶段把电脑网络配置文件改成“专用网络”然后在防火墙弹窗里允许Modbus Slave程序通过。如果你用的是Modbus Poll做主站同理也要放行不然反过来的通信也会被拦截。6. 反向验证也不能少FX5U作为从站时的自测方法前面讲的都是FX5U做主站、电脑软件模拟从站。但在很多项目里FX5U本身要做从站让上位机或者触摸屏来读它。这种场景怎么验证这就要用到反向思路。6.1 开启FX5U作为ModbusTCP从站的参数开关FX5U内置以太网口本身支持作为ModbusTCP从站。在GX Works3的“内置以太网端口设置”里有一个MODBUS TCP相关的选项把它设为允许。然后需要指定哪些软元件可以被外部主站访问这通常在“Modbus从站设置”或“刷新区域”相关的参数里配置。如果你用的固件版本比较老没找到这个选项也可以通过Socket通信程序自己解析ModbusTCP请求帧来模拟从站但这样工作量会大不少。我的建议是优先用原生功能省心得多。配置完成后把PLC的IP设成192.168.3.250电脑IP设成192.168.3.10确保互相PING通。6.2 用Modbus Poll或其他工具模拟主站去读FX5U既然Modbus Slave是从站软件反向验证就不能用它需要换一个主站模拟器。Modbus Poll就是干这个的设置好TCP/IP连接、远程IP和端口502然后去读PLC里的寄存器。Modbus Poll里填的地址也要注意偏移。比如你要读FX5U映射区域的保持寄存器Poll界面里填0对应PLC地址40001和前面从站验证时是一样的逻辑。有些版本在界面里直接显示地址从0开始但旁边会有数据类型选项选Holding Register4x就行。我实际测试中遇到最尴尬的一次是Modbus Poll能连上PLC但读到的全是0。后来发现是PLC里那个Modbus从站映射区域根本没有配置正确外部主站访问的地址范围没有对应到实际软元件上。这个映射关系在GX Works3的参数界面里能看到一张对应表必须确保外部地址和设备地址对应的是同一个区域。6.3 抓包确认最稳妥的问题定位方式不管是主站还是从站验证遇到通信问题最稳妥的方式还是抓包。用Wireshark打开电脑网卡在过滤器里输入tcp.port 502这样就能把ModbusTCP通信的报文全部过滤出来。你能清楚看到TCP三次握手是否建立、请求帧是什么内容、响应帧是正常还是异常。很多参数上说不清的问题报文一抓就水落石出。我个人经验是抓包这个习惯一定要养成。特别是帮别人远程分析问题的时候你看不到对方的操作界面和参数但如果能拿到一个抓包文件几乎80%的问题都能直接判断出来。有一次朋友发来一个抓包文件我一眼就看出PLC发出的TCP SYN包一直重传问题出在网络中间设备上和Modbus协议一点关系都没有。回到调试本身我现在做ModbusTCP相关项目流程已经固定成一套动作电脑装好Modbus Slave和Modbus PollGX Works3参数按固定套路设置通信前先用PING验证链路再通过Communication Traffic看报文数据验证做一次双向读写遇到问题直接抓包。这套流程跑下来不管是FX5U做主站还是从站半小时内都能把通信链路打通。希望这篇重新整理的调试指南能帮你少走点弯路毕竟现场调试的时间不该浪费在这些明明可以提前规避的坑上。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进