
Modbus RTU协议説明
Modbus是基于主从構造的通信プロトコル。它使用RS-485, RS-422, RS-232接口,以及Ethernet TCP/IP网络(Modbus TCPProtocol)进行データ传输。
Modbus RTUメッセージ包括:
- SlaveIDデバイス的アドレス
- function code
- 依赖于機能コード的特殊データ
- CRC-16(Modbus)
構造如下:
SlaveID function code 特殊データ CRC16
もし你去掉SlaveIDアドレス和CRC-16(Modbus),你将得到PDU(协议データユニット)。
SlaveID是デバイス的アドレス,可以从0到247之间選択值。值得注意的是,从248到255的アドレス是保留的。
モジュール中的データストア在四个表中,其中2つ是読み取り専用的,另外2つ是読み書き的。每个表可以容纳9999个值。
以下是表的总结:
- 离散出力コイル (DO):読み書き;Register number1-9999;HEXアドレス範囲0000到270E
- ショップ型入力触点 (DI):読み取り専用;Register number10001-19999;HEXアドレス範囲0000到270E
- 模拟入力レジスタ。 (AI):読み取り専用;Register number30001-39999;HEXアドレス範囲0000到270E
- 模拟出力レジスタを保持する。 (AO):読み書き;Register number40001-49999;HEXアドレス範囲0000到270E
每个表都有一1つのレジスタ号(例如AO的40001),它对应于一アドレスはこちら。(例如0000)。这种差异被称为"偏移"。表的オフセットの量分别为1, 10001, 30001和40001。
以一个例子説明:从40108到40110レジスタ为デバイスアドレス17取得AI值的Modbus RTUリクエスト如下:
11 03 006B 0003 7687
这个分解如下:
11:SlaveIDDevice address(十进制中的17或HEX中的11)03:function code006B:第一1つのレジスタ的アドレス(計算为40108-40001 = 107,这是HEX中的6B)0003:所需的レジスタの数(从40108到40110取得三1つのレジスタ)7687:CRC check和
Modbus RTU从デバイス会回复:
11 03 06 AE41 5652 4340 49AD
这转化为:
- Device address:
11(或十进制中的17) - function code:
03 - バイト计数(表示后面跟随6バイト):
06 - 登録值AO0、AO1和AO2作为两バイトオーダー列
- CRC值由
49AD给出
模拟出力レジスタ的值可以経由多种方式解释,例如:
- 作为16ビット符号なし整数(範囲0至65535)
- 作为16ビット符号付き整数(範囲-32768至32767)
- 作为2つ文字的ASCIIストリング·ストリング
- 作为离散开/关值(0或1)
- 作为32ビット符号なし整数(範囲0到4,294,967,295)
- 作为32ビット符号付き整数(範囲-2,147,483,648至2,147,483,647)
- 作为32位单精度IEEE浮動小数点数(範囲1.2×10^−38至3.4×10^+38)
- 作为四文字ASCIIストリング·ストリング

