(二十二) 欧姆龙PLC Modbus通讯功能介绍 GitHub 项目地址https://github.com/lidecong133/YModbus欧姆龙 PLC 做 Modbus第一句话要先说清楚不要把欧姆龙的 FINS、EtherNet/IP、Host Link、上位链接、Socket 通讯都当成 Modbus。很多欧姆龙项目里HMI 能连CX-Programmer 或 Sysmac Studio 能在线甚至上位机能用 FINS 读写 PLC都不代表 Modbus 已经打开。YModbus 只按 Modbus 工作。对面如果是 FINS那就不是这套协议。对面如果是真正启用了 Modbus RTU 或 Modbus TCP那 YModbus 才能作为主站、客户端、从站模拟器去配合。欧姆龙系列很多CP1、CP2E、CJ、CS、NJ、NX 的做法都不完全一样。这篇不按某一个型号硬套而是按现场最容易遇到的几类结构讲。先问清楚是哪一种欧姆龙PLC欧姆龙 PLC 的 Modbus 能力通常和系列、CPU 型号、通信板、通信单元、功能块有关。现场可以先这样分系列或场景常见Modbus方式CP1H / CP1L常见 Modbus-RTU Easy Master用串口去读写外部从站CP2E官方提供 Modbus RTU Master Function Block也提供 Modbus TCP Server Function BlockCJ / CS常见通过串口通信单元、协议宏、样例程序或功能块做 ModbusNJ / NX常见通过 Modbus TCP 指令、Socket 或库函数做客户端类通讯具体看工程和版本上位机想读 PLC要确认 PLC 是否真的配置成 Modbus TCP Server 或 Modbus RTU Slave这里最容易误判的是最后一条。欧姆龙 PLC 很多项目天然更偏 FINS 或 EtherNet/IP。你能用上位机读变量不代表 YModbus 也能直接读。所以不要只问“欧姆龙 PLC 能不能连”更准确的问法是这台 PLC 有没有运行 Modbus TCP Server或者有没有配置成 Modbus RTU Slave如果没有它是不是只是用 Modbus RTU Master 去读外部设备欧姆龙做Modbus主站很常见欧姆龙小型 PLC 项目里最常见的是 PLC 做 Modbus 主站。比如CP1H 通过 RS485 读取变频器CP1L 读取温控表当前温度CP2E 通过 Modbus RTU Master Function Block 读写仪表CJ / CS 通过串口通信单元轮询多台从站这时 PLC 是主动发请求的一方。YModbus 如果也作为主站去抢同一条 RS485 总线就会出问题。这类场景里YModbus 更适合做模拟从站。举个例子。PLC 工程师正在写欧姆龙程序准备读取一台温控表从站号1 功能码03 起始地址0 数量2真实温控表还没到或者现场不方便接。你可以先打开 YModbus 从站工具模拟一个 RTU 从站在保持寄存器0和1里放固定值。PLC 如果能读到这些固定值说明 PLC 端的站号、功能码、地址、数量、串口参数基本没问题。这样比三个人围着一台真实仪表猜线序快得多。CP2E做Modbus TCP Server如果你希望上位机读取欧姆龙 PLC最舒服的结构是 PLC 做 Modbus TCP Server。CP2E 这一类机型欧姆龙官方提供了 Modbus TCP Server Function Block。它的作用是让 PLC 自动响应主机 PC 或其它 PLC 的 Modbus TCP 访问把外部请求映射到 Work Area 或 Data Memory Area。这时 YModbus 可以作为 Modbus TCP Client 读取。假设现场配置如下PLC IP192.168.1.60 端口502 UnitId1 Holding Register 0通信测试值固定 1234 Holding Register 1设备状态 Holding Register 2报警代码YModbus 代码可以这样写usingYModbus.Clients;awaitusingModbusClientclientawaitModbusClientFactory.CreateTcpAsync(host:192.168.1.60,port:502,unitId:1,readTimeoutMilliseconds:3000,writeTimeoutMilliseconds:3000);ushort[]valuesawaitclient.ReadHoldingRegistersAsync(startAddress:0,quantity:3);CLI 更适合第一步验证ymodbusread-holding-registers--host 192.168.1.60--port 502--unit-id 1--address 0--quantity 3如果第一个值能读到1234说明 TCP 链路、端口、UnitId、功能码和基本映射都通了。如果读不到先别改 C#。先查这些点PLC 是否在 RUNModbus TCP Server Function Block 是否真的在执行PLC IP 和端口是否正确端口是否被防火墙或交换机策略拦住UnitId 是否和 PLC 配置一致Holding Register 地址0是否真的映射到了测试值请求数量是否超过映射区欧姆龙这里特别要注意PLC 里写的是 Work Area、DM、CIO、WR、HR 这些区域上位机读的是 Modbus 地址。两者中间一定有映射关系。不要把D100或DM100直接当成 Modbus 地址100。CP2E做Modbus RTU主站CP2E 官方也提供 Modbus RTU Master Function Block。它用于 PLC 通过 RS485 直接读写变频器、仪表等 Modbus RTU 从站。官方功能块覆盖常见的几类命令比如读线圈、读保持寄存器、写单线圈、写单寄存器、写多寄存器。这时 PLC 是主站。YModbus 的推荐用法是做从站模拟器而不是再做主站。比如 PLC 要读地址0和1在 YModbus 从站工具里启动 RTU 从站。SlaveId 设置成1。保持寄存器0 250。保持寄存器1 1000。让 CP2E 程序执行 Modbus RTU Master Function Block。如果 PLC 能读到250和1000先证明 PLC 端请求是对的。后面再换真实仪表。如果 PLC 读不到就看串口参数是否一致RS485 A/B 是否接反SlaveId 是否一致PLC 功能块是否被触发是否多个请求同时抢一个串口功能码和地址是否和模拟从站一致串口 Modbus 最怕“一边猜程序一边猜接线”。先用模拟从站把 PLC 程序验证一遍会省很多时间。CP1H和CP1L的Easy MasterCP1H / CP1L 项目里常见会看到 Modbus-RTU Easy Master。它的思路是PLC 程序把要执行的 Modbus 命令放到指定的数据区再触发对应控制位让 PLC 自动生成 Modbus RTU 请求。这种方式很适合 PLC 主动控制外部设备。比如读温控表 PV写温控表 SV读变频器状态字写变频器频率设定但它不是“让上位机随便读 PLC”。如果 CP1H / CP1L 只是作为 Modbus RTU Master 去读外部从站YModbus 不能直接把它当成从站来读。YModbus 更适合模拟它要访问的仪表或变频器。如果你的需求是上位机读取 CP1H / CP1L 里的数据要另外确认PLC 是否配置成 Modbus RTU Slave是否有支持 Modbus TCP Server 的以太网模块、网关或功能块是否应该改用 FINS 协议而不是 Modbus这个边界一定要讲清楚。否则很容易出现这种对话“欧姆龙支持 Modbus。”“那我为什么读不到 PLC”因为它支持的是 PLC 主动读别人不代表它已经作为从站让你读。NJ和NX系列要看工程实现NJ / NX 系列更现代工程里常见 EtherNet/IP、OPC UA、Socket 通讯、数据库连接、运动控制等功能。Modbus 也能做但要看具体工程怎么实现。有些项目用 Modbus TCP 指令或功能块主动访问外部设备。有些项目会用 Socket 或库函数实现 Modbus TCP 客户端。有些项目可能通过网关把数据暴露成 Modbus TCP Server。所以对 NJ / NX不要只问“CPU 有没有网口”。要问它现在是 Modbus TCP Client还是 Modbus TCP Server如果是 ClientYModbus 可以做 Server 模拟器。如果是 ServerYModbus 才作为 Client 去读它。如果只是 EtherNet/IP 或 FINS那就不是 Modbus。地址映射一定要让PLC侧写清楚欧姆龙 PLC 的内部区域很多。你可能会看到CIOWRHRARDMEM全局变量结构体变量这些都不是 YModbus 直接认识的东西。YModbus 只认识 Modbus 数据区和协议地址。更稳的地址表应该这样写Modbus地址功能码PLC侧变量或区域类型说明003通信测试值UInt16固定1234103设备状态UInt160 停止1 运行203报警代码UInt160 无报警1003温度原始值Int16实际值 原始值 / 10001运行中BoolCoil不要只写DM100温度 WR10状态这对 PLC 工程师很清楚但对 Modbus 主站不够。上位机需要的是功能码、地址、长度、类型、倍率、字序和读写权限。40001和地址0欧姆龙项目里也会遇到40001。Modbus 显示地址40001通常对应协议地址0。YModbus 里传的是协议地址。所以显示地址 40001 - YModbus 地址 0 显示地址 40002 - YModbus 地址 1 显示地址 40011 - YModbus 地址 10如果欧姆龙功能块或网关手册写的是40001第一次测试时不要把40001原样填进startAddress。先从0开始读。如果项目方给的是 PLC 内部地址比如DM100那就要先问它映射到哪个 Modbus 地址。RTU从站场景下YModbus怎么读如果某个欧姆龙 PLC 或串口单元已经配置成 Modbus RTU SlaveYModbus 可以作为 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:3);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 3如果完全超时先查串口参数和接线。如果返回异常重点查功能码、地址、数量和映射区。如果返回数据但值不对再查类型、倍率和字序。写入要走命令区上位机写欧姆龙 PLC 时不建议直接写输出相关地址。更稳的是让 PLC 程序员做一个通信命令区Holding Register 100命令号 Holding Register 101参数 1 Holding Register 102参数 2 Coil 100命令触发 Coil 101PLC 已接收 Coil 102PLC 执行完成 Holding Register 110执行结果码上位机只写命令区。PLC 程序自己判断模式、急停、互锁、伺服状态、报警状态然后决定是否执行。这样比上位机直接写某个输出点安全。YModbus 写寄存器示例awaitclient.WriteSingleRegisterAsync(address:100,value:1);写线圈示例awaitclient.WriteSingleCoilAsync(address:100,value:true);第一次写入前先在从站模拟器里验证写入流程再接真实 PLC。一个推荐的联调顺序第一次接欧姆龙 PLC我建议这样走先确认协议是不是 Modbus而不是 FINS 或 EtherNet/IP。确认 PLC 是主站/Client还是从站/Server。如果是 TCP确认 IP、端口、UnitId。如果是 RTU确认串口板或通信单元、波特率、校验、停止位、站号。让 PLC 侧给出 Modbus 地址表不要只给 DM 或变量名。先放固定值1234。用 YModbus CLI 或主站工具读一个寄存器。再读多个寄存器。再处理线圈、浮点数、双字和写入命令。如果 PLC 是主站就用 YModbus 从站工具先模拟目标设备。这个顺序能把问题拆开。先证明链路再证明地址再证明数据类型最后才证明业务逻辑。常见坑欧姆龙 PLC 联调 Modbus 时常见坑有这些把 FINS 当成 ModbusPLC 只是 Modbus 主站却被当成从站来读功能块没有循环执行或触发条件不对CP / CJ / CS / NJ / NX 系列做法混用串口参数只差一个校验位RS485 A/B 接反把40001当成协议地址把DM100当成 Modbus 地址100映射区长度不够读数量太大写入成功但 PLC 程序没有处理命令区这些问题看起来小但现场最耗时间。所以第一步还是老办法先读一个固定值。小结欧姆龙 PLC 的 Modbus 通讯关键不是“欧姆龙支不支持 Modbus”。关键是这台 PLC 当前到底扮演什么角色。如果 PLC 做 Modbus TCP Server 或 RTU SlaveYModbus 就作为主站去读写。如果 PLC 做 Modbus TCP Client 或 RTU MasterYModbus 就作为从站或 Server 模拟器配合 PLC 调试。如果现场用的是 FINS、EtherNet/IP、Host Link 或其它欧姆龙通信方式那就不要拿 Modbus 硬套。把协议和角色分清楚后面再谈地址、功能码、浮点数和写入欧姆龙项目就会顺很多。参考资料OMRON: Modbus RTU Master Function Block for CP2EOMRON: Modbus TCP Server Function Block for CP2EOMRON: CP1H / CP1L overview with Modbus-RTU Easy MasterOMRON: NJ/NX-series Instructions Reference Manual