协议

Modbus(TCP/UDP/串口)

qianmoQqianmoQ· 更新于 2026-10-01· 阅读 45 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Modbus 是一种请求/响应协议,最初由 Modicon 于 1979 年发布,如今已成为各类工业设备的事实标准,涵盖 PLC、传感器与电能表等。PLC4X 支持其三种变体:Modbus TCP(modbus-tcp)、Modbus RTU(modbus-rtu)和 Modbus ASCII(modbus-ascii)——其中 RTU 和 ASCII 是"Modbus 串行"的两种线路格式,尽管名称如此,它们同样可以在 TCP 或 UDP 之上运行。

Modbus 是 PLC4X 中使用最广泛的驱动,提供了 C、Go、Java 和 Python 的实现。

支持的操作

名称值描述
read
write
subscribe仅 Java 支持,通过轮询模拟实现。Modbus 没有推送机制,因此订阅本质上是周期性读取,而非设备发起的通知。Go 驱动不支持订阅。

连接字符串

每种 Modbus 变体都有各自的连接字符串,但共享相同的结构:

{modbus-tcp|modbus-rtu|modbus-ascii}:{transport}://{ip-address-or-device}:{port}?{options}

传输、端口和选项字段均为可选。

Modbus TCP 默认使用 tcp 传输:

modbus-tcp:tcp://127.0.0.1:502

Modbus RTU 与 Modbus ASCII 默认使用 serial 传输方式,其寻址目标是串口设备,而不是主机与端口:

modbus-rtu:serial:///dev/ttyUSB0

所有三种变体也都可以通过 tcp 或 udp 运行——这在与串口转 IP 网关或模拟器通信时非常有用——只需显式指定该传输方式,例如 modbus-rtu:tcp://127.0.0.1:5020。

连接字符串选项

Modbus TCP

名称

类型

默认值

是否必需

描述

名称

Modbus TCP

代码

modbus-tcp

Maven 依赖

<dependency>
  <groupId>org.apache.plc4x</groupId>
  <artifactId>plc4j-driver-modbus</artifactId>
  <version>1.0.0</version>
</dependency>

默认传输协议

tcp

支持的传输方式

  • tcp
  • tls
  • tls-psk
  • udp

配置选项:

request-timeout-ms

INT

5000

所有类型请求的默认超时时间。

default-unit-identifier

INT

1

单元标识符或从站 ID,用于标识目标 PLC(在 RS485 上可有多个 Modbus 设备在监听)。默认值为 1。

ping-address

STRING

4x00001:BOOL

简单地址,驱动程序将使用它来检查与给定设备的连接是否处于活动状态(默认为读取保持寄存器 1)。

default-payload-byte-order

STRING

BIG_ENDIAN

用于传输寄存器值的默认编码(默认为 BIG_ENDIAN)。
允许的值有:
- BIG_ENDIAN
- LITTLE_ENDIAN
- BIG_ENDIAN_BYTE_SWAP
- LITTLE_ENDIAN_BYTE_SWAP

自 0.13.0 起

max-coils-per-request

INT

2000

单次请求中可寻址线圈的最大数量(默认为 2000)
自 0.13.0 起

max-registers-per-request

INT

125

单次请求中可寻址的最大寄存器数量(默认为 125)
自 0.13.0 起

传输配置选项:

tcp

tcp.connect-timeout-ms

INT

5000

以毫秒为单位的连接超时时间。

tcp.read-timeout-ms

INT

0

Socket 读取超时时间,单位为毫秒。0 表示不超时。

tcp.write-timeout-ms

INT

0

以毫秒为单位的套接字写入超时时间。0 表示不超时。

tcp.no-delay

BOOLEAN
true
启用 TCP_NODELAY(禁用 Nagle 算法)。

tcp.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tcp.send-buffer-size

INT

81920

以字节为单位的发送缓冲区大小。0 表示使用系统默认值。

tcp.receive-buffer-size

INT

81920

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

tcp.local-address

STRING

用于绑定的本地地址(可选)。若未设置,则使用默认值。

tcp.local-port

整数(INT)

0

要绑定的本地端口(可选)。0 表示使用临时端口。

tls

tls.verify

BOOLEAN

true