Modbus RTU命令是什么?
以下是用于読み取り和写入Modbus RTUレジスタ的代码表。
| 功能代码 | 功能操作 | data type | アクセスタイプ |
|---|---|---|---|
| 01 (0x01) | readDO | 离散出力コイルの状態 | read |
| 02 (0x02) | readDI | ショップ型入力ステータス | read |
| 03 (0x03) | readAO | レジスタを保持する。 | 16位 |
| 04 (0x04) | readAI | 入力レジスタ。 | 16位 |
| 05 (0x05) | 写入一个DO | 强制单コイル | 离散 |
| 06 (0x06) | 写入一个AO | 预设单レジスタ | 16位 |
| 15 (0x0F) | 多DO写入 | 强制多コイル | 离散 |
| 16 (0x10) | 多AO写入 | 预设多レジスタ | 16位 |
如何送信Modbus RTU命令来読み取り离散出力?Command0x01
此命令用于読み取りDO数字輸出した。值。
PDUリクエスト指定第一个DOレジスタ的開始アドレス和后续所需的DO值数量。在PDU中,DO值从零开始寻址。
レスポンス中的DO值为一バイト単位。,对应位的值。
位值定义为1 = ON,0 = OFF。
第一个データバイト的低位包含在リクエスト中指定アドレス的DO值。其余的DO值按照增加的值到バイト的最高值。即从右到左。
もしリクエスト的DO值少于八个,则レスポンス中的其余位将填充为零(从低バイト数到ハイバイト的方向)。バイト计数进一步表示レスポンス中データ完全に。Bytesの数。
一个从20到56的DO查询サンプル,针对デバイス的SlaveIDaddress17。第一1つのレジスタ的アドレス将是0013十六进制=19,因为帐户是从0アドレス始まりました。(0014十六进制=20, -1零偏移=我们得到0013十六进制=19)。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 01 | 功能代码 | 01 | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 05 | もっと見る的Bytesの数 |
| 13 | 第一个レジスター·アドレス低バイト数 | CD | DO 27-20的レジスタの値 (1100 1101) |
| 00 | レジスタの数ハイバイト | 6B | DO 35-28的レジスタの値 (0110 1011) |
| 25 | レジスタの数低バイト数 | B2 | DO 43-36的レジスタの値 (1011 0010) |
| 0E | CRC-16(Modbus) | 0E | DO 51-44的レジスタの値 (0000 1110) |
| 84 | CRC-16(Modbus) | 1B | DO 56-52的レジスタの値 (0001 1011) |
| 45 | CRC-16(Modbus) | ||
| E6 | CRC-16(Modbus) | ||
| DO 27-20的出力ステータス表示为バイトCD十六进制值,或在二进制系统中为1100 1101。 |
在レジスタDO 56-52中,右边リクエスト了5位,其余的位填充为零以得到完全的バイト(0001 1011)。
| 通道 | - | - | - | DO 56 | DO 55 | DO 54 | DO 53 | DO 52 |
|---|---|---|---|---|---|---|---|---|
| 位 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
| hexadecimal | 1B |
如何送信Modbus RTU命令来読み取り数字入力?Command0x02
此命令用于読み取り数字入力DI的值。
从レジスタ# 10197到10218的DIリクエストサンプル,针对デバイス的SlaveIDaddress17。第一1つのレジスタ的アドレス将是00C4十六进制=196,因为帐户是从0アドレス始まりました。。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 02 | 功能代码 | 02 | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 03 | もっと見る的Bytesの数 |
| C4 | 第一个レジスター·アドレス低バイト数 | AC | DI 10204-10197的レジスタの値 (1010 1100) |
| 00 | レジスタの数ハイバイト | DB | DI 10212-10205的レジスタの値 (1101 1011) |
| 16 | レジスタの数低バイト数 | 35 | DI 10218-10213的レジスタの値 (0011 0101) |
| BA | CRC-16(Modbus) | 20 | CRC-16(Modbus) |
| A9 | CRC-16(Modbus) | 18 | CRC-16(Modbus) |
如何送信Modbus RTU命令来読み取り模拟出力?Command0x03
此命令用于読み取り模拟出力AO的值。
从レジスタ# 40108到40110的AOリクエストサンプル,针对デバイス的SlaveIDaddress17。第一1つのレジスタ的アドレス将是006Bhexadecimal=107,因为帐户是从0アドレス始まりました。。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | ( |
Hex) | 字段名
11 | Device address | 11 | Device address
03 | 功能代码 | 03 | 功能代码
00 | 第一个レジスター·アドレスハイバイト | 06 | もっと見る的Bytesの数
6B | 第一个レジスター·アドレス低バイト数 | AE | #40108的レジスタの値高位
00 | レジスタの数ハイバイト | 41 | #40108的レジスタの値低位
03 | レジスタの数低バイト数 | 56 | #40109的レジスタの値高位
76 | CRC check和 | 52 | #40109的レジスタの値低位
87 | CRC check和 | 43 | #40110的レジスタの値高位
40 | #40110的レジスタの値低位
49 | CRC-16(Modbus)
AD | CRC-16(Modbus)
如何送信Modbus RTU命令来読み取り模拟入力?Command0x04
此命令用于読み取り模拟入力AI的值。
从レジスタ# 30009的AIリクエストサンプル,针对デバイス的SlaveIDaddress17。第一1つのレジスタ的アドレス是0008十六进制=8,因为帐户是从0アドレス始まりました。。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 04 | 功能代码 | 04 | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 02 | もっと見る的Bytesの数 |
| 08 | 第一个レジスター·アドレス低バイト数 | 00 | #30009的レジスタの値高位 |
| 00 | レジスタの数ハイバイト | 0A | #30009的レジスタの値低位 |
| 01 | レジスタの数低バイト数 | F8 | CRC-16(Modbus) |
| B2 | CRC-16(Modbus) | F4 | CRC-16(Modbus) |
| 98 | CRC-16(Modbus) |
如何送信Modbus RTU命令来写入离散出力?Command0x05
此命令用于记录DO数字輸出した。一个值。
值FF 00十六进制将出力設定为ON。
值00 00十六进制将出力設定为OFF。
すべての其他值都无效,且不会影响出力值。
对这样的リクエスト的普通の反応是回声(レスポンス中的重复リクエスト),在DOステータス已更改后戻る。
example,使用デバイス的SlaveIDaddress17的レジスタ# 173的DO记录。レジスター·アドレス为00AChexadecimal=172,因为从0アドレス开始记录。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 05 | 功能代码 | 05 | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 00 | 第一个レジスター·アドレスハイバイト |
| AC | 第一个レジスター·アドレス低バイト数 | AC | 第一个レジスター·アドレス低バイト数 |
| FF | ハイバイト值 | FF | ハイバイト值 |
| 00 | 低バイト数值 | 00 | 低バイト数值 |
| 4E | CRC-16(Modbus) | 4E | CRC-16(Modbus) |
| 8B | CRC-16(Modbus) | 8B | CRC-16(Modbus) |
| DO173出力ステータス已从OFF更改为ON。 |
如何送信Modbus RTU命令来记录模拟出力?Command0x06
此命令用于记录模拟出力AO的一个值。
example,使用デバイス的SlaveIDaddress17的レジスタ# 40002的AO记录。第一1つのレジスタ的アドレス为0001十六进制=1,因为从0アドレス开始记录。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 06 | 功能代码 | 06 | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 00 | 第一个レジスター·アドレスハイバイト |
| 01 | 第一个レジスター·アドレス低バイト数 | 01 | 第一个レジスター·アドレス低バイト数 |
| 00 | ハイバイト值 | 00 | ハイバイト值 |
| 03 | 低バイト数值 | 03 | 低バイト数值 |
| 9A | CRC-16(Modbus) | 9A | CRC-16(Modbus) |
| 9B | CRC-16(Modbus) | 9B | CRC-16(Modbus) |
如何送信Modbus RTU命令来写入多个离散引脚?Command0x0F
此命令用于记录DO数字輸出した。多个值。
example,写入多个DO,从デバイス的SlaveIDaddress17的レジスタ# 20到# 29。レジスター·アドレス为0013十六进制=19,因为从0アドレス开始记录。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 0F | 功能代码 | 0F | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 00 | 第一个レジスター·アドレスハイバイト |
| 13 | 第一个レジスター·アドレス低バイト数 | 13 | 第一个レジスター·アドレス低バイト数 |
| 00 | レジスタの数ハイバイト | 00 | 记录的レジスタの数ハイバイト |
| 0A | レジスタの数低バイト数 | 0A | 记录的レジスタの数低バイト数 |
| 02 | もっと見る的Bytesの数 | 26 | CRC-16(Modbus) |
| CD | DO 27-20的バイト值 (1100 1101) | 99 | CRC-16(Modbus) |
| 01 | DO 29-28的バイト值 (0000 0001) | ||
| BF | CRC-16(Modbus) | ||
| 0B | CRC-16(Modbus) |
答案戻る已记录的レジスタの数。
如何送信Modbus RTU命令来记录多个模拟出力?Command0x10
此命令用于记录模拟出力AO的多个值。
example,记录多个AO,从デバイス的SlaveIDaddress17的レジスタ# 40002和# 40003。第一1つのレジスタ的アドレス为0001十六进制=1,因为从0アドレス开始记录。
| byte | Request | byte | Reply |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 11 | Device address | 11 | Device address |
| 10 | 功能代码 | 10 | 功能代码 |
| 00 | 第一个レジスター·アドレスハイバイト | 00 | 第一个レジスター·アドレスハイバイト |
| 01 | 第一个レジスター·アドレス低バイト数 | 01 | 第一个レジスター·アドレス低バイト数 |
| 00 | レジスタの数ハイバイト | 00 | 记录的レジスタの数ハイバイト |
| 02 | レジスタの数低バイト数 | 02 | 记录的レジスタの数低バイト数 |
| 04 | もっと見る的Bytesの数 | 12 | CRC-16(Modbus) |
| 00 | 40002高位值 | 98 | CRC-16(Modbus) |
| 0A | 40002低位值 | ||
| 01 | 40003高位值 | ||
| 02 | 40003低位值 | ||
| C6 | CRC-16(Modbus) | ||
| F0 | CRC-16(Modbus) |

