1. 三菱FX5U的Modbus TCP双角色实战
三菱FX5U系列PLC自带的以太网口原生支持Modbus TCP协议栈,这个功能在实际项目中简直不要太方便。相比那些需要额外购买通讯模块的方案,FX5U直接用本体网口就能玩转Modbus TCP,而且性能相当稳定。今天我要分享的是一个进阶玩法——让同一台PLC同时作为Modbus TCP服务器和客户端。这种架构在需要数据中转或设备级联的场景特别实用,比如生产线中段设备既要接收前段PLC的数据,又要转发给后端系统。
1.1 硬件准备与环境搭建
首先确认你的FX5U硬件版本支持以太网功能(所有FX5U-CPU型号都内置以太网口)。我用的是一台FX5U-32MT/ES,固件版本1.240。硬件连接非常简单:
- 用普通网线将PLC的以太网口接入局域网
- 确保PLC与调试电脑在同一网段(比如PLC设192.168.1.88,电脑设192.168.1.100)
- 准备一根USB编程线用于初始参数设置
注意:首次使用时建议先用USB连接配置基本参数,避免因IP设置错误导致无法连接
在GX Works3中新建工程时,务必选择正确的系列和型号。软件版本建议使用1.050L以上,老版本可能缺少部分功能支持。新建工程后先进行基本参数设置:
- 导航到"参数"→"FX5UCPU"→"模块参数"→"以太网端口"
- 设置IP地址、子网掩码和默认网关
- 工作模式选择"TCP/IP"
1.2 协议栈功能启用
FX5U的Modbus TCP协议栈是内置功能,不需要额外编程实现。启用方法如下:
- 在以太网端口参数页面,切换到"协议设置"标签
- 勾选"使用协议"
- 协议类型选择"TCP"
- 勾选"Modbus服务器功能"
- 端口号保持默认502(除非有冲突)
关键参数说明:
- 最大连接数:FX5U最多支持16个TCP连接
- 超时时间:建议设为3000ms(3秒)
- 站号:Modbus从站地址,默认255