tls.ignore-common-name

BOOLEAN

false

接受为与所连接主机不同的其他主机签发的服务器证书。

tls.trust-store

STRING

需要信任的证书的密钥库,替代 JVM 的公共证书颁发机构

tls.trust-store-password

STRING

由 tls.trust-store 指定的信任库的密码

tls.trust-store-type

STRING

PKCS12

由 tls.trust-store 指定的信任库的类型

tls.version

STRING

TLS 协议版本(例如 'TLSv1.2'、'TLSv1.3')。若未设置,则使用 TLS 1.3,若不支持则回退到 TLS 1.2。

tls.keystore

STRING

用于双向 TLS 的客户端证书与私钥所在的密钥库(PKCS12/JKS)路径。

tls.keystore-password

STRING

客户端密钥库的密码。

tls.keystore-type

STRING

密钥库类型(例如 'PKCS12'、'JKS')。默认为 PKCS12。

tls.log-session-keys

BOOLEAN

false

将 TLS 会话密钥以 SSLKEYLOGFILE 格式记录到审计日志中,供 Wireshark 解密使用。

tls.connect-timeout-ms

INT

5000

以毫秒为单位的连接超时时间。

tls.read-timeout-ms

INT

0

套接字读取超时时间,以毫秒为单位。0 表示不超时。

tls.write-timeout-ms

INT

0

Socket 写入超时(毫秒)。0 表示不超时。

tls.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tls.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tls.send-buffer-size

INT

81920

以字节为单位的发送缓冲区大小。0 表示使用系统默认值。

tls.receive-buffer-size

INT(有符号整数)

81920

接收缓冲区大小(字节)。0 表示使用系统默认值。

tls.local-address

STRING

要绑定的本地地址(可选)。如果未设置,则使用默认值。

tls.local-port

INT

0

绑定的本地端口(可选)。0 表示使用临时端口。

tls-psk

tls-psk.psk-identity

STRING

用于 TLS-PSK 身份验证的 PSK 身份字符串。必须与 psk-key 一起使用。

tls-psk.psk-key

STRING

用于 TLS-PSK 身份验证的十六进制字符串形式的 PSK 密钥。必须与 psk-identity 一起使用。

tls-psk.log-session-keys

BOOLEAN

false

将 TLS 会话密钥以 SSLKEYLOGFILE 格式记录到审计日志中,以便 Wireshark 进行解密。

tls-psk.connect-timeout-ms

INT

5000

连接超时(毫秒)。

tls-psk.read-timeout-ms

INT

0

套接字读取超时时间(毫秒)。0 表示不超时。

tls-psk.write-timeout-ms

INT

0

Socket 写入超时时间(毫秒)。0 表示不超时。

tls-psk.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tls-psk.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tls-psk.send-buffer-size

INT

81920

发送缓冲区大小(字节)。0 表示使用系统默认值。

tls-psk.receive-buffer-size

INT

81920

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

tls-psk.local-address

STRING | 绑定的本地地址(可选)。若未设置,则使用默认值。

tls-psk.local-port

INT

0

绑定的本地端口(可选)。0 表示使用临时端口。

udp

udp.local-address

STRING

用于绑定的本地地址。如果未设置,则绑定到所有网络接口。

udp.local-port

INT

0

要绑定的本地端口。0 表示使用临时端口。

udp.read-timeout-ms

整型(INT)

0

以毫秒为单位的套接字读取超时时间。0 表示不超时。

udp.max-packet-size

INT

65507

以字节为单位的最大 UDP 数据包大小。

udp.send-buffer-size

INT

0

发送缓冲区大小(字节)。0 表示使用系统默认值。

udp.receive-buffer-size

INT

0

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

udp.broadcast

布尔型

false

启用 SO_BROADCAST 以发送广播数据包。

udp.reuse-address

BOOLEAN

false

启用 SO_REUSEADDR,以允许绑定到相同的地址/端口。

udp.share-socket

BOOLEAN

false

在多个传输实例之间共享底层 UDP 套接字。设为 true 时,具有相同 localAddress:localPort 的实例将共享一个套接字。这对于多个逻辑连接共用同一个 UDP 端口的协议非常有用。

udp.multicast-ttl

