本文承接上篇,讲解多设备总线管理、Modbus TCP以太网通讯、故障冗余方案,以及实际项目中常见踩坑点。适合想系统掌握三菱PLC Modbus通讯的开发者。
一、温故知新:上篇核心要点
上篇讲解了Modbus RTU基础和单设备通讯,以下内容需要读者已经掌握:
- RS485硬件接线(A+/B-极性)
- GX Works3串口Modbus RTU模式配置
- ADPRW指令读写寄存器
- 通讯错误代码含义
本篇在上篇基础上,攻克两个更高阶的课题:
- 一台PLC同时管理多台Modbus从站设备
- 从RS485升级到Modbus TCP以太网通讯
二、多从站管理:RS485总线实战
2.1 为什么需要多从站
工厂里往往有多台变频器同时运行:
- 一条传送带有3段独立调速 → 3台变频器
- 中央空调系统有冷却泵、冷却塔风机、冷冻泵 → 至少3台
- 污水处理需要多台搅拌器、曝气设备
用一台PLC的RS485总线,可以最多挂247个从站。
2.2 总线拓扑与接线规范
code复制
┌─────────┐ ┌─────────────│ FX5U │─────────────┐ │ │ RS485 │ │ │ └─────────┘ │ │ │ ───┼─── A+ ──── A+ ──── A+ ──── A+ ──┼─── │ │ ───┼─── B- ──── B- ──── B- ──── B- ──┼─── │ │ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │ └────│VFD│───│VFD│───│VFD│───│VFD│───┘ │ #1│ │ #2│ │ #3│ │ #4│ └───┘ └───┘ └───┘ └───┘关键接线规范:
| 规范 | 说明 |
|---|---|
| 总线式连接 | 所有设备并联在总线A+/B-上 |
| 终端电阻 | 总线两端加120Ω终端电阻 |
| 支线长度 | 支线长度<1米,越短越好 |
| 屏蔽接地 | 单端接地(主站端),切勿两端接地 |
| 线材选型 | 推荐0.75mm²双绞屏蔽线 |
2.3 多从站地址分配
每台变频器必须设置唯一的通讯地址:
| 设备 | 从站地址 | 说明 |
|---|---|---|
| 变频器#1 | 1 | 主传送电机 |
| 变频器#2 | 2 | 副传送电机 |
| 变频器#3 | 3 | 搅拌电机 |
| 温控仪#1 | 10 | 加热区温控 |
| 温控仪#2 | 11 | 冷却区温控 |
2.4 多从站轮询程序
PLC按顺序逐个与各从站通讯,这就是轮询(Polling)机制:
pascal复制
// ============== 多从站轮询程序(结构化文本 ST)============== PROGRAM Modbus_Polling VAR iStep : INT := 0; // 当前轮询步骤 tScan : TON; // 扫描定时器 rFreq1 : INT; // 变频器1频率 rFreq2 : INT; // 变频器2频率 rFreq3 : INT; // 变频器3频率 rTemp1 : INT; // 温控仪1温度 bSendOk : BOOL; // 发送完成标志 END_VAR // 轮询步骤分配(每500ms切换一个从站) tScan(IN:=TRUE, PT:=T#500MS); IF tScan.Q THEN tScan(IN:=FALSE); iStep := (iStep + 1) MOD 5; // 5个设备循环 CASE iStep OF 0: // ========== 读取变频器#1频率 ========== ADPRW(K1, 1, H0003, H2100, 1, D100, M100); 1: // ========== 读取变频器#2频率 ========== ADPRW(K1, 2, H0003, H2100, 1, D110, M110); 2: // ========== 读取变频器#3频率 ========== ADPRW(K1, 3, H0003, H2100, 1, D120, M120); 3: // ========== 读取温控仪#1温度 ========== ADPRW(K1, 10, H0003, H1000, 1, D200, M130); 4: // ========== 写入变频器#1频率设定 ========== ADPRW(K1, 1, H0006, H1001, 1, D10, M140); END_CASE; END_IF; // 处理返回值(按步骤对应存储) IF M100 THEN rFreq1 := D100; END_IF; // 变频器1完成 IF M110 THEN rFreq2 := D110; END_IF; // 变频器2完成 IF M130 THEN rTemp1 := D200; END_IF; // 温控仪1完成2.5 轮询时序图
code复制
时间轴 ─────────────────────────────────────────────────────► [ 0ms ] ── 发送 ──► [从站1响应] ── 500ms ──► [从站2响应] [500ms] ── 发送 ──► [从站2响应] ── 500ms ──► [从站3响应] [1000ms] ── 发送 ──► [从站3响应] ── 500ms ──► [从站4响应] [1500ms] ── 发送 ──► [温控仪1] ── 500ms ──► [返回步骤0] 扫描周期 = 设备数量 × 单次通讯时间 ≈ 5 × 500ms = 2.5s三、Modbus TCP:以太网通讯配置
3.1 为什么升级到Modbus TCP
当设备分散在不同位置,或者数据量较大时,RS485的局限性显现:
| 对比项 | Modbus RTU | Modbus TCP |
|---|---|---|
| 通讯速率 | 最高115200bps | 100Mbps(提升800倍) |
| 设备数量 | 247台 | 无限制(受IP网络限制) |
| 通讯距离 | <1200米 | 全球(依赖网络) |
| 布线成本 | 专用通讯线 | 复用工厂局域网 |
| 实时性 | 较低 | 高 |
适合升级Modbus TCP的场景:
- 设备分散在不同车间
- 需要与SCADA系统对接
- 数据量大(多寄存器批量读取)
- 需要远程监控和调试
3.2 FX5U以太网配置
GX Works3 → 参数 → FX5UCPU → 模块参数 → 以太网端口
设置IP地址:
| 参数 | 设定值 | 说明 |
|---|---|---|
| IP地址 | 192.168.1.100 | PLC的IP地址 |
| 子网掩码 | 255.255.255.0 | 局域网网段 |
| 默认网关 | 192.168.1.1 | 路由器地址 |
启用Modbus TCP服务器:
| 参数 | 设定值 |
|---|---|
| 协议选择 | Modbus TCP |
| 连接模式 | Active(主动模式) |
| 连接对象数 | 4 |
3.3 Modbus TCP通讯帧结构
Modbus TCP在以太网TCP/IP协议栈上运行,帧结构如下:
code复制
TCP头部(6B) + Modbus应用数据单元(MBAP) ┌──────────┬──────────────┬────────────┬──────────────┐ │ 事务ID │ 协议ID=0 │ 长度(2B) │ 单元ID(从站) │ │ (2B) │ (2B) │ │ (1B) │ └──────────┴──────────────┴────────────┴──────────────┘读取1号变频器H2100的频率值(以太网):
code复制
发送帧: 00 01 00 00 00 06 01 03 21 00 00 01 └──TCP头──┘ 单元 功能码 地址 数量 接收帧: 00 01 00 00 00 05 01 03 02 12 34 └──TCP头──┘ 单元 功能码 数据3.4 GX Works3 Modbus TCP指令
三菱FX5U使用SP.SOCOPEN / SP.SOCRECV / SP.SOCSEND进行TCP通讯:
pascal复制
// ============== Modbus TCP通讯程序 ============== PROGRAM ModbusTCP_Client VAR socket : INT := -1; // Socket编号 txBuf : ARRAY[0..15] OF BYTE; // 发送缓冲区 rxBuf : ARRAY[0..15] OF BYTE; // 接收缓冲区 iLen : INT; bConn : BOOL := FALSE; END_VAR // Step 1: 建立TCP连接(目标:192.168.1.10,端口502) IF NOT bConn THEN socket := SP.SOCOPEN(1, "192.168.1.10", 502); IF socket >= 0 THEN bConn := TRUE; END_IF; END_IF; // Step 2: 构建Modbus TCP读取请求(读取H2100,1字) IF bConn THEN txBuf[0] := 16#00; txBuf[1] := 16#01; // 事务ID txBuf[2] := 16#00; txBuf[3] := 16#00; // 协议ID txBuf[4] := 16#00; txBuf[5] := 16#06; // 长度=6 txBuf[6] := 16#01; // 从站地址=1 txBuf[7] := 16#03; // 功能码=读 txBuf[8] := 16#21; txBuf[9] := 16#00; // H2100 txBuf[10]:= 16#00; txBuf[11]:= 16#01; // 数量=1 iLen := 12; // 发送请求 SP.SOCSEND(socket, txBuf, iLen); // 接收响应 SP.SOCRECV(socket, rxBuf, iLen); // 解析数据(rxBuf[9]*256 + rxBuf[10] = 频率值) D100 := TO_INT(rxBuf[9]) * 256 + TO_INT(rxBuf[10]); END_IF;四、实战案例:PLC + 多变频器 + HMI监控系统
4.1 系统架构
code复制
┌─────────────┐ Ethernet ┌─────────────┐ │ GX Works3 │───────────────────│ FX5U CPU │ │ (编程) │ Modbus TCP │ │ └─────────────┘ └──────┬──────┘ │ RS485 总线 │ ┌──────────────────────────────┼────────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │变频器#1 │ │变频器#2 │ │变频器#3 │ │ 地址=1 │ │ 地址=2 │ │ 地址=3 │ │ 7.5kW │ │ 5.5kW │ │ 3.7kW │ └─────────┘ └─────────┘ └─────────┘4.2 HMI触摸屏配置(以威纶通MT8103iE为例)
HMI作为Modbus TCP客户端,连接PLC:
| HMI设置项 | 设定值 |
|---|---|
| PLC类型 | Modbus TCP/IP |
| IP地址 | 192.168.1.100 |
| 端口 | 502 |
| 通讯超时 | 3000ms |
读取PLC数据地址映射:
| HMI地址 | 对应PLC | 说明 |
|---|---|---|
| 4x0001 | D1 | 变频器1频率设定 |
| 4x0002 | D2 | 变频器2频率设定 |
| 4x0003 | D3 | 变频器3频率设定 |
| 4x0101 | D101 | 变频器1当前频率 |
| 4x0102 | D102 | 变频器2当前频率 |
4.3 完整程序:多变频器协同控制
pascal复制
// ============== 多变频器协同控制程序(ST)============== PROGRAM MultiVFD_Control VAR // 频率设定值(由HMI写入) wFreqSet1 : INT := 3000; // 变频器1:30.00Hz wFreqSet2 : INT := 2500; // 变频器2:25.00Hz wFreqSet3 : INT := 2000; // 变频器3:20.00Hz // 实际反馈值 wFreqAct1 : INT; wFreqAct2 : INT; wFreqAct3 : INT; // 运行状态 atRun1, atRun2, atRun3 : BOOL; // 轮询步骤 iStep : INT := 0; tPoll : TON; END_VAR // ========== 轮询调度(每300ms处理一个从站)========== tPoll(IN:=TRUE, PT:=T#300MS); IF tPoll.Q THEN tPoll(IN:=FALSE); iStep := (iStep + 1) MOD 8; // 8个操作循环 CASE iStep OF 0: ADPRW(K1, 1, H0006, H1001, 1, wFreqSet1, M1); // 写变频器1频率 1: ADPRW(K1, 2, H0006, H1001, 1, wFreqSet2, M2); // 写变频器2频率 2: ADPRW(K1, 3, H0006, H1001, 1, wFreqSet3, M3); // 写变频器3频率 3: ADPRW(K1, 1, H0003, H2100, 1, wFreqAct1, M4); // 读变频器1频率 4: ADPRW(K1, 2, H0003, H2100, 1, wFreqAct2, M5); // 读变频器2频率 5: ADPRW(K1, 3, H0003, H2100, 1, wFreqAct3, M6); // 读变频器3频率 6: ADPRW(K1, 1, H0003, H2102, 1, D10, M7); // 读变频器1电流 7: ADPRW(K1, 2, H0003, H2102, 1, D11, M8); // 读变频器2电流 END_CASE; END_IF; // ========== 频率自动同步(补偿机械惯性)========== // 当设定值与实际值偏差>5Hz时,分步调整防止冲击 IF ABS(wFreqSet1 - wFreqAct1) > 500 THEN wFreqAct1 := wFreqAct1 + SIGN(wFreqSet1 - wFreqAct1) * 100; ADPRW(K1, 1, H0006, H1001, 1, wFreqAct1, M1); END_IF;五、常见踩坑与解决方案
坑1:波特率不一致,通讯全挂
症状:PLC能发,变频器不回,所有设备都无响应。
排查:
powershell复制
# 用串口调试助手直连变频器测试 # 如果PC直连变频器能通讯,说明是PLC侧问题 # 检查项: # 1. PLC侧波特率是否一致(变频器常见9600/19200,PLC默认可能不同) # 2. 变频器P14.01参数是否匹配 # 3. 数据位/校验/停止位是否完全一致坑2:RS485总线终端电阻没加
症状:距离超过50米后,数据开始随机丢包。
解决:在总线两端(PLC端和最后一台设备端)各加一个120Ω终端电阻。
code复制
PLC端 ────[120Ω]─── 总线主线 ────[120Ω]─── 最后一台设备坑3:从站地址重复
症状:读取地址2的设备,返回的却是地址1的数据。
解决:逐台检查变频器P14.00(或对应通讯地址参数),确保不重复。
坑4:Modbus TCP端口被防火墙拦截
症状:本地测试正常,远程连不上。
解决:
- 防火墙开放502端口(Modbus TCP标准端口)
- 确认PLC以太网模块固件版本支持Modbus TCP
- 检查路由器/交换机的VLAN设置
坑5:寄存器地址写错
症状:PLC写入后,变频器没反应,或者行为异常。
注意:不同品牌的Modbus寄存器地址映射不同:
- 汇川MD580:频率设定=H1001,运行频率=H2100
- 三菱E800:频率设定=H0001,运行频率=H0002
- 台达VFD-B:频率设定=H2001,运行频率=H2101
一定要查对应设备的Modbus寄存器映射表!
六、总结与进阶方向
本系列核心收获
| 技能点 | 掌握情况 |
|---|---|
| Modbus RTU/TCP协议原理 | ✅ |
| FX5U RS485/以太网配置 | ✅ |
| ADPRW指令读写寄存器 | ✅ |
| 多从站轮询程序 | ✅ |
| 常见故障排查方法 | ✅ |
| PLC+HMI数据联动 | ✅ |
进阶学习方向
- SCADA系统对接:用Modbus TCP接入组态王/WinCC
- 数据采集与边缘计算:PLC + Python/MQTT + 云端
- 工业机器人通讯:Modbus TCP控制ABB/安川机器人
- EtherCAT/PROFINET:高速运动控制总线
感谢阅读。
上篇:《三菱PLC与Modbus通讯实战(上):环境配置与基础通讯》
如果觉得有帮助,欢迎收藏、点赞。有工控项目经验想交流的,欢迎在评论区留言。