# Beckhoff ADS

> 通过 ADS/AMS 连接 Beckhoff TwinCAT PLC：AMS 路由、运行时端口、符号路径和读取长度。

**Beckhoff ADS** 驱动通过 ADS 和 Beckhoff TwinCAT PLC 对话，也就是承载在 AMS 路由上的那个 TwinCAT 自动化协议。你按 PLC 程序里的符号路径来寻址数值，所以你打进去的就是 TwinCAT 项目声明的那个。在 [Connector](connector) 里的 Beckhoff ADS 驱动下面添加一台设备；面板只显示这个协议用得到的那些字段。

## 连接 {#connection}

| 字段 | 含义 | 默认值 |
| --- | --- | --- |
| **主机** | PLC 的 IP 地址。它的 AMS Net Id 由这个地址推成 `{ip}.1.1`。 除非在 **PLC 的 AMS Net Id** 中另行填写，PLC 的 AMS Net Id 就是这个地址后面跟 `.1.1`；写成名称时，先把它解析成 IPv4 地址。 | 空 |
| **端口** | 目标运行时的 AMS 端口：851 是 TwinCAT 3 的第 1 个 PLC 运行时，再往后的 TwinCAT 3 运行时从那里往上数（852、853、……）。框留空时 851 以灰色显示，用的就是这个运行时；以 0 保存的设备也是这样显示的。 | 851 |
| **本机 IP（AMS）** | 本工作站自己的 IP 地址，它的 AMS Net Id 由此推成 `{ip}.1.1`。它必须和 PLC 上配置的 AMS 路由对上。框留空时，用的是本工作站在通往 PLC 的网络上的地址，并以灰色显示；在框里填了值，就改用填的值。 | 空 |
| **PLC 的 AMS Net Id** | PLC 自己的 AMS Net Id，用于 id 不是其 IP 地址后面跟 `.1.1` 的 PLC：用点分隔的六个 0 到 255 之间的数，与 TwinCAT XAE 在 **SYSTEM > Routes** 的 **NetId Management** 选项卡中显示的 **Target NetId** 一致。框留空时用主机的 IPv4 地址后面跟 `.1.1`，并以灰色显示。不是 AMS Net Id 的值会让设备保持断开，并说明应该填什么。 | 空 |
| **轮询间隔（ms）** | 整台设备的读取周期，供没有自己另作规定的点位使用。 | 1000 |

设备标题栏显示拼好的 endpoint，例如 `ads://192.168.0.1:192.168.0.50:851`（本机 IP、PLC IP、AMS 端口）。每个点位都可以设自己的**轮询间隔（ms）**；点位填 0 就退回设备的间隔。

