# Mitsubishi MC

> 通过 MC 协议（3E 帧）连接 Mitsubishi MELSEC PLC：软元件代号、十进制与十六进制编号，以及读取长度。

**Mitsubishi MC** 驱动通过 MC 协议和 Mitsubishi MELSEC PLC 对话，用的是 TCP 上的二进制 3E 帧，也就是 Q、L 和 iQ 系列说的那种帧。你用熟悉的 MELSEC 软元件记法来寻址数值：一个软元件代号加一个编号，例如 `D100` 或 `M50`。在 [Connector](connector) 里的 Mitsubishi MC 驱动下面添加一台设备；面板只显示这个协议用得到的那些字段。

## 连接 {#connection}

| 字段 | 含义 | 默认值 |
| --- | --- | --- |
| **主机** | PLC 以太网接口的 IP 地址或主机名。 | 空 |
| **端口** | MC 协议连接的 TCP 端口，1 到 65535。框留空时 5007 以灰色显示，设备就在这个端口上被拨号连接；以 0 保存的设备也是这样显示的。 | 5007 |

设备标题栏显示拼好的 endpoint，例如 `mcp://192.168.0.20:5007`。这个驱动没有轮询间隔字段：它的点位每秒读一次。PLC 那一侧需要在选定的端口上有一条 TCP、二进制的 MC 协议（SLMP）连接：在哪里创建，见[准备 PLC](#prepare-the-plc)。

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

MELSEC CPU 只在它的工程创建的连接上提供 MC 协议；除非它的以太网端口允许，它在 RUN 状态下会拒绝写入。这些设置在工程工具中完成，并随参数一起写入 CPU（**Online > Write to PLC**）；CPU 在启动时读取它们，因此写入后要复位 CPU 或断电再上电。

| 设置 | GX Works3（iQ-R、iQ-F） | GX Works2（Q、L） | 没有它时 |
| --- | --- | --- | --- |
| 设备**端口**上的一条 TCP MC 连接 | **Module Parameter > Ethernet Port > Basic Settings > External Device Configuration**：把一个 **SLMP Connection Module** 拖进表格，Protocol 选 TCP，**Port No.** 填设备的端口。 | **PLC Parameter > Built-in Ethernet Port Setting > Open Setting**：填写一行，Protocol 为 TCP，**Open System** 为 MC Protocol，**Host Station Port No.** 为设备的端口。 | CPU 拒绝该端口上的连接，设备保持离线。 |
| **Communication Data Code** 设为二进制 | **Module Parameter > Ethernet Port > Basic Settings**：**Binary**。 | **PLC Parameter > Built-in Ethernet Port Setting**：**Binary Code**。 | CPU 以 ASCII 字符应答，或者根本不应答，没有点位能读到值。 |
| 允许 RUN 中写入 | iQ-R：**Module Parameter > Ethernet Port > Basic Settings**，把 **Enable/Disable Online Change** 设为 **Enable All (SLMP)**。 | **PLC Parameter > Built-in Ethernet Port Setting**，勾选 **Enable online change (FTP, MC Protocol)**。 | CPU 读取正常，但在 RUN 状态下以结束码 0x0055 拒绝每一次写入。 |

Q 或 L 系列 CPU 自己保留端口 5000 到 5009，所以它的 MC 连接不能使用设备的默认端口 5007：给它另一个端口，例如 5010，并在设备的**端口**中填入这个端口。GX Works2 可能以十六进制显示 **Host Station Port No.**，此时 5010 显示为 1392。数据代码对整个以太网端口只有一种：在该端口上用 ASCII 与 CPU 通信的其他程序也必须改为二进制。

当 CPU 拒绝端口、以 ASCII 应答或拒绝 RUN 中的写入时，设备页面会用一条提示说明是哪项设置，并附上这些步骤和设备连接的端口；CPU 接受后，提示会自行消失。对于 RUN 中被拒绝的写入，它会列出写入被拒绝的点位。诊断日志和代理读到的是同样的步骤。

## 寻址 {#addressing}

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

| 字段 | 含义 | 接受的取值 | 默认值 |
| --- | --- | --- | --- |
| **设备地址** | MELSEC 软元件代号加编号，例如 `D100`。必填。 | 自由文本 | 空 |
| **读取长度（字节，留空为自动）** | 每次读取传输多少字节。留空就按数据类型定读取的大小。 | 1 及以上，或留空 | 留空 |

地址不区分大小写，而且匹配最长的那个代号胜出，所以 `SD100` 是特殊寄存器 100，不是步进继电器 `S`。对 Mitsubishi 按十六进制编号的那些软元件（X、Y、B、W、SB、SW、DX、DY），编号是**十六进制**的，其余一律是十进制的（`X1F` 是输入 0x1F）。接受的软元件代号有：

| 代号 | 软元件 | 编号 |
| --- | --- | --- |
| `M` | 内部继电器 | 十进制 |
| `SM` | 特殊继电器 | 十进制 |
| `L` | 锁存继电器 | 十进制 |
| `F` | 报警器 | 十进制 |
| `V` | 边沿继电器 | 十进制 |
| `S` | 步进继电器 | 十进制 |
| `X` | 输入 | 十六进制 |
| `Y` | 输出 | 十六进制 |
| `B` | 链接继电器 | 十六进制 |
| `SB` | 特殊链接继电器 | 十六进制 |
| `DX` | 直接输入 | 十六进制 |
| `DY` | 直接输出 | 十六进制 |
| `D` | 数据寄存器 | 十进制 |
| `SD` | 特殊寄存器 | 十进制 |
| `R` | 文件寄存器 | 十进制 |
| `ZR` | 扩展文件寄存器 | 十进制 |
| `W` | 链接寄存器 | 十六进制 |
| `SW` | 特殊链接寄存器 | 十六进制 |
| `Z` | 变址寄存器 | 十进制 |
| `TC` / `TS` / `TN` | 定时器线圈 / 触点 / 当前值 | 十进制 |
| `SC` / `SS` / `SN` | 累计定时器线圈 / 触点 / 当前值 | 十进制 |
| `CC` / `CS` / `CN` | 计数器线圈 / 触点 / 当前值 | 十进制 |

底层的 MC 库还接受 `TT`、`TM`、`CT`、`CM` 和 `A` 这几个代号。“信号源”卡片里那行只读的**源地址（总线）**会随着你编辑显示拼好的地址。

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

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

| 数据类型 | 自动读取长度 | 说明 |
| --- | --- | --- |
| Boolean | 1 字节 | 在位软元件上就是点名的那一个继电器；在字软元件上则是任何非零的字 |
| Int32 | 4 字节 | 两个连续的 16 位字，例如 `D100`+`D101` |
| Float | 4 字节 | 两个连续的字，装着一个 IEEE 单精度数 |
| String | 16 字节 | 读缓冲区里直到第一个 NUL 为止的文本 |

字数据以 MELSEC 原生的小端序到来，并被自动解码；没有字节序选项。一个 32 位的值跨两个连续的字软元件。文本长于 16 个字符时，请把**读取长度**抬到能覆盖存着的那段文本。**读取长度**是一个字节数，而协议传输的是整个 16 位字，所以奇数长度会被向上取整到装着它最后一个字节的那个字。

位软元件，也就是驱动一次读一个继电器的那些，是 `X`、`Y`、`M`、`L`、`F`、`V`、`B`、`S`、`TS`、`TC`、`SS`、`SC`、`CS`、`CC`、`SB`、`DX`、`DY`。放在它们上面的布尔点位，只替你打进去的那个地址应答，不替别的。其余代号都是字软元件，定时器或计数器的当前值（`TN`、`SN`、`CN`）以及链接寄存器（`W`、`SW`）也在其中；那里整个字说了算：`D100` 里装着 `0x0100` 就读作真。

PLC 拒绝的读取（例如超出范围末尾的地址）会让该点位没有值，它的错误写出结束码及其在手册中的含义，例如 `end code 0xC056 (the request goes past the last address of the device)`。设备的其他点位继续读取。

## 写入 {#writes}

**访问**为读写或只写的点位可以被写，写到读所用的那同一个设备地址上。位软元件上的布尔写入会置位或复位点名的那一个继电器，一点也不碰它的邻居。其余一切都按整个 16 位字来写：Int32 和 Float 各两个字，字软元件上的布尔一个字，而文本则是这个点位整个**读取长度**，前面是文本的 UTF-8 字节，后面是零，并向上取整到最后一个字。因此，用一段短文本盖住一段长文本时，整个值都被替换掉，旧的一点儿都不剩。装不进声明长度的文本会被拒绝，长度写进诊断日志，绝不会被截短了塞进去。新点位一开始是只读。

PLC 拒绝的写入会以拒绝返回，并以同样的方式写出结束码及其含义。因 CPU 处于 RUN 而被拒绝的写入（结束码 0x0055）还会显示在设备页面上，并附上允许它的设置（见[准备 PLC](#prepare-the-plc)）。

## 设备发现 {#discovery}

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

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

- 这个驱动上每一个点位的轮询都固定为一秒；平常那些轮询间隔字段不显示。
- 这个驱动只使用二进制的 3E 帧，从不使用 ASCII：设为 ASCII 代码的连接读不到任何值（见[准备 PLC](#prepare-the-plc)）。
- 一台够不着的 PLC 在启动时不花什么代价：设备在后台一直重试，在连接接上之前它的点位读作质量不可用。
- TCP 连接有 5 秒时间打开，每个请求有 10 秒时间得到应答。接受了连接却没有及时应答的 PLC 会被断开，并像够不着的 PLC 一样重试；它的错误写出端口和两个常见原因：端口设为 ASCII 代码的 Q 或 L 系列 CPU 对二进制请求什么都不应答，或者那个端口上的设备不使用 MC 协议。
