(二十)汇川PLC Modbus通讯功能介绍 GitHub 项目地址https://github.com/lidecong133/YModbus汇川 PLC 这几年在设备厂里很常见。尤其是包装、锂电、非标设备、伺服轴比较多的机器经常能看到 H3U、H5U、AM、AC 这些系列。现场问得最多的是“汇川 PLC 能不能用 Modbus 连”能不能连不能只看品牌要看这台 PLC 当前开放的到底是什么协议。汇川 PLC 可能走 Modbus RTU也可能走 Modbus TCP也可能现场实际用的是编程口、HMI 驱动、CANopen、EtherCAT、厂家自己的通信方式。YModbus 只处理 Modbus所以第一步不是写 C#而是确认 PLC 端有没有真正启用 Modbus。这篇按现场最常见的几种情况把汇川 PLC 和 YModbus 怎么配合讲清楚。先分清PLC型号和通信口汇川 PLC 系列比较多不同型号支持的接口不完全一样。但从实际项目看常见可以先按这几类分系列或场景常见Modbus方向H3U常见支持以太网 Modbus TCP、RS485 Modbus RTUH5U常见支持以太网 Modbus TCP、RS485 Modbus RTU 主从站AM / AC 系列控制器根据具体型号和模块确认很多项目会用以太网或串口做 Modbus老项目或简化项目可能只有串口 RTU或者通过网关转 TCP触摸屏已经能连不代表 YModbus 一定能按同样地址直接连这里最容易踩坑的是最后一条。触摸屏软件里能填D100、M0、X10不代表标准 Modbus 报文里也能直接写D100。很多 HMI 驱动会在背后做“设备类型 地址”的转换。YModbus 是纯 Modbus 库它发送的是功能码和数字地址不认识D100这种 PLC 软元件写法。所以你要先问清楚这台汇川 PLC 是按 Modbus TCP Server 暴露数据还是按 Modbus RTU Slave 暴露数据保持寄存器地址0对应 PLC 里的哪个变量这个问题比“汇川能不能连”更有用。TCP和RTU怎么选如果 PLC 和上位机都在同一个以太网里优先考虑 Modbus TCP。TCP 调试更方便看 IP、端口、网络连通性抓包也容易。常见参数是PLC IP192.168.1.30 端口502 UnitId1但端口和 UnitId 不要死背。现场要以 PLC 程序或通信配置为准。如果设备现场只有 RS485或者 PLC 要和变频器、温控表、称重仪表挂在一条总线上那就走 Modbus RTU。RTU 要确认这些参数串口COM3 波特率9600 或 19200 数据位8 校验位None / Even / Odd 停止位1 或 2 站号1 到 247RTU 出问题时代码往往不是第一嫌疑。线序、终端电阻、屏蔽接地、站号、校验位任何一个不对都会超时。汇川PLC做Modbus TCP Server上位机读取 PLC 时最常见的结构是汇川 PLC 做 Modbus TCP ServerYModbus 做 Modbus TCP Client。PLC 侧需要做的事情通常包括启用 Modbus TCP 服务。配置 IP 地址和端口。设定哪些变量或软元件对外开放。明确 Holding Register、Coil 等地址和 PLC 变量的对应关系。保证 PLC 程序周期里会更新这些数据。上位机侧不要一上来就读一大堆地址。我一般让 PLC 程序员先给一张最小测试表Holding Register 0固定值 1234 Holding Register 1固定值 5678 Holding Register 2设备状态 Holding Register 3报警代码 Coil 0设备运行中 Coil 1设备报警中先把固定值读对再往后加业务数据。YModbus 读取 TCP 示例usingYModbus.Clients;awaitusingModbusClientclientawaitModbusClientFactory.CreateTcpAsync(host:192.168.1.30,port:502,unitId:1,readTimeoutMilliseconds:3000,writeTimeoutMilliseconds:3000);ushort[]registersawaitclient.ReadHoldingRegistersAsync(startAddress:0,quantity:4);bool[]coilsawaitclient.ReadCoilsAsync(startAddress:0,quantity:2);CLI 先测更快ymodbusread-holding-registers--host 192.168.1.30--port 502--unit-id 1--address 0--quantity 4如果读不到先不要改代码。先确认电脑能不能 ping 到 PLCPLC 的 Modbus TCP 服务是否启用端口是不是502防火墙或交换机策略有没有拦截UnitId 是否和 PLC 配置一致地址0是否真的有映射PLC 是否处于 RUN很多时候PLC 网口能下载程序和 Modbus TCP 服务能响应是两件事。汇川PLC做Modbus RTU从站如果现场走 RS485且希望 YModbus 读取 PLC那么 PLC 侧要做 Modbus RTU 从站。PLC 侧要确认使用哪个 RS485 口通信口是否配置成 Modbus RTU从站号是多少波特率、校验、停止位是多少地址映射表怎么写是否有通信状态或错误码可以监控YModbus 读取 RTU 示例usingSystem.IO.Ports;usingYModbus.Clients;usingYModbus.Serial;usingSerialPortportnew(COM3){BaudRate9600,DataBits8,ParityParity.Even,StopBitsStopBits.One,ReadTimeout3000,WriteTimeout3000};port.Open();awaitusingModbusClientclientModbusSerialClientFactory.CreateRtu(slaveId:1,serialPort:port,leaveOpen:true);ushort[]valuesawaitclient.ReadHoldingRegistersAsync(startAddress:0,quantity:4);CLI 示例ymodbusread-holding-registers--transport rtu--serial-port COM3--baud-rate 9600--data-bits 8--parity even--stop-bitsone--slave-id 1--address 0--quantity 4如果是 RTU 超时我会按这个顺序查COM 口有没有选错。USB 转 485 驱动是否正常。A/B 线有没有接反。PLC 侧 485 口是不是当前这个口。波特率、校验、停止位是否完全一致。从站号是否一致。总线上是否有两个主站。终端电阻和接地是否合理。这八项查完才值得怀疑代码。汇川PLC做Modbus主站或Client有些项目里汇川 PLC 不是被上位机读取而是主动去读设备。比如PLC 通过 RTU 读取变频器状态PLC 通过 RTU 写温控表设定值PLC 通过 TCP 读取扫码枪、仪表或另一台控制器PLC 主动把数据写到某个 Modbus Server这时 PLC 是主站或 Client。YModbus 的角色就要反过来。如果 PLC 做 Modbus RTU 主站YModbus 可以做 RTU 从站模拟器。如果 PLC 做 Modbus TCP ClientYModbus 可以做 TCP Server 模拟器。这个思路很有用。真实仪表还没到货时你可以先用 YModbus 放几个固定寄存器Holding Register 0 250 Holding Register 1 1000 Holding Register 2 0让 PLC 去读。PLC 如果能读到这些值说明它的站号、功能码、地址、数量、串口参数或 TCP 连接基本没问题。后面再换真实设备调试压力会小很多。地址映射不要靠猜汇川 PLC 联调里地址映射是最容易吵起来的地方。PLC 工程师说“我这个值在D100。”上位机工程师问“那我是不是读保持寄存器地址100”答案是不一定。如果 PLC 的 Modbus 映射规则就是D100对应 Holding Register100那可以这么读。但有些项目会做变量映射有些 HMI 驱动会做设备类型转换有些网关会重新映射地址有些 PLC 程序会把业务数据搬到专门的通信区。所以最稳的方式是让 PLC 侧给一张表Modbus地址功能码PLC变量类型说明003通信测试值UInt16固定1234103设备状态UInt160 停止1 运行203当前产量UInt16件数1003温度原始值Int16实际值 原始值 / 10001运行中BoolCoil101报警中BoolCoil有了这张表YModbus 只按 Modbus 地址读不去猜 PLC 内部软元件。40001和地址0的问题Modbus 文档里经常写40001、40002。YModbus 里传的通常是协议地址不是显示地址。所以显示地址 40001 - YModbus 地址 0 显示地址 40002 - YModbus 地址 1 显示地址 40011 - YModbus 地址 10第一次测试时如果 PLC 表格写的是40001你在 YModbus 里通常要从0开始读。不要把40001原样填进startAddress。这一点在所有 PLC 上都容易错汇川也一样。浮点数和缩放值汇川 PLC 项目里经常会有温度、压力、速度、位置、张力。这些值有两种常见表达方式。第一种是缩放整数。比如温度原始值 253 实际温度 25.3 ℃这种最稳一个寄存器就够通讯也直观。第二种是 32 位浮点数。一个浮点数通常占两个保持寄存器。问题就来了高字在前还是低字在前所以我更喜欢先读原始寄存器ushort[]rawawaitclient.ReadHoldingRegistersAsync(10,2);Console.WriteLine(raw[0]);Console.WriteLine(raw[1]);先把两个 16 位数记下来再用RegisterConverter去试字序。不要只说“浮点数读出来不对”。更有用的说法是我读地址10和11原始寄存器是17142和59769。按高字在前解析是12.34按低字在前解析不对。PLC 工程师一听这种描述马上就知道该查映射还是查字序。写入PLC要设计命令区读 PLC 数据问题不大写 PLC 一定要谨慎。不要让上位机直接写输出点。更推荐做一个命令区Holding Register 100命令号 Holding Register 101参数 1 Holding Register 102参数 2 Coil 100命令触发 Coil 101PLC 已接收 Coil 102PLC 执行完成 Holding Register 110执行结果码上位机写命令号和参数再置位触发位。PLC 程序收到触发后自己判断设备状态、互锁、安全条件然后执行动作。执行完再反馈完成位和结果码。这样比上位机直接写某个Y点安全得多。YModbus 写寄存器示例awaitclient.WriteSingleRegisterAsync(address:100,value:1);写线圈示例awaitclient.WriteSingleCoilAsync(address:100,value:true);写入前先在停机安全状态下测试。尤其是伺服、气缸、切刀、加热这些动作不要拿通讯调试当设备调试。一个推荐的联调流程第一次接汇川 PLC我建议这样走确认型号比如 H3U、H5U、AM、AC。确认走 TCP 还是 RTU。确认 PLC 是 Server/Slave还是 Client/Master。让 PLC 侧给最小地址表。先放固定值1234。用 YModbus CLI 读一个寄存器。再读多个寄存器。再读线圈。再接入 C# 程序。最后处理浮点数、写入命令和业务联锁。这个顺序看起来啰嗦但现场真能省时间。因为它把问题拆开了链路通不通、地址对不对、数据类型对不对、业务逻辑对不对。这四件事混在一起调最容易把简单问题调复杂。小结汇川 PLC 和 YModbus 能不能连关键看 PLC 端有没有真正开放 Modbus。H3U、H5U 这类常见汇川 PLC很多项目可以走 Modbus TCP 或 Modbus RTU但具体端口、地址、功能码和映射关系要以型号手册和项目配置为准。如果汇川 PLC 做 Server / SlaveYModbus 就作为 Client / Master 去读写。如果汇川 PLC 做 Client / MasterYModbus 就作为模拟 Server / Slave 配合 PLC 调试。第一次联调不要先追求“读全设备数据”。先读一个固定值最好是1234。这个值一通后面的路就顺了。参考资料Inovance H5U Series product pageInovance H5U Series PLC flyerInovance H3U Series PLC flyer