Modbus

概略

Modbusとは通信プロトコルのひとつで産業用電子機器を接続するときに使われます
ここではModbusのフレームについて簡単な説明をします
このページの最後に通信テスト用のアプリケーションへのリンクがあります
種類
  • Modbus-ASCII
  • Modbus-RTU
  • Modbus-TCP

アドレスについて

Modbusで扱うアドレスは4つの種類があります
種類 アドレス範囲 データ種別
コイル(coil) 1-9999 1bit
入力ステータス(Input Status) 10001-19999 1bit
入力レジスタ(Input Register) 30001-39999 16bit
保持レジスタ(Holding Register) 40001-49999 16bit

メッセージフレーム

Modbus-ASCII
Modbus-ASCIIはRS-422,RS-485で通信する文字列のメッセージです

送信メッセージ

保持レジスタの40001から2個のデータを読み出すメッセージフレーム
ヘッダ スレーブアドレス ファンクション データ LRC フッタ
アドレス 個数
":" "01" "03" "0000" "0002" "FA" CR+LF
1文字 2文字 2文字 4文字 4文字 2文字 2文字

受信メッセージ

ヘッダ スレーブアドレス ファンクション 受信バイト数 データ1 データ2 LRC フッタ
上位 下位 上位 下位
":" "01" "03" "06" "00" "01" "00" "02" "F3" CR+LF
1文字 2文字 2文字 2文字 2文字 2文字 2文字 2文字 2文字 2文字
LRCの計算
スレーブアドレス~データの文字を数値(16進)にして合計して下2桁の2の補数+1とします
上の例だと 0+1+0+3+0+0+0+0+0+0+0+2=6 を2の補数+1にして"FA" になると思います

Modbus-RTU
Modbus-RTUはRS-422,RS-485で通信するバイナリのメッセージです

送信メッセージ

保持レジスタの40001から2個のデータを読み出すメッセージフレーム
ヘッダ スレーブアドレス ファンクション データ CRC フッタ
アドレス 個数
(*1) 0x01 0x03 0x00 0x00 0x00 0x02 0xC4 0x0B (*1)
1byte 1byte 2byte 2byte 2byte (*2)

受信メッセージ

ヘッダ スレーブアドレス ファンクション 受信バイト数 データ1 データ2 CRC フッタ
上位 下位 上位 下位
(*1) 0x01 0x03 0x06 0x00 0x01 0x00 0x02 0x53 0xF2 (*1)
1byte 1 1 1 1 1 1 2
*1) 3.5文字分のサイレントインターバル(無通信時間)
*2) 下位バイトから先に送信
CRCの計算
CRC16の右シフト 初期値=0xFFFF 反転なしでよさそう・・・
計算はこのアプリで計算できます

Modbus-TCP
Modbus-TCPはEthernetで通信するバイナリのメッセージです

送信メッセージ

TCPヘッダより後ろのフレームです
転送ID プロトコルID 転送バイト数 ユニットID ファンクション データ
アドレス 個数
0x00 0x00 0x00 0x00 0x00 0x06 0x01 0x03 0x00 0x00 0x00 0x02
2byte 2byte 2byte 1byte 1byte 2byte 2byte

受信メッセージ

転送ID プロトコルID 転送バイト数 ユニットID ファンクション
 
0x00 0x00 0x00 0x00 0x00 0x07 0x01 0x03
2byte 2byte 2byte 1byte 1byte

受信バイト数 データ1 データ2
上位 下位 上位 下位
0x04 0x00 0x01 0x00 0x02
1byte 1byte 1byte 1byte 1byte


ファンクション

一覧
ファンクション 名称 機能
01 Read Coil Status コイルの読出し
02 Read Input Status 入力ステータスの読出し
03 Read Holding Register 保持レジスタの読出し
04 Read Input Register 入力レジスタの読出し
05 Force Single Coil コイルの書込み
06 Preset Single Register 保持レジスタの書込み
08 Diagnostics 通信の診断
11(0x0B) Fetch Communication Event Counter 通信イベントカウンタ読出し
12(0x0C) Fetch Communication Event Log 通信イベントログ読出し
15(0x0F) Force Multiple Coils 連続した複数のコイルの書込み
16(0x10) Force Multiple Registers 連続した複数のレジスタの書込み
17(0x11) Report Slave ID スレーブ情報読出し

アドレスについて
コイルのアドレスを指定するときに20番地を指定したい場合は20から1引いた19(0x13)を指定します
同様に入力ステータス、保持レジスタ、入力レジスタの指定も-1した数値で指定します

(01) Read Coil Status
コイル1から20個を読み出す例
送信メッセージ
ファンクション アドレス 個数
0x01 0x00 0x00 0x00 0x14

受信メッセージ
ファンクション 受信バイト数 データ1-8 データ9-16 データ17-24
0x01 0x03 0x01 0x00 0x08

ビットの並び
データにはLSB(0ビット)から入り端数は0で埋められます
例)コイル0と20がONの場合 データ1-8は0x01 データ17-24は0x08

(02) Read Input Status
入力ステータス20から20個を読み出す例
送信メッセージ
ファンクション アドレス 個数
0x02 0x00 0x13 0x00 0x14

