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"になると思います
アドレス40017から2個読み出すときの例
アドレスは4017-40001=16 (0x0010)となって 個数は2(0x0002)なので
0+1+0+3+0+0+1+0+0+0+0+2=7(0x07) を2の補数+1にして"F9" になると思います
(16進では 0x00+0x01+0x00+0x03+0x00+0x00+0x01+0x00+0x00+0x00+0x00+0x02)
アドレス40201から20個読み出すときの例
アドレスは40201-40001=200 (0x00C8)となって 個数は20(0x0014)なので
0+1+0+3+0+0+12+8+0+0+1+4=29(0x1D) を2の補数+1にして"E3" になると思います
(16進では 0x00+0x01+0x00+0x03+0x00+0x00+0x0C+0x08+0x00+0x00+0x01+0x04)
Modbus-RTU
Modbus-RTUはRS-422,RS-485で通信するバイナリのメッセージです
送信メッセージ
| ヘッダ | スレーブアドレス | ファンクション | データ | 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で通信するバイナリのメッセージです
送信メッセージ
| 転送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 | 0x00 0x00 | 0x12 0x34 |
(12) Fetch Communication Event Log
エコーを返す例
受信メッセージ
| ファンクション | バイトカウント | ステータス |
| 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 | ... |
異常レスポンス
受信メッセージ
(03) Read Holding Register実行時にアドレスが無かったとき
ファンクションの最上位ビット
異常時の受信データではファンクションの最上位ビットがONした値で返信されます
異常コード
| 異常コード | 名称 |
| 01 | 不正ファンクション |
| 02 | 不正データアドレス |
| 03 | 不正データ |
アプリケーション
comcom
EtherntのSocket通信を使ってメッセージを送信するアプリケーションです
ModbusTcpMes
ModbusTCPコマンドの作成支援と対応機器にコマンドを送信するアプリケーションです