INT(有符号整数)

1

多播包的生存时间(1-255)。

Modbus RTU

名称

类型

默认值

必填

描述

名称

Modbus RTU

代码

modbus-rtu

Maven 依赖

<dependency>
  <groupId>org.apache.plc4x</groupId>
  <artifactId>plc4j-driver-modbus</artifactId>
  <version>1.0.0</version>
</dependency>

默认传输方式

serial

支持的传输方式

  • serial
  • tcp
  • tls
  • tls-psk
  • udp

配置选项:

request-timeout-ms

INT

5000

所有类型请求的默认超时时间。该超时覆盖从提交开始的完整时间(包括排队时间);排队中剩余预算低于一小段调度余量(最多为超时时间的四分之一,且不超过 50 毫秒)的请求将立即失败,而不会被发送出去。

default-unit-identifier

INT

1

用于识别目标 PLC 的单元标识符或从站 ID(在 RS485 上可能有多个 Modbus 设备在监听)。默认值为 1。

ping-address

STRING

4x00001:BOOL

简单地址,驱动程序将使用它来检查与给定设备的连接是否处于活动状态(默认为读取保持寄存器 1)。

default-payload-byte-order

STRING

BIG_ENDIAN

用于传输寄存器值的默认编码(默认为 BIG_ENDIAN)。
允许的取值有:
- BIG_ENDIAN
- LITTLE_ENDIAN
- BIG_ENDIAN_BYTE_SWAP
- LITTLE_ENDIAN_BYTE_SWAP

自 0.13.0 起

max-coils-per-request

INT(整数)

2000

单次请求可寻址的线圈最大数量(默认为 2000)
自 0.13.0 起

max-registers-per-request

INT

125

单次请求中可寻址的最大寄存器数量(默认为 125)
自 0.13.0 起

传输配置选项:

串口

serial.baud-rate

INT

9600

波特率(比特每秒)

serial.data-bits

INT

8

数据位数(5、6、7 或 8)

serial.stop-bits

INT

1

停止位数(1 或 2)

serial.parity

STRING

none(无)

校验位(Parity):none、odd、even、mark、space(不区分大小写)

serial.flow-control

STRING

none

流控制:none、rts-cts、xon-xoff(不区分大小写)

serial.read-timeout-ms

INT

1000

以毫秒为单位的读取超时时间。0 表示阻塞式读取。

serial.write-timeout-ms

INT

1000

以毫秒为单位的写超时时间。

serial.dtr

BOOLEAN

false

启用 DTR(数据终端就绪)信号

serial.rts

BOOLEAN

false

启用 RTS(Request To Send,请求发送)信号

serial.reuse-port

BOOLEAN

false

在多个传输实例之间复用底层串口。设置为 true 时,使用相同端口的实例将共享同一个连接。这对于多个逻辑连接共用一个串口的协议很有用。共享端口的连接必须指向不同的单元 ID;Modbus RTU 响应不携带事务 ID,因此无法区分来自多个连接的同一单元的流量。

serial.interframe-delay

INT

0

帧间延迟,单位为毫秒,适用于需要在消息之间保持间隔的协议。适用于共享端口和专用端口;该间隔从最后一次写入或接收数据时开始计算。

tcp

tcp.connect-timeout-ms

整数 (INT)

5000

以毫秒为单位的连接超时时间。

tcp.read-timeout-ms

INT

0

以毫秒为单位的套接字读取超时时间。0 表示不超时。

tcp.write-timeout-ms

整数(INT)

0

套接字写入超时时间,单位为毫秒。0 表示不超时。

tcp.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tcp.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tcp.send-buffer-size

INT

81920

发送缓冲区大小(字节)。0 表示使用系统默认值。

tcp.receive-buffer-size

整数(INT)

81920

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

tcp.local-address

STRING

要绑定的本地地址(可选)。如未设置,则使用默认值。

tcp.local-port

INT

0

绑定的本地端口(可选)。0 表示使用临时端口。

tls

tls.verify

BOOLEAN

true

tls.ignore-common-name

布尔值

false

接受为与当前所连接主机不同的其他主机所颁发的服务器证书

tls.trust-store

STRING | 要信任的证书的密钥库,用以替代 JVM 的公共受信证书