受信メッセージ
ファンクション 受信バイト数 データ1-8 データ9-16 データ17-24
0x02 0x03 0x01 0x00 0x08


(03) Read Holding Register
保持レジスタ20から3個を読み出す例
送信メッセージ
ファンクション アドレス 個数
0x03 0x00 0x13 0x00 0x03

受信メッセージ
ファンクション 受信バイト数 データ1 データ2 データ3
0x03 0x06 0x00 0x00 0x00 0x01 0x00 0x02


(04) Read Input Register
入力レジスタ20から3個を読み出す例
送信メッセージ
ファンクション アドレス 個数
0x04 0x00 0x13 0x00 0x03

受信メッセージ
ファンクション 受信バイト数 データ1 データ2 データ3
0x04 0x06 0x00 0x00 0x00 0x01 0x00 0x02


(05) Force Single Coil
コイル20をONにする例
送信メッセージ
ファンクション アドレス データ
0x05 0x00 0x13 0xFF 0x00

受信メッセージ
ファンクション アドレス データ
0x05 0x00 0x13 0xFF 0x00

データの指定方法
0x00 0x00 = OFF, 0xFF 0x00 = ON


(06) Preset Single Register
保持レジスタ20を0x1234にする例
送信メッセージ
ファンクション アドレス データ
0x06 0x00 0x13 0x12 0x34

受信メッセージ
ファンクション アドレス データ
0x06 0x00 0x13 0x12 0x34


(08) Diagnostics
エコーを返す例
送信メッセージ
ファンクション 診断サブコード データ
0x08 0x00 0x00 0x12 0x34

受信メッセージ
ファンクション 診断サブコード データ
0x08 0x00 0x00 0x12 0x34

診断サブコード
診断サブコード データ 機能
0x00 0x00 0x?? 0x?? エコー
0x00 0x01 0x00 0x00 初期化
0xFF 0x00 イベントログも初期化
0x00 0x02 0x00 0x00 診断レジスタの読出し
0x00 0x04 0x00 0x00 リードオンリーモード
0x00 0x0A 0x00 0x00 カウンタと診断レジスタクリア
0x00 0x0B 0x00 0x00 メッセージ合計読出し
0x00 0x0C 0x00 0x00 CRCエラー数読出し
0x00 0x0D 0x00 0x00 例外レスポンス数読出し
0x00 0x0E 0x00 0x00 受信メッセージ数読出し
0x00 0x0F 0x00 0x00 レスポンスを返さなかったメッセージ数
0x00 0x11 0x00 0x00 スレーブビジー例外レスポンス数
0x00 0x12 0x00 0x00 キャラクタオーバーランカウンタ数


(11) Fetch Communication Event Counter
ステータスワードとイベントカウンタを読み出す例
送信メッセージ
ファンクション
0x0B

受信メッセージ
ファンクション ステータス イベントカウンタ
0x0B 0x00 0x00 0x12 0x34


(12) Fetch Communication Event Log
イベントログを読み出す例
送信メッセージ
ファンクション
0x0C

受信メッセージ
ファンクション バイトカウント ステータス
0x0C 0x08 0x00 0x00

イベントカウンタ メッセージカウンタ イベント0 イベント1
0x12 0x34 0x12 0x34 0x20 0x00


(15) Force Multiple Coils
コイル20から10個のコイルの値を変更する例
書込みデータ(20-29) = 1100 0000 01
送信メッセージ
ファンクション アドレス 個数 バイト数 データ
0x0F 0x00 0x13 0x00 0x0A 0x02 0x03 0x02

データ部分のビットの並び
(20番)1100 0000 01(29番) → データ1byte目(27)0000 0011(20) 2byte目 (36)---- --10(28)

受信メッセージ
ファンクション アドレス 個数
0x0F 0x00 0x13 0x00 0x0A


(16) Preset Multiple Registers
保持レジスタ20から3個の値を変更する例
書込みデータ(20-22) = 0x0001 0x0002 0x0003
送信メッセージ
ファンクション アドレス 個数 バイト数 データ1 データ2 データ3
0x10 0x00 0x13 0x00 0x03 0x06 0x00 0x01 0x00 0x02 0x00 0x03

受信メッセージ
ファンクション アドレス 個数
0x10 0x00 0x13 0x00 0x03


(17) Report Slave ID
スレーブ情報を読み出す例
送信メッセージ
ファンクション
0x11

受信メッセージ
ファンクション 以下はデバイスにより変わります
0x11 ...

異常レスポンス

受信メッセージ
(03) Read Holding Register実行時にアドレスが無かったとき
ファンクション 異常コード
0x83 0x02

ファンクションの最上位ビット
異常時の受信データではファンクションの最上位ビットがONした値で返信されます

異常コード
異常コード 名称
01 不正ファンクション
02 不正データアドレス
03 不正データ

アプリケーション

comcom
comcom EtherntのSocket通信を使ってメッセージを送信するアプリケーションです
ModbusTcpMes
modbustcpmes ModbusTCPコマンドの作成支援と対応機器にコマンドを送信するアプリケーションです