# Modbus TCP

Modbus TCP 是一种基于以太网的 Modbus 协议版本，它使用 TCP/IP 协议进行通信。与传统的 Modbus RTU 协议不同，Modbus TCP 允许设备直接通过以太网互联，不需要任何专用的硬件或通信接口。因此，Modbus TCP 具有更高的通信速率和更广泛的应用范围。

Neuron 的 Modbus TCP 插件除了支持以 TCP 客户端的模式主动接入设备进行数据采集；还增加支持了 TCP 服务端模式，允许设备主动接入到 Neuron，主要用于如 4G DTU，因 4G 网络的 IP 是属于私网 IP，此时只能由 DTU 设备主动连接到 Neuron。

## 添加插件

在 **配置 -> 南向设备**，点击**添加设备**来创建设备节点，输入插件名称，插件类型选择 **Modbus TCP** 或 **Modbus TCP QH** 启用插件。

| <div style="width:100pt">插件</div> | 说明                                                    |
| -------------------- | ------------------------------------------------------- |
| **Modbus TCP** | 标准 Modbus TCP 协议实现，支持 TCP 客户端与服务端模式，对设备有更好的兼容性。|
| **Modbus TCP QH** | 定制化 Modbus TCP 协议实现，支持一次最大读取 65530 字节，标准的协议最大一次读取 250 字节。|

## 设备配置

点击插件卡片或插件列，进入**设备配置**页。配置 Neuron 与设备建立连接所需的参数，下表为插件相关的配置项。

| <div style="width:100pt">字段</div> | 说明                                                    |
| -------------------- | ------------------------------------------------------- |
| **连接模式** | 选择以太网 TCP 连接时，可以选择 Neuron 作为 TCP 的客户端或是服务端。|
| **最大重试次数** | 发送读取指令失败后最大重试次数。 |
| **指令重新发送间隔** | 发送读取指令失败后重新发送读指令时间间隔，单位为毫秒。 |
| **4 字节字节序**   | 32 位数据类型字节序，ABCD 对应 1234。 |
| **8 字节字节序**   | 64 位数据类型字节序，每个数字代表一字节。 |
| **开始地址** | 点位起始地址从 1 开始或从 0 开始。 |
| **指令发送间隔** | 发送每条读写指令之间的等待时间。某些串口设备在较短时间内接收到连续指令时，可能会丢弃某些指令。 |
| **IP 地址** | TCP 连接时，设备的 IP 地址（Neuron 作为客户端）；或是 Neuron 本机的 IP 地址（Neuron 作为服务端），默认可填 0.0.0.0。|
| **端口号** | TCP 连接时，设备的端口号（Neuron 作为客户端）；或是 Neuron 本机的端口（Neuron 作为服务端）。|
| **连接超时时间** | 等待设备返回指令响应的时间。 |
| **校验报文头** | 选择是否对报文头进行校验。选择校验后，遇到报文头错误时 neuron 与设备会重新连接。 |
| **设备降级** | 启用或禁用设备降级机制。 |
| **降级失败阈值** | 触发设备降级所需的连续失败周期数。 |
| **降级恢复时间** | 设备从降级中恢复所需的时间（单位：秒）。 |
| **备用 IP 地址** | 选填，当连接异常后会自动尝试连接备用地址，备用地址连接异常会自动尝试连接原地址。 |
| **备用端口号** | 选填，当连接异常后会自动尝试连接备用地址，备用地址连接异常会自动尝试连接原地址。 |

::: tip  
上述配置可以满足设备的个性化需求：<br> 

1. 重试请求视为同一次请求，即重试成功视为该请求成功。<br>
2. 在同一读取周期内，如果某个站点号的某个点位未收到回复，则跳过该周期内同站点号下其他点位的请求。<br>  
3. 设备降级触发条件为连续多个周期某站点号的点位未收到设备回复（也可以配置为一个周期失败即触发）。一旦触发，在配置的时间段内，所有该站点的请求将停止发送。
:::

## 设置组和点位

完成插件的添加和配置后，要建立设备与 Neuron 之间的通信，首先为南向驱动程序添加组和点位。