tls.trust-store-password

STRING

由 tls.trust-store 指定的信任库的密码

tls.trust-store-type

STRING

PKCS12

由 tls.trust-store 指定的信任库的类型

tls.version

STRING

TLS 协议版本(例如 'TLSv1.2'、'TLSv1.3')。如果未设置,则使用 TLS 1.3,并在不支持时回退到 TLS 1.2。

tls.keystore

STRING

包含用于双向 TLS 的客户端证书和私钥的密钥库(PKCS12/JKS)路径。

tls.keystore-password

STRING

客户端密钥库的密码。

tls.keystore-type

STRING

密钥库类型(例如 'PKCS12'、'JKS')。默认为 PKCS12。

tls.log-session-keys

BOOLEAN

false

将 TLS 会话密钥以 SSLKEYLOGFILE 格式记录到审计日志中,供 Wireshark 进行解密使用。

tls.connect-timeout-ms

INT

5000

以毫秒为单位的连接超时时间。

tls.read-timeout-ms

INT(有符号 16 位整数)

0

Socket 读取超时时间(毫秒)。0 表示不超时。

tls.write-timeout-ms

INT

0

Socket 写入超时时间(毫秒)。0 表示不超时。

tls.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tls.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tls.send-buffer-size

INT

81920

发送缓冲区大小(字节)。0 表示使用系统默认值。

tls.receive-buffer-size

INT

81920

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

tls.local-address

STRING

要绑定的本地地址(可选)。若未设置,则使用默认值。

tls.local-port

整型(INT)

0

要绑定的本地端口(可选)。0 表示使用临时端口。

tls-psk

tls-psk.psk-identity

STRING

用于 TLS-PSK 身份验证的 PSK 标识字符串。必须与 psk-key 一起使用。

tls-psk.psk-key

STRING

用于 TLS-PSK 身份验证的十六进制格式 PSK 密钥字符串。必须与 psk-identity 一起使用。

tls-psk.log-session-keys

BOOLEAN

false

以 SSLKEYLOGFILE 格式将 TLS 会话密钥记录到审计日志中,供 Wireshark 解密使用。

tls-psk.connect-timeout-ms

INT

5000

连接超时时间(毫秒)。

tls-psk.read-timeout-ms

INT

0

Socket 读取超时时间,单位为毫秒。0 表示不超时。

tls-psk.write-timeout-ms

INT(有符号整数)

0

Socket 写入超时时间(毫秒)。0 表示不超时。

tls-psk.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tls-psk.keep-alive

布尔值

false

启用 SO_KEEPALIVE。

tls-psk.send-buffer-size

INT

81920

发送缓冲区大小(字节)。0 表示使用系统默认值。

tls-psk.receive-buffer-size

INT

81920

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

tls-psk.local-address

STRING

绑定的本地地址(可选)。若未设置,则使用默认值。

tls-psk.local-port

INT

0

要绑定的本地端口(可选)。0 表示使用临时端口。

udp

udp.local-address

STRING

要绑定的本地地址。若未设置,则绑定到所有接口。

udp.local-port

INT

0

要绑定的本地端口。0 表示使用临时端口。

udp.read-timeout-ms

INT

0

套接字读取超时时间(毫秒)。0 表示不超时。

udp.max-packet-size

INT

65507

以字节为单位的最大 UDP 数据包大小。

udp.send-buffer-size

INT

0

发送缓冲区大小(字节)。0 表示使用系统默认值。

udp.receive-buffer-size

INT

0

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

udp.broadcast

BOOLEAN

false

启用 SO_BROADCAST 以发送广播数据包。

udp.reuse-address

BOOLEAN

false

启用 SO_REUSEADDR,以允许绑定到相同的地址/端口。

udp.share-socket

BOOLEAN

false

在多个传输实例之间共享底层 UDP 套接字。当设置为 true 时,具有相同 localAddress:localPort 的实例将共享同一个套接字。这对于多个逻辑连接共用一个 UDP 端口的协议非常有用。

udp.multicast-ttl

INT

1

组播数据包的生存时间(1-255)。

Modbus ASCII

名称

类型

默认值

必填

描述

名称

Modbus ASCII

代码

modbus-ascii

