Modbus

**Modbus**はModicon社が1979年、同社のプログラマブルロジックコントローラ (PLC) 向けに策定したシリアル通信プロトコルである。産業界におけるデ・ファクト標準の通信プロトコルとなり、現在では産業用電子機器を接続する最も一般的手段となっている。Modbusが他の通信プロトコルより普及した理由は以下の通りである。
* 仕様が公開されていて利用が無料である
* 実装が比較的容易である
* データをそのまま転送でき、ベンダーに多くの制約を設けていない

Modbusは同じネットワークに多数の機器を接続して通信可能である。例えば、温度と湿度を測定するシステムがその測定結果をコンピュータと通信するといった使い方がある。ModbusはSCADAシステムにおける監視コンピュータと遠隔端末装置 (RTU) の接続に使われることが多い。

## プロトコルのバージョン
Modbusプロトコルには、シリアルポート向けバージョン、イーサネットその他のインターネット・プロトコル・スイートをサポートしたネットワーク向けバージョンがある。

Modbus機器の多くはシリアルのEIA-485物理層上で通信する。

シリアルコネクションは2種類あり、数値データの表現が異なり、プロトコルの詳細も若干異なる。Modbus RTU はデータのコンパクトなバイナリ表現である。Modbus ASCII は人間が読める表現で、より冗長である。これらはいずれもシリアル通信を用いる。RTUフォーマットではコマンドやデータに巡回冗長検査 (CRC) チェックサムが付き、ASCIIフォーマットは水平冗長検査 (LRC) チェックサムを用いる。各ノードはRTUを使うかASCIIを使うかが設定されており、異なるフォーマット同士では通信できない。

TCP/IP（例えばイーサネット）上のコネクションでは、より新しい Modbus/TCP を使う。こちらではチェックサムは下位層に任せている。

データモデルとファンクションコールはこれら3種類のプロトコルで同一である。カプセル化方式だけが異なる。

拡張バージョンである Modbus Plus (Modbus+ or MB+) もあるが、Modicon 社の独自仕様である。高速なHDLC風トークンローテーションを扱うために専用のコプロセッサを必要とする。撚り線対で1Mbit/sの通信を行い、レベルトリガではなくエッジトリガで通信する。Modbus Plus をコンピュータに接続するには特殊なインタフェースが必要であり、一般にISAやPCIやPCMCIAの専用カードを使う。

## 通信と機器
Modbusを使って通信する各機器には一意なアドレスが与えられる。シリアルおよびMB+のネットワークでは、マスターとされたノードだけがコマンドを発行できる。イーサネットでは任意のノードがコマンドを発行できるが、一般に唯一のマスターノードがコマンドを発行する。Modbusコマンドには、それを実行させたい機器のModbusアドレスが含まれている。指定された機器だけがそのコマンドを実行し、他の機器はたとえ受信しても何もしない（ただし、ブロードキャスト型のコマンドもある）。Modbusコマンドにはチェック情報が含まれ、受信したコマンドが壊れていないことを確認できる。基本Modbusコマンドは、RTUに対してそのレジスタの1つの値を変更させたり、I/Oポートの読み書きをさせたりできる。さらに機器に対してそのレジスタ内の値を送り返させることができる。

Modbusは非常に単純なプロトコルでコピー規格もあるため、これをサポートするモデムやゲートウェイは多数存在する。また、Modbusプロトコル専用の機器も存在する。有線だけでなく無線通信による実装や、SMSやGPRSによる実装もある。そのような設計では、高レイテンシとタイミングを考慮する必要がある。

## 実装
ほとんど全ての実装において、公式の規格からの逸脱が見られる。したがって、異なるベンダーの機器同士では正しく通信できない可能性がある。違いがよく見られるのは以下の点である。
* データ型
** 浮動小数点(IEEE)
** 32ビット整数
** 8ビットデータ
** 混合データ型
** 整数内のビットフィールド
** データと整数を変換する乗数 10, 100, 1000, 256 ...
* プロトコル拡張
** 16ビットスレーブアドレス
** 32ビットデータサイズ（1アドレス = 32ビットの返却データ）
** ワードを入れ替えたデータ

## 制限
* Modbus は1970年代末にプログラマブルロジックコントローラと通信するために設計された。そのため、その当時のPLCが解釈できるデータ型しかなく、大規模ライブラリのオブジェクトはサポートされていない。
* データオブジェクトを説明する標準的手段が存在しない。例えば、レジスタ値が30度から175度の温度を表しているといった情報である。
* Modbusはマスタースレーブ型プロトコルであるため、機器が例外事象を報告する手段がない（ただし、イーサネット TCP/IP 上では open-mbus という例外を扱えるものもある）。したがって、マスターノードが定期的に各機器の状態を問い合わせる必要がある（状態を問い合わせると言っても、そのようなコマンドがあるわけではなく、単にデータを読み取って異常がないかチェックするだけである）。これは低速な無線リンクなどバンド幅が貴重なネットワークでは、バンド幅の無駄遣いになる。
* Modbusは1つのデータリンク内で最大247個のアドレスまでしか扱えない。このため、1つのマスターステーションに接続できる機器の台数が制限される（ただし、イーサネット TCP/IP ではその限りではない）。
* Modbusの転送は連続的でなければならない。そのため、遠隔通信機器はデータをバッファリングし転送にギャップが生じないようにする必要がある。

## 脚注

## 外部リンク
* プロトコルの詳細
* Modbus-IDA サイト
* MBX Driver サイト - 標準Modbus, Modbus Plus, Modbus/TCP のドライバソフトウェア、Cyberlogic と Schneider Electric
* Java開発者のためのプロトコル解説
* Answers to the 14 Most Frequently Asked Modbus Questions
* Modbusについての基本的解説
* CommServer OPC Server for Modbus
* Modbusプロトコル概説書（日本語） 株式会社エムジー（旧社名：エム・システム技研）

### オープンソース
* libmodbus GNU/Linux 上のC言語向けオープンソースライブラリ。GitHubにはVisual Studio 2008のプロジェクトファイルもある。
* QModBus LinuxおよびWindows用のグラフィカルなModbusマスターアプリケーション
* Free Modbus ASCII/RTU and TCP for microcontrollers C言語。新しいサイトは http://www.freemodbus.org。
* NModbus C#実装
* *(リンク切れ)*blueSCADA Windows用のグラフィカルなModbusマスターアプリケーション
* Protocol::Modbus in Perl 
* Modbus::Client in Perl
* Modbus master for Ruby. パブリックドメインのサンプルコード。他のスクリプト言語に容易に移植可能。
* RModBus. RubyによるModbusプロトコルのフリーな実装
* jamod. JavaによるModbusプロトコルの実装