ADS 只应答 PLC 有 AMS 路由的那些工作站：要加哪条路由、在哪里加，见[准备 PLC](#prepare-the-plc)。

## 准备 PLC {#prepare-the-plc}

TwinCAT PLC 只对它的 AMS 路由器有路由的工作站应答 ADS。没有这条路由，路由器会在 TCP 端口 48898 接受连接，然后把它关掉或者一直不应答，所以即使网络通路完全正常，连接也会失败。请在 PLC 上为本工作站加一次静态路由：

| TwinCAT Add Route 对话框的字段 | 值 |
| --- | --- |
| 名称：**Route Name (Target)** | 任意名称；提示里建议用本工作站的计算机名。 |
| Net Id：**AmsNetId** | 本工作站的地址后面跟 `.1.1`，和驱动从**本机 IP（AMS）**推出来的那个一致。 |
| 传输：**Transport Type** | 传输方式 `TCP_IP` |
| 地址：**Address Info** | 本工作站的地址，并选中 **IP Address**。 |
| 路由类型：**Target Route** 和 **Remote Route** | `Static` 和 `None` |

在 TwinCAT XAE 中把 PLC 选为目标系统，打开 **SYSTEM > Routes** 的 **Static Routes** 选项卡，再点 Add。在 PLC 自己的桌面上，通知区域里的 TwinCAT 图标通过 **Router > Edit Routes** 也能打开同一个列表。

这个地址是本工作站在通往 PLC 的那个网络上的地址。装了几块网卡的计算机每块网卡各有一个地址，路由只对它写明的那个地址有效。**本机 IP（AMS）**留空时，驱动使用 Windows 通往 PLC 时经过的那块网卡的地址，框里以灰色显示它：路由要写的就是这个地址。在框里填了值，就改用填的值，路由也必须写这个值。

PLC 的路由器因为缺少路由而拒绝本工作站时，设备页面会用一条提示代替驱动的错误来说明：一条可以直接添加的路由（它的名称、本工作站的 AMS Net Id、它的地址和传输方式，每项都带复制按钮），以及在 TwinCAT 里添加它的位置。PLC 一应答，提示就会自行消失，日志和智能体读到的也是同一条路由。拒绝连接或一直不出声的端口，会照实说明，而不会被说成缺少路由。

本工作站用 AMS Net Id 来寻址 PLC，而 PLC 的路由器只应答发给它自己那个 id 的请求：AMS Net Id 和本工作站所用的不一致的 PLC 同样永远不会应答，看起来和缺少路由完全一样。如果 PLC 上已经有这条路由却仍然不应答，请在 TwinCAT XAE 的 **SYSTEM > Routes** 的 **NetId Management** 选项卡中核对 **Target NetId**，并把它填到 **PLC 的 AMS Net Id** 里；提示里会写出本工作站所用的那个 id。

## 寻址 {#addressing}

Beckhoff 的点位靠点位“信号源”卡片里的两个字段寻址：

| 字段 | 含义 | 接受的取值 | 默认值 |
| --- | --- | --- | --- |
| **符号** | 这个变量在 PLC 程序里的符号路径。必填。 | 自由文本，例如 `MAIN.fValue` | 空 |
| **读取长度（字节，留空为自动）** | 每次读取传输多少字节。留空就按数据类型定读取的大小。 | 1 及以上，或留空 | 留空 |

符号路径就是 TwinCAT 显示的那个：程序变量写作 `MAIN.fValue`，全局变量列表写作 `GVL.MachineSpeed` 或 `GVL_Settings.rSetpoint`。驱动在 PLC 上按名字解析这个符号，并读它的原始字节。自动的读取长度是：

| 数据类型 | 自动读取长度 |
| --- | --- |
| Boolean | 1 字节 |
| Int32 | 4 字节 |
| Float | 4 字节 |
| String | 16 字节 |

文本长于 16 个字符时，请把**读取长度**设到能覆盖声明的大小（一个 TwinCAT 的 `STRING(80)` 需要 80 字节的文本）。“信号源”卡片里那行只读的**源地址（总线）**会随着你编辑显示拼好的地址。

PLC 拒绝的读取（例如读一个它没有的符号，或一个它不允许读的符号）会让点位没有值，点位的原因会写出 ADS 错误代码及其含义，例如 `ADS error 0x710 (no symbol by that name)`。连接保持不断，其他点位照常读取；PLC 应答下一次读取时，这个原因就会消失。

## 数据类型 {#data-types}

**数据类型**选择器提供驱动能编排的那四种类型：

| 数据类型 | PLC 里的对应物 | 说明 |
| --- | --- | --- |
| Boolean | BOOL | 1 字节，非零为真 |
| Int32 | DINT | 小端序，和 PLC 一致 |
| Float | REAL | 小端序，和 PLC 一致 |
| String | STRING | 读缓冲区里直到第一个 NUL 为止的文本 |

字节序就是 PLC 自己的小端序，由驱动自动处理；没有字节序选项。文本读取会把返回的缓冲区解码到第一个 NUL 结束符为止，所以一段短文本后面的填充绝不会漏进这个值里。别的 TwinCAT 位宽（INT、LREAL、WORD、……）不提供：请在 PLC 程序里把这样的变量以上面那四种类型之一暴露出来，再在这里读。

## 写入 {#writes}

**访问**为读写或只写的点位可以被写。一次写入会解析同一个符号，并写下这个值的字节：布尔 1 字节，Int32 和 Float 各 4 字节。文本写入会铺满这个点位整个**读取长度**：前面是文本的 UTF-8 字节，后面是零，所以用一段短文本盖住一段长文本时，整个值都被替换掉，旧的一点儿都不剩。装不进声明长度的文本会被拒绝，长度写进诊断日志，绝不会被截短了塞进去。新点位一开始是只读。

PLC 拒绝的写入（例如写一个它不允许写的符号）会以拒绝返回，并带上 ADS 错误代码及其含义，例如 `ADS error 0x704 (the symbol may not be written)`；连接保持不断。

## 设备发现 {#discovery}

这个驱动里的 ADS 没有广播式的设备发现，所以 Connector 不显示“发现设备”按钮。设备和它的符号请手工添加。

## 需要知道的事 {#good-to-know}

- 第一次连接失败，通常的原因就是 AMS 路由：PLC 上那条路由的 AMS Net Id 必须恰好是工作站 IP 加上 `.1.1`，设备页面会给出要添加的整条路由。
- 驱动在每次连接里只向 PLC 要一次每个符号的句柄，连接关闭时再把句柄还回去。PLC 下载之后，PLC 不再认的句柄会在下一次读取时换掉，所以点位在新程序下照常读取；被这次下载重命名或删掉的符号，会让它的点位没有值，并带上 `ADS error 0x710 (no symbol by that name)`，直到名字重新对上为止。
- 一台够不着的 PLC 在启动时不花什么代价：设备在后台一直重试，在连接接上之前它的点位读作质量不可用。