Maven 依赖

<dependency>
  <groupId>org.apache.plc4x</groupId>
  <artifactId>plc4j-driver-modbus</artifactId>
  <version>1.0.0</version>
</dependency>

默认传输协议

serial

支持的传输方式

  • serial
  • tcp
  • tls
  • tls-psk
  • udp

配置选项:

request-timeout-ms

INT

5000

所有类型请求的默认超时时间。该超时覆盖从提交起的全部时间,包括排队时间;排队中的请求若剩余预算低于一个较小的调度余量(最多为超时时间的四分之一,且不超过 50 毫秒),则会快速失败,而不再发送。

default-unit-identifier

INT

1

单元标识符或从站 ID,用于标识目标 PLC(在 RS485 上可能有多个 Modbus 设备在监听)。默认值为 1。

ping-address

STRING

4x00001:BOOL

简单地址,驱动程序将使用该地址来检查与给定设备的连接是否处于活动状态(默认为读取保持寄存器 1)。

default-payload-byte-order

STRING

BIG_ENDIAN

用于传输寄存器值的默认编码方式(默认为 BIG_ENDIAN)。
允许的取值有:
- BIG_ENDIAN
- LITTLE_ENDIAN
- BIG_ENDIAN_BYTE_SWAP
- LITTLE_ENDIAN_BYTE_SWAP

自 0.13.0 起

max-coils-per-request

INT

2000

单次请求中可寻址线圈的最大数量(默认为 2000)
自 0.13.0 起

max-registers-per-request

INT

125

单个请求中可寻址的最大寄存器数量(默认为 125)
自 0.13.0 起

传输配置选项:

serial

serial.baud-rate

INT

9600

波特率(比特每秒)

serial.data-bits

INT

8

数据位数量(5、6、7 或 8)

serial.stop-bits

INT

1

停止位的数量(1 或 2)

serial.parity

STRING

none

校验位(Parity):none、odd、even、mark、space(不区分大小写)

serial.flow-control

STRING

none

流控制:none、rts-cts、xon-xoff(不区分大小写)

serial.read-timeout-ms

INT

1000

以毫秒为单位的读取超时时间。0 表示阻塞式读取。

serial.write-timeout-ms

INT

1000

写入超时时间,单位为毫秒。

serial.dtr

BOOLEAN

false

启用 DTR(数据终端就绪)信号

serial.rts

BOOLEAN

false

启用 RTS(Request To Send,请求发送)信号

serial.reuse-port

BOOLEAN

false

在多个传输实例之间复用底层串口。当该值为 true 时,使用同一端口的实例将共享同一条连接。这适用于多个逻辑连接共享一个串口的协议。共享端口的连接必须指向不同的单元 ID;Modbus RTU 响应不携带事务 ID,因此无法区分来自多个连接的同一单元的流量。

serial.interframe-delay

INT(有符号 16 位整数)

0

帧间延迟(毫秒),用于需要在消息之间保持间隔的协议。适用于共享端口和专用端口;间隔从最后一次写入或接收数据时开始计算。

tcp

tcp.connect-timeout-ms

INT

5000

连接超时时间,单位为毫秒。

tcp.read-timeout-ms

INT

0

Socket 读取超时时间,单位为毫秒。0 表示不超时。

tcp.write-timeout-ms

INT

0

Socket 写入超时时间(毫秒)。0 表示不超时。

tcp.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tcp.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tcp.send-buffer-size

INT

81920

以字节为单位的发送缓冲区大小。0 表示使用系统默认值。

tcp.receive-buffer-size

INT

81920

以字节为单位的接收缓冲区大小。0 表示使用系统默认值。

tcp.local-address

STRING

要绑定的本地地址(可选)。如果未设置,则使用默认值。

tcp.local-port

INT

0

要绑定的本地端口(可选)。0 表示使用临时端口。

tls

tls.verify

BOOLEAN

true

tls.ignore-common-name

BOOLEAN

false

接受为与所连接主机不同的其他主机签发的服务器证书

tls.trust-store

STRING

要信任的证书密钥库,替代 JVM 的公共权威证书

tls.trust-store-password

STRING

由 tls.trust-store 指定的信任库(trust store)的密码

