4. ADS协议原理

ADS(Automation Device Specification)是 Beckhoff 为 TwinCAT 体系定义的自动化设备通信规范。它并不是一个孤立的“新协议”,而是建立在 TCP/IP 或 UDP 之上的应用层协议,通过 AMS(Automation Message Specification)报文完成设备寻址、服务调用与数据读写。理解 ADS,关键要抓住五个概念:协议栈、AMS NetID、端口号、索引组与索引偏移、通信模型。它们分别回答“数据怎么走”“找哪台设备”“找哪个服务”“读写哪个变量”“谁主动发起”这五个问题。

一、ADS 协议栈:从用户程序到物理网络

ADS 通信在软件层面是分层封装的。最上层是用户程序或 ADS 客户端库(如 TwinCAT.Ads、ADS DLL、PyADS);向下是 ADS 服务层,负责 Read、Write、ReadWrite、AddDeviceNotification 等服务命令;再向下是 AMS 报文层,封装源/目标 NetID、源/目标端口、命令号、状态码和数据长度;之后是 TCP 或 UDP 传输层,最后是 Ethernet 物理层。TwinCAT 运行时内部有一个 AMS Router,它负责把 AMS 报文在本地端口、远程设备、不同网络接口之间转发。

因此,一次 ADS 读写并不是“直接访问 PLC 内存”,而是“客户端构造 AMS 报文 → 传输层发送 → 目标 AMS Router 接收 → 路由到目标端口 → 目标服务处理 → 返回响应”。这也是为什么 NetID 和端口号必须同时正确,否则报文会被路由器丢弃或返回目标未找到错误。

二、AMS NetID:设备的逻辑地址

AMS NetID 是 AMS 网络中设备的唯一逻辑标识,通常表示为“IP 地址.1.1”的形式,例如 192.168.1.10.1.1。其中前四段是 IP 地址,后两段是 AMS 子网标识和节点标识。对于本机 TwinCAT 系统,常见本机 NetID 为 127.0.0.1.1.1 或实际网卡 IP 对应的 NetID。NetID 的作用类似“门牌号”,它告诉 AMS Router:这条报文最终应该交给哪台设备上的 AMS 服务。

需要特别注意:NetID 不是 IP 地址的简单别名。一个设备可能有多个网卡,也可能配置多个 NetID;远程路由场景下,目标 NetID 甚至可能不是目标设备的真实 IP,而是路由表中映射的逻辑地址。因此,在跨网段或通过路由访问时,必须同时检查路由表和 NetID 配置。

三、端口号:定位设备内的服务

AMS 端口号不是 TCP/UDP 端口,而是 AMS 网络内部的“服务端口”。它用于区分同一台设备上的不同 ADS 服务。常见端口包括:

端口号 服务对象 典型用途
851 TwinCAT PLC 运行时 读写 PLC 变量、调用 PLC 服务
852 TwinCAT NC/运动控制 轴参数、运动控制数据访问
10000 系统服务 系统信息、设备管理
16 ADS 设备通知 订阅变量变化通知

端口号决定了“找哪个服务”。例如访问 PLC 变量时目标端口通常是 851;如果误写成 852,即使 NetID 正确,也会因为目标服务不存在或变量不匹配而失败。

四、索引组与索引偏移:定位具体变量

在 ADS 中,真正定位一个变量或数据项,靠的是“索引组(IndexGroup)+ 索引偏移(IndexOffset)”。索引组表示数据类别或对象类型,索引偏移表示该类别中的具体位置。对于 PLC 变量,常见做法是通过变量名解析得到对应的索引组和索引偏移;对于符号访问,ADS 还支持按名称读取,但底层仍会转换为索引组/偏移或句柄。

例如,读取 PLC 中某个变量时,客户端可能使用:

IndexGroup  = 0x4020
IndexOffset = 0x00000000
Length      = 4
目标端口    = 851
目标NetID   = 192.168.1.10.1.1

其中 0x4020 常用于 PLC 变量区访问。不同索引组对应不同数据区域,索引偏移则像“数组下标”一样指向具体位置。若索引组或偏移错误,即使 NetID 和端口正确,也会读到错误数据或返回访问拒绝。

记忆口诀:NetID 找设备,端口找服务,索引组找类别,索引偏移找位置。四者同时正确,ADS 读写才能成功。

五、通信模型:客户端/服务端与通知机制

ADS 采用客户端/服务端通信模型。客户端主动发起请求,服务端响应。典型服务包括 Read、Write、ReadWrite、ReadState、WriteControl 和 AddDeviceNotification。前几种是同步请求/响应模式;AddDeviceNotification 则用于订阅变量变化,服务端在数据变化时主动发送通知,适合数据采集和实时监控。

从数据流看,一次 ADS 读取的路径是:客户端构造 AMS 报文 → 传输层发送 → 目标 AMS Router → 目标端口服务 → 根据索引组/偏移访问数据 → 返回响应。通知模式则是在服务端注册后,由服务端按周期或变化触发上报。理解这个模型,有助于排查“读不到”“读错”“通知不触发”等问题。

ADS 协议栈与通信模型 ADS 客户端 用户程序 / ADS 库 ADS 服务层 AMS 报文封装 TCP / UDP 传输 Ethernet 物理层 AMS Router 按 NetID + 端口转发 本地 / 远程路由 ADS 服务端 目标端口 851 / 852 索引组 IndexGroup 索引偏移 IndexOffset PLC 变量 / 数据区 返回响应 / 通知 请求 请求 响应 响应 NetID 定位设备 → 端口定位服务 → IndexGroup/IndexOffset 定位数据 → 客户端/服务端完成读写或通知

六、案例与排障:一次读取失败的复盘

假设客户端要读取 192.168.1.10 上 PLC 的某个变量,配置如下:

目标NetID   = 192.168.1.10.1.1
目标端口    = 851
IndexGroup  = 0x4020
IndexOffset = 0x00000000
读取长度    = 4

如果返回“目标未找到”,优先检查 NetID 是否与目标设备实际配置一致,以及 AMS 路由表是否已添加。如果返回“端口未找到”,检查目标端口是否写错,或 PLC 运行时是否已启动。如果返回“访问拒绝”或数据异常,检查索引组和索引偏移是否对应正确变量,以及读取长度是否越界。若使用通知模式却收不到数据,检查 AddDeviceNotification 是否注册成功、通知周期是否合理、变量是否真的发生变化。

常见误区:把 AMS 端口号当成 TCP 端口号;把 NetID 当成 IP 地址直接使用;只改 IP 不更新 NetID;索引偏移按字节数而不是按变量实际偏移计算。这些都会导致 ADS 通信失败或数据错位。

七、核心要点清单

  • ADS 是应用层协议,依赖 TCP/UDP 传输,由 AMS Router 完成路由。
  • AMS NetID 是设备逻辑地址,格式通常为“IP.1.1”。
  • AMS 端口号定位设备内服务,PLC 常用 851,NC 常用 852。
  • IndexGroup 表示数据类别,IndexOffset 表示具体位置。
  • 通信模型以客户端/服务端为主,支持同步读写和通知订阅。
  • 排障顺序:NetID → 端口 → 索引组/偏移 → 数据长度 → 服务状态。

掌握这五个概念后,再看 ADS 的 API、路由配置和变量访问代码,就能把“地址、服务、数据、方向”四个维度对应起来,而不是停留在“能连上但不知道为什么能连上”的层面。