(二十一) 台达PLC Modbus通讯功能介绍 GitHub 项目地址https://github.com/lidecong133/YModbus台达 PLC 在小型设备里很常见。尤其是 DVP 系列包装机、贴标机、输送线、小型检测设备、改造项目里经常能遇到。现场常听到一句话“台达 PLC 支持 Modbus那我是不是直接读D100就行”这句话只说对了一半。台达很多 PLC 的确支持 ModbusDVP-SX、DVP-SA2 这类机型常见有 RS-232 / RS-485支持 Modbus ASCII / RTUDVP-50MC 这类控制器也会看到 Modbus TCP / RTU如果现场用了 RTU-EN01 之类模块还可能把远程 I/O 或串口设备通过 Modbus TCP 暴露出来。但 YModbus 看到的不是D100、M0、X0这种 PLC 软元件名字。YModbus 看到的是 Modbus 功能码和数字地址。所以台达 PLC 能不能连不要只问“是不是台达”而要问这台 PLC 当前启用的是 Modbus RTU、Modbus ASCII、Modbus TCP还是台达 HMI/编程软件自己的驱动下面按现场最常见的 DVP 类项目把台达 PLC 和 YModbus 怎么配合讲清楚。先看型号和通信方式台达 PLC 型号很多通信方式也不完全一样。现场可以先按这几类判断场景常见通信方式DVP-SX、DVP-SA2、DVP-SS2、DVP-ES2 等小型 PLC常见 RS-232 / RS-485Modbus ASCII / RTUDVP-SE、带以太网的 DVP 型号常见 Modbus TCP也可能同时有串口 RTUDVP-50MC 等运动控制器常见 Ethernet、Modbus TCP / RTU、EtherNet/IP 等RTU-EN01 这类模块对外可能是 Modbus TCP从站侧或远程 I/O 场景触摸屏能通信不代表标准 Modbus 地址已经清楚最后一条很重要。台达 DOP 触摸屏或其它 HMI 驱动里可能直接填D0、M10、Y0。那是 HMI 驱动帮你做了地址转换。YModbus 是通用 Modbus 库它不会自己理解D0。如果要用 YModbus 读台达 PLC必须先知道D0对应的 Modbus 地址是多少。RTU和ASCII不要混台达 DVP 系列经常能看到 “Modbus ASCII / RTU” 这种描述。这两个都是 Modbus但帧格式完全不一样。RTU 是二进制帧靠 CRC 校验。ASCII 是文本帧冒号开头靠 LRC 校验。现场如果 PLC 配成 ASCII而上位机按 RTU 去读结果就是超时。反过来也一样。YModbus 既能做 RTU也能做 ASCII但你必须按 PLC 端的真实配置来选。不要因为接线都是 RS485就默认一定是 RTU。所以第一次联调时先确认这几个参数协议RTU 还是 ASCII 串口COM3 波特率9600 / 19200 / 38400 数据位7 或 8 校验None / Even / Odd 停止位1 或 2 站号1 到 247很多台达旧项目默认会让你想到9600, 7, Even, 1这种 ASCII 风格也有很多现场会改成9600, 8, None, 1或9600, 8, Even, 1的 RTU 风格。不要猜。让 PLC 程序员或电气工程师把通信参数表拿出来。台达PLC做Modbus RTU从站如果你要让 YModbus 读取台达 PLC最常见结构是台达 PLC 做 Modbus RTU 从站YModbus 做 Modbus RTU 主站。PLC 侧要确认使用哪个通信口比如 COM1、COM2 或内置 RS-485通信口是否配置成 Modbus RTU站号是多少波特率、校验、停止位是多少D、M、X、Y 等软元件对应哪些 Modbus 地址是否允许外部写入DVP 项目里经常会通过软件通信参数或特殊寄存器设置串口格式。你可能会看到D1120、D1121这类通信参数相关寄存器也可能在软件界面里配置。不同系列和软件版本会有差异不要拿一个项目的设置照搬到另一个项目。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:4096,quantity:3);这里的4096不是随便写的。在很多 DVP 地址表里D0会出现在0x1000这一类地址也就是十进制4096。但你不能把它当成所有台达 PLC 的永久真理。更稳的写法是让 PLC 侧给表Modbus地址功能码PLC软元件说明409603D0通信测试值固定1234409703D1设备状态409803D2当前产量204801M0运行中204901M1报警中这张表比一句“读 D0”可靠得多。CLI 可以先这样测ymodbusread-holding-registers--transport rtu--serial-port COM3--baud-rate 9600--data-bits 8--parity even--stop-bitsone--slave-id 1--address 4096--quantity 3如果 PLC 里D0 1234读回来的第一个值也应该是1234。这个值读对了再继续读其它地址。线圈和输入输出怎么读台达 PLC 里常见位设备有X、Y、M、S。在 Modbus 里它们通常会落到 Coils 或 Discrete Inputs 这类区域。但要注意两件事。第一X、Y在 PLC 里可能有自己的编号习惯手册里还可能用八进制或十六进制方式表达。上位机不能只看字符要看对应的 Modbus 数字地址。第二不同驱动、网关、型号的映射可能不完全一样。所以不要直接问“M100怎么读”更好的问法是M100对应 Coil 地址多少我用功能码01还是功能码02YModbus 读线圈示例bool[]coilsawaitclient.ReadCoilsAsync(startAddress:2048,quantity:16);CLI 示例ymodbusread-coils--transport rtu--serial-port COM3--baud-rate 9600--data-bits 8--parity even--stop-bitsone--slave-id 1--address 2048--quantity 16如果这条命令读的是M0起始地址那第一个布尔值就是M0。如果项目表里写的不是2048就按项目表来。台达PLC做Modbus TCP Server如果台达 PLC 是带以太网的型号或者通过以太网模块、网关对外提供 Modbus TCPYModbus 连接会更简单。典型参数PLC IP192.168.1.40 端口502 UnitId1YModbus 示例usingYModbus.Clients;awaitusingModbusClientclientawaitModbusClientFactory.CreateTcpAsync(host:192.168.1.40,port:502,unitId:1,readTimeoutMilliseconds:3000,writeTimeoutMilliseconds:3000);ushort[]valuesawaitclient.ReadHoldingRegistersAsync(startAddress:4096,quantity:3);CLI 示例ymodbusread-holding-registers--host 192.168.1.40--port 502--unit-id 1--address 4096--quantity 3TCP 不用管串口参数但仍然要确认地址映射。另外某些网关或模块会重新映射地址。比如 PLC 内部是D0网关对外不一定还是4096。如果中间隔了以太网模块、远程 I/O 模块或第三方网关一定要拿网关侧的 Modbus 地址表。不要拿 PLC 手册的地址表直接套到网关上。台达PLC做Modbus主站有些台达项目不是让上位机读 PLC而是 PLC 主动去读设备。比如PLC 通过 RS485 读取变频器频率PLC 读取温控表当前温度PLC 写称重仪表的清零命令PLC 通过 TCP 读取远程 I/O这时台达 PLC 是 Modbus 主站或 Client。YModbus 的角色要反过来。如果 PLC 是 RTU 主站YModbus 可以模拟 RTU 从站。如果 PLC 是 TCP ClientYModbus 可以模拟 TCP Server。真实设备没到现场时这个方法很好用。先在 YModbus 从站里放几个固定值Holding Register 0 250 Holding Register 1 1000 Holding Register 2 0让台达 PLC 去读。PLC 能读到这些值说明主站请求的站号、功能码、地址、数量和串口参数基本正确。之后再换真实温控表或仪表问题会少很多。40001、十六进制和地址偏移台达项目里地址问题特别容易乱。常见有三种写法混在一起D0 0x1000 4096 40001它们不是同一种东西。D0是 PLC 软元件。0x1000是十六进制地址。4096是十进制地址。40001是很多 Modbus 资料里的显示地址。YModbus 的startAddress传的是协议地址不是40001这种显示地址。如果手册说某个保持寄存器显示地址是40001YModbus 通常从地址0开始读。如果台达 DVP 地址表说D0通信地址是0x1000YModbus 就传十进制4096。这两个规则不要混。我现场一般会让 PLC 工程师把地址表写成十进制D0 - Holding Register 4096 D1 - Holding Register 4097 M0 - Coil 2048 M1 - Coil 2049上位机按这个表读最少出错。浮点数和双字台达 PLC 项目里很多数据会用双字或浮点数。比如位置、速度、重量、温度、累计产量。Modbus 每个寄存器是 16 位。一个 32 位整数或浮点数要占两个寄存器。所以联调时要确认这个值是整数缩放还是浮点数占几个寄存器高字在前还是低字在前是否有正负号实际值是否要除以 10、100 或 1000我更推荐先用整数缩放。比如温度D10 253 实际温度 25.3 ℃这种上位机读起来很稳。如果必须用浮点数先打印原始寄存器ushort[]rawawaitclient.ReadHoldingRegistersAsync(4106,2);Console.WriteLine(raw[0]);Console.WriteLine(raw[1]);然后再用RegisterConverter按不同字序解析。不要一开始就只看最终浮点结果。原始寄存器才是排查证据。写入台达PLC要走命令区台达 PLC 可以通过 Modbus 写寄存器和线圈但写入一定要谨慎。不建议上位机直接写Y输出。更稳的方式是让 PLC 程序员做一块通信命令区D100命令号 D101参数 1 D102参数 2 M100命令触发 M101PLC 已接收 M102PLC 执行完成 D110执行结果码上位机写D100、D101、D102再置位M100。PLC 程序自己判断安全条件、互锁、设备状态然后执行动作。执行结束后PLC 反馈M102和D110。YModbus 写寄存器示例awaitclient.WriteSingleRegisterAsync(address:4196,value:1);如果项目表里D100对应 Holding Register4196这就是写命令号。写线圈示例awaitclient.WriteSingleCoilAsync(address:2148,value:true);如果项目表里M100对应 Coil2148这就是触发命令。写入前先确认设备处于安全状态。伺服、气缸、加热、切刀这些动作不要在生产运行中随便试写。一个推荐的联调流程第一次接台达 PLC我建议按这个顺序确认型号是 DVP 串口型、以太网型还是通过网关。确认协议是 RTU、ASCII还是 TCP。确认 PLC 是从站/Server还是主站/Client。让 PLC 侧给地址表最好写十进制 Modbus 地址。在 PLC 里放固定值比如D0 1234。用 YModbus CLI 先读一个寄存器。再读多个寄存器。再读线圈。再接入 C# 程序。最后处理浮点数、写入命令和业务逻辑。如果第一步固定值都读不对就不要继续调浮点数和业务代码。先把通信参数、站号、线序、协议类型和地址表查清楚。常见坑台达 PLC 联调里我最常见到这些坑PLC 配的是 ASCII上位机按 RTU 读波特率对了校验位错了RS485 A/B 接反或者没有接 SG站号填成了 HMI 站号不是 PLC Modbus 站号把D0当成地址0把十六进制0x1000当成十进制1000把显示地址40001直接填进startAddress以太网模块或网关重新映射了地址上位机写Y输出PLC 程序下一周期又覆盖掉这些问题都不高级但很耗时间。所以最稳的方式还是那句话先读固定值再扩展。小结台达 PLC 的 Modbus 通讯核心是先分清通信方式和地址映射。DVP 类小型 PLC 常见是 RS485 上的 Modbus ASCII / RTU。带以太网的型号、运动控制器或 RTU-EN01 这类模块可能提供 Modbus TCP。如果台达 PLC 做从站或 ServerYModbus 就作为主站或 Client 去读写。如果台达 PLC 做主站或 ClientYModbus 就可以作为模拟从站或 Server 配合 PLC 调试。第一次联调不要先读一大堆变量。让 PLC 里放一个固定值按地址表用 YModbus 读出来。这个点打通了后面的温度、速度、报警、命令区都好办。参考资料Delta DVP-SX SeriesDelta DVP-SA2 SeriesDelta DVP-50MC SeriesDelta RTU-EN01 Modbus TCP Remote I/O ModuleDelta Download Center: DVP-PLC Application Manual