tls.trust-store-type

STRING

PKCS12

由 tls.trust-store 指定的信任库的类型

tls.version

STRING

TLS 协议版本(例如 'TLSv1.2'、'TLSv1.3')。如果未设置,则使用 TLS 1.3,并在不支持时回退到 TLS 1.2。

tls.keystore

STRING

用于双向 TLS 的密钥库(PKCS12/JKS)路径,其中包含客户端证书和私钥。

tls.keystore-password

STRING

客户端密钥库的密码。

tls.keystore-type

STRING

密钥库类型(例如 'PKCS12'、'JKS')。默认为 PKCS12。

tls.log-session-keys

BOOLEAN

false

将 TLS 会话密钥以 SSLKEYLOGFILE 格式记录到审计日志中,供 Wireshark 解密使用。

tls.connect-timeout-ms

INT

5000

连接超时时间,单位为毫秒。

tls.read-timeout-ms

INT(整数)

0

Socket 读取超时时间(毫秒)。0 表示不超时。

tls.write-timeout-ms

INT

0

套接字写入超时时间,单位为毫秒。0 表示不超时。

tls.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tls.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tls.send-buffer-size

INT(整型)

81920

发送缓冲区大小(字节)。0 表示使用系统默认值。

tls.receive-buffer-size

整数(INT)

81920

以字节为单位的接收缓冲区大小。设置为 0 表示使用系统默认值。

tls.local-address

STRING

要绑定的本地地址(可选)。如未设置,将使用默认值。

tls.local-port

INT

0

绑定的本地端口(可选)。0 表示使用临时端口。

tls-psk

tls-psk.psk-identity

STRING

用于 TLS-PSK 身份验证的 PSK 身份字符串。必须与 psk-key 一起使用。

tls-psk.psk-key

STRING

用于 TLS-PSK 身份验证的十六进制字符串形式的 PSK 密钥。必须与 psk-identity 一起使用。

tls-psk.log-session-keys

BOOLEAN

false

将 TLS 会话密钥以 SSLKEYLOGFILE 格式记录到审计日志中,供 Wireshark 解密使用。

tls-psk.connect-timeout-ms

INT

5000

连接超时时间(毫秒)。

tls-psk.read-timeout-ms

INT

0

以毫秒为单位的套接字读取超时时间。0 表示不设置超时。

tls-psk.write-timeout-ms

INT

0

Socket 写入超时时间,单位为毫秒。0 表示不超时。

tls-psk.no-delay

BOOLEAN

true

启用 TCP_NODELAY(禁用 Nagle 算法)。

tls-psk.keep-alive

BOOLEAN

false

启用 SO_KEEPALIVE。

tls-psk.send-buffer-size

INT

81920

发送缓冲区大小(字节)。0 表示使用系统默认值。

tls-psk.receive-buffer-size

INT

81920

以字节为单位的接收缓冲区大小。设置为 0 时使用系统默认值。

tls-psk.local-address

STRING

要绑定的本地地址(可选)。若未设置,则使用默认值。

tls-psk.local-port

INT

0

要绑定的本地端口(可选)。0 表示使用临时端口。

udp

udp.local-address

STRING

绑定的本地地址。若未设置,则绑定到所有网络接口。

udp.local-port

INT

0

绑定的本地端口。设置为 0 时使用临时端口。

udp.read-timeout-ms

INT

0

Socket 读取超时时间(毫秒)。0 表示不超时。

udp.max-packet-size

INT

65507

以字节为单位的 UDP 数据包最大大小。

udp.send-buffer-size

INT

0

发送缓冲区大小(字节)。设置为 0 表示使用系统默认值。

udp.receive-buffer-size

INT

0

接收缓冲区大小(字节)。0 表示使用系统默认值。

udp.broadcast

BOOLEAN

false

启用 SO_BROADCAST 以发送广播数据包。

udp.reuse-address

BOOLEAN

false

启用 SO_REUSEADDR,以允许绑定到同一地址/端口的多个绑定。

udp.share-socket

BOOLEAN

false

在多个传输实例之间共享底层 UDP 套接字。设置为 true 时,localAddress:localPort 相同的实例将共享同一个套接字。这对于多个逻辑连接共用一个 UDP 端口的协议非常有用。