完成设备配置后，在**南向设备**页，点击设备卡片/设备列进入**组列表**页。点击**创建**来创建组，设定组名称以及采集间隔。完成组的创建后，点击组名称进入**点位列表**页，添加需要采集的设备点位，包括点位地址，点位属性，数据类型等。

公共配置项部分可参考[连接南向设备](../south-devices.md)，本页将介绍支持的数据类型和地址格式部分。

### 数据类型

* INT16
* UINT16
* INT32
* UINT32
* INT64
* UINT64
* FLOAT
* DOUBLE
* BIT
* STRING
* BYTES

### 地址格式

> SLAVE!ADDRESS\[.BIT][#ENDIAN]\[.LEN\[H]\[L]\[D]\[E]]\[.BYTES]
#### **SLAVE**

必填，指从机地址或者是站点号。

#### **ADDRESS**

必填，指寄存器地址。Modbus 协议有四个区域，每个区域最大有 65536 个寄存器，每个区域的地址范围如下表所示。注意：实际应用中，一般 PLC 厂家普遍采用 10000 以内的地址范围，请注意根据设备的区域及功能码，正确填写点位地址。

| 区域                       | 地址范围          | 属性        | 寄存器大小     | 功能码        | 数据类型 |
| ------------------------- | ---------------- | ---------- | ------------- | ------------ | ------- |
| Coil（线圈）                | 000001 ~ 065536 | 读/写       | 1Bit          | 0x01,0x05,0x0f | BIT     |
| Input（离散量输入）          | 100001 ~ 165536 | 读          | 1Bit         | 0x02          | BIT     |
| Input Register（输入寄存器） | 300001 ~ 365536 | 读          | 16Bit,2Byte         | 0x04          | BIT,INT16,UINT16,INT32,UINT32,INT64,UINT64,FLOAT,DOUBLE,STRING|
| Hold Register（保持寄存器）  | 400001 ~ 465536 | 读/写       | 16Bit,2Byte         | 0x03,0x06,0x10 | BIT,INT16,UINT16,INT32,UINT32,INT64,UINT64,FLOAT,DOUBLE,STRING|

#### **.BIT**

选填，寄存器中的特定 bit，例如：
| 地址         | 数据类型 | 说明                                                |
| ----------- | ------- | --------------------------------------------------- |
| 1!300004.0  | bit     | 指站号为1，输入寄存器区域，地址为 300004，第 0 位。    |
| 1!400010.4  | bit     | 指站号为1，保持寄存器区域，地址为 400010，第 4 位。    |
| 2!400001.15 | bit     | 指站号为2，保持寄存器区域，地址为 400001，第 15 位。   |

#### **#ENDIAN**

选填，字节顺序，适用于 int16/uint16/int32/uint32/float 数据类型，详细说明见下表。
| 符号 | 字节顺序 | 支持的数据类型        | 备注 |
| --- | ------- | ------------------ | ----- |
| #B  | 2,1     | int16/uint16       |       |
| #L  | 1,2     | int16/uint16       | 不填，默认字节顺序 |
| #LL | 1,2,3,4 | int32/uint32/float | 不填，默认字节顺序 |
| #LB | 2,1,4,3 | int32/uint32/float | |
| #BL | 3,4,1,2 | int32/uint32/float | |
| #BB | 4,3,2,1 | int32/uint32/float | |

字节顺序同样适用于 int64/uint64/double 数据类型，每个数字代表一字节，详细说明见下表。
| 符号 | 字节顺序 | 支持的数据类型        | 备注 |
| --- | ------- | ------------------ | ----- |
| #LL | 12,34,56,78 | int64/uint64/double | 不填，默认字节顺序 |
| #LB | 21,43,65,87 | int64/uint64/double | |
| #BL | 78,56,34,12 | int64/uint64/double | |
| #BB | 87,65,43,21 | int64/uint64/double | |

::: tip
点位字节序优先级高于节点字节序配置。即点位配置字节序后，字节序按照点位的配置，忽略节点配置。
字节顺序可能用 ABCD 表示，只需将 1234 对应 ABCD 即可。例如 ABCD 对应默认字节序 1234 (#LL)。
:::

#### .LEN\[H]\[L]\[D]\[E]

当数据类型为 STRING 类型时，**.LEN** 是必填项，表示字符串需要占用的字节长度，每个寄存器中包含**H**，**L**，**D** 和**E** 四种存储方式，如下列表格所示。
| 符号 | 说明                                  |
| --- | ------------------------------------- |
| H   | 一个寄存器存储两个字节，高字节在前低字节在后。 |
| L   | 一个寄存器存储两个字节，低字节在前高字节在后。 |
| D   | 一个寄存器存储一个字节，且存储在低字节。      |
| E   | 一个寄存器存储一个字节，且存储在高字节。      |

#### **.BYTES**

选填，读写 bytes 类型数据的长度，适用于 bytes 数据类型。

::: tip
Modbus 驱动的一个寄存器包含 2 个 bytes，在以 bytes 数据类型读取和写入 Modbus 寄存器数据时，请保证 bytes 参数设置为偶数。
:::

### 地址示例

| 地址         | 数据类型 | 说明 |
| ----------- | ------- | --------- |
| 1!300004    | int16    | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #L |
| 1!300004#B  | int16    | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #B |
| 1!300004#L  | uint16   | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #L |
| 1!400004    | int16    | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #L |
| 1!400004#L  | int16    | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #L |
| 1!400004#B  | uint16   | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #B |
| 1!300004    | int32    | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #LL |
| 1!300004#BB | uint32   | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #BB |
| 1!300004#LB | uint32   | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #LB |
| 1!300004#BL | float    | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #BL |
| 1!300004#LL | int32    | 指站号为 1，输入寄存器区域，地址为 300004，字节顺序为 #LL |
| 1!400004    | int32    | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #LL |
| 1!400004#LB | uint32   | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #LB |
| 1!400004#BB | uint32   | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #BB |
| 1!400004#LL | int32    | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #LL |
| 1!400004#BL | float    | 指站号为 1，保持寄存器区域，地址为 400004，字节顺序为 #BL |
| 1!300001.10  | String  | 指站号为1，输入寄存器区域，地址为 300001，字符长度为 10，字节顺序为 L，即占用的地址为 300001 ～ 300005 |
| 1!300001.10H | String  | 指站号为1，输入寄存器区域，地址为 300001，字符长度为 10，字节顺序为 H，即占用的地址为 300001 ～ 300005 |
| 1!300001.10L | String  | 指站号为1，输入寄存器区域，地址为 300001，字符长度为 10，字节顺序为 L，即占用的地址为 300001 ～ 300005 |
| 1!400001.10  | String  | 指站号为1，保持寄存器区域，地址为 400001，字符长度为 10，字节顺序为 L，即占用的地址为 400001 ～ 400005 |
| 1!400001.10H | String  | 指站号为1，保持寄存器区域，地址为 400001，字符长度为 10，字节顺序为 H，即占用的地址为 400001 ～ 400005 |
| 1!400001.10L | String  | 指站号为1，保持寄存器区域，地址为 400001，字符长度为 10，字节顺序为 L，即占用的地址为 400001 ～ 400005 |
| 1!400001.10D | String  | 指站号为1，保持寄存器区域，地址为 400001，字符长度为 10，字节顺序为 D，即占用的地址为 400001 ～ 400010 |
| 1!400001.10E | String  | 指站号为1，保持寄存器区域，地址为 400001，字符长度为 10，字节顺序为 E，即占用的地址为 400001 ～ 400010 |

## 应用场景

您可通过 PeakHMI Slave Simulators 模拟 Modbus 设备测试到 Neuron 的连接，具体步骤，见[快速入门](../../../quick-start/quick-start.md)。

您也可通过 Modbus Slave 从机模拟器测试到 Neuron 的连接，具体步骤，见 [Modbus Salve 模拟器](./example/modbus-slave/modbus-slave.md)。

## 数据监控

完成点位的配置后，您可点击 **监控** -> **数据监控**查看设备信息以及反控设备，具体可参考[数据监控](../../../admin/monitoring.md)。