2. 服务器端配置详解
2.1 数据区映射配置
FX5U的Modbus功能码与内部软元件对应关系如下表:
| Modbus功能码 | 对应PLC软元件 | 地址范围 |
|---|---|---|
| 01(读线圈) | M0~M1999 | 0-1999 |
| 02(读离散输入) | M8000~M8999 | 8000-8999 |
| 03(读保持寄存器) | D0~D1999 | 0-1999 |
| 04(读输入寄存器) | D8000~D8999 | 8000-8999 |
| 05(写单个线圈) | M0~M1999 | 0-1999 |
| 06(写单个寄存器) | D0~D1999 | 0-1999 |
| 15(写多个线圈) | M0~M1999 | 0-1999 |
| 16(写多个寄存器) | D0~D1999 | 0-1999 |
重要提示:地址映射时要注意十进制与十六进制的转换。例如当上位机请求读取D100时:
- PLC内部处理的是十进制100
- 但有些上位机工具可能发送十六进制0x64
- 如果通信异常,建议在调试工具中切换地址格式试试
2.2 服务器模式参数优化
在"协议详细设置"中,有几个关键参数需要特别关注:
- 保持连接:建议勾选,减少TCP重复连接的开销
- 允许同时通信:必须勾选才能实现双角色功能
- 通信超时:设为3000ms比较合理
- 最大重试次数:3次足够
对于需要高频通信的场景,可以在SD区设置以下特殊寄存器:
- SD21800:通信状态码(0x0000表示正常)
- SD21801:通信控制字(0x0002启用字节交换)
- SD21802:当前连接数
3. 客户端程序开发
3.1 ADPRW指令深度解析
FX5U使用专用的ADPRW指令实现Modbus TCP客户端功能。典型代码如下:
st复制// 读取服务器数据的示例
MOV K1 D100 // 从站站号(1~247)
MOV H0000 D101 // 起始地址(十六进制)
MOV K10 D102 // 读取数量(10个字)
ADPRW K1 K0 D100 K4 D200
指令参数详解:
- K1:通信通道号(固定为1)
- K0:状态存储地址(对应SD21800)
- D100:参数起始地址(站号+起始地址+数量)
- K4:模式选择(4=Modbus TCP)
- D200:数据接收缓冲区
调试技巧:实时监控SD21800的值,0x0000表示通信正常。如果出现0x1234等错误码,查阅手册附录的"通信异常代码表"。
3.2 超时处理与重试机制
工业现场网络环境复杂,必须实现可靠的超时处理:
st复制// 带超时重试的读取逻辑
LD M0 // 触发信号
ADPRW K1 K0 D100 K4 D200
OUT T0 K3000 // 3秒超时定时器
LDP T0 // 超时触发
INC D500 // 错误计数器
MOV K0 SD21800 // 复位通信状态
最佳实践建议:
- 每次通信前复位状态寄存器(MOV K0 SD21800)
- 超时时间设为通信周期的3倍以上
- 连续错误超过5次应触发报警
- 重试间隔加入随机延时(避免网络拥塞)
3.3 字节顺序问题解决方案
不同设备对多字节数据的存储顺序可能不同:
-
PLC默认模式:高位字节在前(Big-endian)
- 例如D100中存储0x1234,发送顺序是0x12 0x34
-
常见上位机模式:低位字节在前(Little-endian)
- 同样数据会解释为0x34 0x12
解决方法有两种:
st复制// 方法1:程序内转换
ADPRW K1 K0 D100 K4 D200
BSWAP D200 D300 // 字节交换
// 方法2:修改PLC参数
MOV H2 SD21801 // 设置通信控制字
4. 双角色模式实现技巧
4.1 端口配置要点
让PLC同时作为服务器和客户端,关键是要处理好端口分配:
- 服务器端口:固定502(标准Modbus TCP端口)
- 客户端端口:建议使用5020~5029范围
- 在以太网参数中勾选"允许同时通信"
- 最大连接数设为至少2
配置示例:
ini复制[以太网端口]
IP地址 = 192.168.1.88
子网掩码 = 255.255.255.0
协议 = TCP
服务器端口 = 502
客户端端口 = 5020
最大连接数 = 16
4.2 资源分配策略
为避免资源冲突,建议采用以下策略:
- 服务器功能使用M8000~M8999和D8000~D8999区
- 客户端功能使用M0~M7999和D0~D7999区
- 为每个连接分配独立的缓冲区(D区)
- 关键操作使用互锁逻辑
示例资源分配表:
| 功能 | 软元件范围 | 用途说明 |
|---|---|---|
| 服务器输入 | D8000~D8499 | 接收上位机数据 |
| 服务器输出 | D8500~D8999 | 返回给上位机的数据 |
| 客户端发送 | D1000~D1999 | 要发送到其他设备的数据 |
| 客户端接收 | D2000~D2999 | 从其他设备读取的数据 |
4.3 调试工具使用心得
推荐使用Modbus Poll进行调试,关键配置如下:
-
连接设置:
- Connection → TCP/IP
- IP地址填PLC的IP
- 端口号:502(服务器模式)/5020(客户端模式)
- Timeout设为3000ms
-
从站设置:
- Slave ID填255(FX5U默认站号)
- Address format选"PLC address"
-
数据显示:
- 右键点击数据区 → Display → 选择Signed/Unsigned
- 对于浮点数要正确设置字节顺序
常见问题排查:
- 连接失败:检查防火墙设置,确认端口开放
- 数据异常:切换地址格式(PLC地址/Modbus地址)
- 通信中断:检查网线质量,避免与变频器等干扰源共线
5. 高级应用与性能优化
5.1 多线程通信处理
FX5U支持最多16个TCP连接,合理利用可以实现:
- 并行数据采集:同时连接多台设备
- 主备通道切换:双链路冗余设计
- 数据分级传输:重要数据走独立连接
实现示例:
st复制// 通道1读取温度
MOV K1 D100
MOV H1000 D101
MOV K5 D102
ADPRW K1 K0 D100 K4 D200
// 通道2读取压力
MOV K2 D110
MOV H2000 D111
MOV K5 D112
ADPRW K1 K1 D110 K4 D300
5.2 通信性能测试数据
在不同数据量下的实测性能:
| 数据量(字) | 平均响应时间(ms) | 吞吐量(字/秒) |
|---|---|---|
| 10 | 12 | 833 |
| 50 | 18 | 2777 |
| 100 | 25 | 4000 |
| 200 | 42 | 4761 |
优化建议:
- 单次读取不超过100字
- 高频数据分组轮询
- 非关键数据降低采样率
5.3 异常处理大全
整理实际项目中遇到的典型问题及解决方案:
-
错误代码0x1234:从站无响应
- 检查目标设备IP和端口
- 确认目标设备Modbus功能已启用
-
错误代码0x1302:数据长度异常
- 检查ADPRW指令的读取数量参数
- 确认缓冲区足够大
-
数据错位:地址偏移问题
- 在调试工具中切换地址格式
- 确认功能码与寄存器类型匹配
-
通信时断时续:网络干扰
- 使用屏蔽双绞线
- 避免与动力线平行走线
-
PLC响应缓慢:连接数过多
- 监控SD21802查看当前连接数
- 优化程序减少并发请求
6. 项目实战:数据网关实现
最后分享一个真实案例——用FX5U实现生产线数据网关:
系统架构:
- 作为客户端:每500ms读取前段设备的产量数据(D100~D105)
- 作为服务器:接收MES系统的查询请求(D8000~D8005)
- 数据转换:将原始数据转换为标准JSON格式
- 异常缓冲:网络中断时本地存储最近100条记录
关键程序片段:
st复制// 数据读取周期任务
LD SM400 // 常ON信号
OUT T0 K500 // 500ms定时器
LDP T0
MOV K1 D100 // 前段设备站号
MOV H100 D101 // 起始地址
MOV K6 D102 // 读取6个字
ADPRW K1 K0 D100 K4 D200
// 数据转换存储
MOV D200 D8000 // 产量1
MOV D201 D8001 // 产量2
BSWAP D202 D8002 // 质量数据(需要字节交换)
// 异常处理
LD= SD21800 K0
MOVP K0 D500 // 复位错误计数器
LDP<> SD21800 K0
INC D500
LD>= D500 K5
SET M100 // 触发报警
实施效果:
- 通信成功率从92%提升到99.8%
- 系统响应时间小于50ms
- 实现了设备层与企业层的无缝对接
这个方案已经在三个工厂稳定运行超过一年,期间只出现过一次因交换机故障导致的通信中断,充分证明了FX5U Modbus TCP双角色方案的可靠性。对于需要实现设备联网又不想增加专用网关的项目,这确实是个经济高效的解决方案。