udp.multicast-ttl

INT

1

多播包的生存时间(1-255)。

标签地址

寻址功能在 C、Go、Java 和 Python 中均有实现。关于各实现的具体支持情况,请参阅协议支持矩阵。

通用格式

通常,所有 Modbus 地址都具有如下格式:

{memory-Area}{start-address}[{selection}]:{data-type}{name-value-tag-options}

若省略选择部分,则读取单个元素。方括号中的选择部分采用共享的数组记法——单个索引、闭区间范围,以及可选的数组 声明下界。参见 数组寻址,了解全部形式以及本驱动所能表达的内容。

若省略数据类型部分,则线圈(Coils)与离散输入(Discrete Inputs)默认为 BOOL,输入寄存器、保持寄存器与扩展寄存器默认为 INT。若省略 name-value-tag-options 部分,则表示不进行任何配置微调。

此外,address 还可以包含标签配置:

{unit-id: 123}

指定此值将覆盖连接字符串中指定的 default-unit-identifier 参数的值。

{byte-order: 'LITTLE_ENDIAN'}

通过此设置,可以按标签(per-tag)覆盖默认字节序。如果未提供,则使用连接字符串中的 default-payload-byte-order;若也未提供,则使用 BIG_ENDIAN。

Java 将 plc4x 风格的地址(coil:、discrete-input:、input-register:、holding-register:、extended-register:)限制为最多 9 位数字;Go 的模式则没有限制,因此例如 coil:1234567890 会被 Go 接受而被 Java 拒绝。本页记录的是 Java 语法——关于此重构,请参见 Java/Go 地址分歧报告中的 modbus 条目。

存储区

Modbus 规范中定义了若干存储区。

  • 离散输入区
  • 线圈区
  • 输入寄存器区
  • 保持寄存器
  • 扩展寄存器区
名称存储区别名描述位宽权限起始地址
离散输入discrete-input: 或 1 或 1x布尔输入值,通常表示 PLC 的二进制输入1只读1
线圈coil: 或 0 或 0x布尔值,通常表示 PLC 的二进制输出1读/写1
输入寄存器input-register: 或 3 或 3x短整型输入值,通常表示 PLC 的模拟输入16只读1
保持寄存器holding-register: 或 4 或 4x短整型值,通常表示 PLC 的模拟输出16读/写1
扩展寄存器extended-register: 或 6 或 6x短整型值,16读/写0

最初的 Modbus 格式允许为离散输入、线圈、输入寄存器和保持寄存器指定最多 10000 个地址。后来这一限制被放宽,每个存储区(扩展寄存器区除外)内允许最多 65536 个地址。使用长地址格式,例如 input-registers:1 时,可以指定 1 到 65535 之间的地址。使用较短的版本时有两种格式可用,即 30001 和 300001。其中较短的格式 3XXXX 限定在 30001 到 39999 之间,而较长的格式 3XXXXX 限定在 300001 到 365535 之间。这些存储区的起始地址均为 1。

地址从 1 开始,而传输线上从 0 开始

这是 Modbus 的一个特性,值得特别说明,因为它经常导致差一错误的困惑:Modbus 规范以及几乎所有设备文档都从 1 开始为寄存器和线圈编号,但实际在请求中传输的地址是该编号减去一。

PLC4X 遵循文档中的惯例——你按照设备手册列出的方式书写地址,由驱动程序在发送到传输线之前将其减一:

标签地址线路上的地址含义
coil:10第一个线圈
holding-register:10第一个保持寄存器
holding-register:10099第 100 个保持寄存器

因此,设备手册中标注的“保持寄存器 40001”以 holding-register:1(或 4x00001)进行寻址,而离开 PLC4X 的请求携带地址 0。

扩展寄存器区是例外——在规范中它确实是基于 0 的,因此在该区域不进行减一操作,其最低可用标签地址为 extended-register:1(同时也是线路上的地址 1)。extended-register:0 会被拒绝。