Modbusリクエスト的エラー
もしデバイス受信到一个リクエスト,但无法処理该リクエスト,该デバイス将以エラー代码进行レスポンス。
レスポンス将包含修改后的功能代码,高位バイト为1。
example:
| 元の值 | 结果值 |
|---|---|
| リクエスト中的功能代码 | レスポンス中的功能エラー代码 |
| 01 (01 hex) 0000 0001 | 129 (81 hex) 1000 0001 |
| 02 (02 hex) 0000 0010 | 130 (82 hex) 1000 0010 |
| 03 (03 hex) 0000 0011 | 131 (83 hex) 1000 0011 |
| 04 (04 hex) 0000 0100 | 132 (84 hex) 1000 0100 |
| 05 (05 hex) 0000 0101 | 133 (85 hex) 1000 0101 |
| 06 (06 hex) 0000 0110 | 134 (86 hex) 1000 0110 |
| 15 (0F hex) 0000 1111 | 143 (8F hex) 1000 1111 |
| 16 (10 hex) 0001 0000 | 144 (90 hex) 1001 0000 |
带有エラー的リクエスト和レスポンスサンプル:
| byte | Request | byte | Response |
|---|---|---|---|
| (Hex) | 字段名 | (Hex) | 字段名 |
| 0A | Device address | 0A | Device address |
| 01 | 功能代码 | 81 | 已更改的功能代码 |
| 04 | 第一个レジスター·アドレスハイバイト | 02 | エラー代码 |
| A1 | 第一个レジスター·アドレス低バイト数 | B0 | CRC-16(Modbus) |
| 00 | レジスタの数ハイバイト | 53 | CRC-16(Modbus) |
| 01 | レジスタの数低バイト数 | ||
| AC | CRC-16(Modbus) | ||
| 63 | CRC-16(Modbus) |
エラー代码説明
01 | 不能処理已接受的功能代码。
02 | リクエスト中指定的データアドレス不可用。
03 | 查询データ字段中包含的值是无效值。
04 | スレーブ尝试执行リクエスト的操作时发生不可恢复的エラー。
05 | スレーブ已接受リクエスト并処理中です。,但需要较长时间。此レスポンス防止マスター生成タイムアウトエラー。
06 | スレーブ正忙于処理命令。マスター在スレーブ暇なとき必须重复メッセージ。
07 | スレーブ无法执行リクエスト中指定的程序功能。使用功能编号13或14的不成功的程序リクエスト戻る此代码。マスター必须从スレーブリクエスト诊断信息或エラー信息。
08 | スレーブ在読み取り扩展内存时检测到奇偶検証エラー。マスター可以重复リクエスト,但通常在这种情况下需要维修。
Leave a Reply