对于扩展寄存器区,可以指定 0-99999 范围内的地址。这些寄存器被映射到长度为 10000 的文件记录。地址 600000 对应文件记录 0 中的第一个地址,地址 610000 则是第二个文件记录中的第一个地址,依此类推。需要注意的是,通常只有 10 个文件记录(600000 至 699999),但规范允许有 65536 个文件记录。使用 extended-register: 格式可以引用所有这些记录,若使用较短的格式,则限制在 699999 以内。与其他存储区不同,该区域在规范中是基于 0 的,因此其地址原样传递;不过最低可用标签地址仍为 extended-register:1。

数据类型

支持以下数据类型

  • BOOL(布尔)
  • SINT(有符号 8 位整数)
  • USINT(无符号 8 位整数)
  • BYTE(无符号 8 位整数)
  • INT(有符号 16 位整数)
  • UINT(无符号 16 位整数)
  • WORD(无符号 16 位整数)
  • DINT(有符号 32 位整数)
  • UDINT(无符号 32 位整数)
  • DWORD(无符号 32 位整数)
  • LINT(有符号 64 位整数)
  • ULINT(无符号 64 位整数)
  • LWORD(无符号 64 位整数)
  • REAL(浮点数)
  • LREAL(双精度浮点数)
  • CHAR(字符)
  • WCHAR(2 字节字符)
  • STRING(utf-8)
  • WSTRING(utf-16)
  • TIME(时长,毫秒)
  • LTIME(时长,纳秒)
  • DATE(日期)
  • LDATE(日期)
  • TIME_OF_DAY(一天中的时刻)
  • LTIME_OF_DAY(一天中的时刻)
  • DATE_AND_TIME(日期和时间)
  • LDATE_AND_TIME(日期和时间)
线圈和离散输入各持有一个位,因此仅支持 BOOL。以其他任何数据类型声明的线圈或离散输入标签可被地址解析器接受,但读取会返回响应码 UNSUPPORTED。

读取线圈数组会返回其全部元素:coil:1[0..7]:BOOL 将产生一个包含 8 个值的列表。

示例

若要从地址 20 开始读取 10 个保持寄存器并解析为无符号整数,以下示例均为有效。

  • holding-register:20[0..9]:UINT
  • 400020[0..9]:UINT
  • 4x00020[0..9]:UINT
  • 40020[0..9]:UINT
  • 4x0020[0..9]:UINT

若要读取地址 5678 处的 1 个保持寄存器,以下示例均为有效。

  • holding-register:5678
  • 405678
  • 4x05678
  • 45678
  • 4x5678

若要读取单元 10 中地址 5678 处的 1 个保持寄存器,以下示例均为有效。

  • holding-register:5678{unit-id: 10}
  • 405678{unit-id: 10}
  • 4x05678{unit-id: 10}
  • 45678{unit-id: 10}
  • 4x5678{unit-id: 10}

若要从地址 50 开始读取 10 个扩展寄存器,以下示例均为有效。

  • extended-register:50[0..9]
  • 600050[0..9]
  • 6x00050[0..9]
  • 60050[0..9]
  • 6x0050[0..9]

这对应于文件记录 1 中的地址 50-59。

要从地址 9995 开始读取 10 个扩展寄存器,以下示例是有效的。

  • extended-register:9995[0..9]
  • 609995[0..9]
  • 6x09995[0..9]
  • 69995[0..9]
  • 6x9995[0..9]

这对应于文件记录 1 中的地址 9995-9999 以及文件记录 2 中的地址 0-5。请注意,该请求在 Modbus 协议中会被拆分为 2 个子请求。

注意事项与提示

大多数内存区域从地址 1 开始,唯独扩展寄存器区域从 0 开始。在通过 Modbus 协议发送时,这两者都会被映射为 0x0000。

输入寄存器、保持寄存器和扩展寄存器由 16 位寄存器组成,而离散输入和线圈区域由位组成。

支持以下 Modbus 功能码:-

  • 0x01(读线圈)
  • 0x02(读离散输入)
  • 0x03(读保持寄存器)
  • 0x04(读输入寄存器)
  • 0x05(写单个线圈)
  • 0x06(写单个寄存器)
  • 0x0F(写多个线圈)
  • 0x10(写多个寄存器)
  • 0x14(读文件记录)(扩展寄存器读取)
  • 0x15(写文件记录)(扩展寄存器写入)

评论

登录后参与评论

正在加载评论…