インターフェース・バス(有線)

Modbus

産業機器で定番の通信プロトコル。

概要

Modbusは1979年にModicon社(現Schneider Electric)がPLC(プログラマブルロジックコントローラ)向けに開発した産業用通信プロトコルです。現在も産業機器における事実上の標準プロトコルとして世界中で使われています。

Modbusはオープン規格として公開されており、特許もライセンス費用も不要です。マスタースレーブ(クライアント/サーバー)構成でシンプルな通信を実現し、RS-485RS-232Cの物理層(Modbus RTU/ASCII)またはTCPネットワーク(Modbus TCP)上で動作します。

PLCと温度調節器・インバーター(周波数変換器)・電力計・センサーユニットなどのフィールド機器を接続するのに最もよく使われます。設定・計測値の読み書き、コイル(ビット)とレジスタ(16ビット整数)というシンプルなデータモデルが特徴です。

歴史・背景

Modbusは1979年にModicon社(旧Gould Electronics)が自社PLCの通信規格として開発しました。当初は独自規格でしたが、シンプルさと実用性が評価されて多くのメーカーに採用され、産業フィールドの標準として普及しました。

1996年にModbus TCP(Ethernet上のModbus)が導入され、イーサネットネットワークでの産業通信にも対応しました。2004年にはModbus-IDEというオープン規格推進団体(現Modbus Organization)が設立され、仕様が正式にオープン化されました。

現在、産業機器のほぼ全カテゴリにModbus対応製品が存在し、ビル管理・エネルギー管理・水処理・製造業など幅広い分野で使われています。

技術仕様

Modbusのバリアント

バリアント物理層フォーマット特徴
Modbus RTURS-485 / RS-232Cバイナリ最も一般的。高効率
Modbus ASCIIRS-485 / RS-232CASCIIテキスト人間可読、通信効率低
Modbus TCPEthernet / TCP/IPバイナリLANで使用
Modbus UDPEthernet / UDPバイナリ低レイテンシ用途

データモデル

Modbusは4種類のデータオブジェクトを定義しています:

オブジェクトアクセスビット幅説明
コイル(Coil)読み書き1ビットデジタル出力(例:リレー状態)
ディスクリート入力(DI)読み取りのみ1ビットデジタル入力(例:スイッチ)
保持レジスタ(HR)読み書き16ビットアナログ出力・設定値
入力レジスタ(IR)読み取りのみ16ビットアナログ入力・計測値

アドレス範囲は0〜65535(機能コードで区別)。Modbusアドレスは1始まりと0始まりで表記が異なる場合があるため注意が必要です(「400001」表記と「40000」のオフセット計算等)。

機能コード(Function Code)

よく使われる機能コード:

コード機能
0x01コイル読み取り(Read Coils)
0x02ディスクリート入力読み取り
0x03保持レジスタ読み取り(最多使用)
0x04入力レジスタ読み取り
0x05単一コイル書き込み
0x06単一レジスタ書き込み
0x0F複数コイル書き込み
0x10複数レジスタ書き込み

エラーレスポンスの場合は機能コードの最上位ビットを1にし(0x83等)、例外コードを返します。

Modbus RTUフレームフォーマット

[スレーブアドレス(1B)][機能コード(1B)][データ(N B)][CRC(2B)]

例:スレーブ1の保持レジスタ40001〜40002を読む
送信: [0x01][0x03][0x00][0x00][0x00][0x02][0xC4][0x0B]
      アドレス=1, FC=03, 開始Reg=0x0000, 個数=2, CRC

応答: [0x01][0x03][0x04][0x01][0xF4][0x00][0x64][CRC2B]
      アドレス=1, FC=03, バイト数=4, Reg1=500(0x01F4), Reg2=100(0x0064)

CRCはCRC-16/ANSIアルゴリズム(多項式0x8005)を使います。

Modbus TCPフレームフォーマット

Modbus TCPはTCP/IP上で動作し、CRCの代わりにMBAP(Modbus Application Protocol)ヘッダーが付加されます:

[トランザクションID(2B)][プロトコルID(2B)=0x0000][データ長(2B)][ユニットID(1B)][機能コード(1B)][データ(N B)]

デフォルトTCPポート: 502

動作原理

マスタースレーブモデル

Modbusはマスタースレーブ(Modbus TCP以降ではクライアント/サーバーとも呼ぶ)のプロトコルです:

  • マスター(クライアント): リクエストを送信。PLCやSCADAシステムが担当
  • スレーブ(サーバー): リクエストに応答。計測器・センサーユニット・インバーターが担当
  • スレーブはマスターのリクエストがないとデータを送信しない(ポーリング方式)
// FreeModbus等のライブラリを使ったModbus RTU実装例(マスター側)

#include "mb.h"         // FreeModbus
#include "mbport.h"

// Modbus RTU初期化(スレーブアドレス1、RS-485、9600bps)
eMBErrorCode err = eMBInit(MB_RTU, 1, 1, 9600, MB_PAR_NONE);
eMBEnable();

// 保持レジスタ読み取りリクエスト送信(FC03)
USHORT regs[10];
UCHAR slave_addr = 1;    // スレーブアドレス
USHORT reg_start = 0;    // 開始レジスタ
USHORT reg_count = 10;   // レジスタ数

// FreeModbusではコールバック関数でレジスタへのアクセスを実装
eMBErrorCode eMBRegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress,
                              USHORT usNRegs, eMBRegisterMode eMode) {
    if (eMode == MB_REG_READ) {
        for (int i = 0; i < usNRegs; i++) {
            *pucRegBuffer++ = (regs[i] >> 8) & 0xFF;
            *pucRegBuffer++ = regs[i] & 0xFF;
        }
    }
    return MB_ENOERR;
}

// メインループで定期的にポーリング
while (1) {
    eMBPoll();  // Modbusイベント処理
    HAL_Delay(1);
}

CRC-16計算

Modbus RTUのCRC計算:

uint16_t calc_modbus_crc(uint8_t *buf, uint16_t len) {
    uint16_t crc = 0xFFFF;
    for (uint16_t i = 0; i < len; i++) {
        crc ^= buf[i];
        for (int j = 0; j < 8; j++) {
            if (crc & 0x0001) crc = (crc >> 1) ^ 0xA001;
            else crc >>= 1;
        }
    }
    return crc;  // LSBファースト(低位バイトを先に送信)
}

用途・ユースケース

Modbusが使われる産業現場:

  • PLCと計測器の接続: 温度調節器・流量計・電力計からModbus RTU(RS-485)でPLCにデータ収集
  • インバーター制御: モーターインバーターの速度設定・運転/停止命令をModbusで送受信
  • 太陽光発電: パワーコンディショナーとデータロガーのModbus通信で発電量モニタリング
  • ビル管理: 空調機器・電力計・環境センサーのデータをBASサーバーがModbus TCPで収集
  • 水処理プラント: 水質センサー・ポンプ制御盤との通信
  • SCADA/HMI: SCADA(監視制御)システムがModbus TCPでフィールド機器を監視・制御

実装・開発のポイント

ライブラリの活用

Modbus実装はゼロから開発せず、実績のあるオープンソースライブラリを使います:

ライブラリ言語特徴
FreeModbusCRTOS対応マイコン向け。FreeRTOS等と連携
libmodbusCLinux/Windowsマスター実装
pymodbusPythonPythonテスト・プロトタイピング
ModbusScope-デバッグ・解析ツール

タイムアウトとレスポンス時間

Modbus RTUでは「3.5文字時間(T3.5)」がフレーム間のサイレント区間です。9600bpsの場合、1文字≈1ms程度なので約3.5msです。マスターはリクエスト送信後、一定時間(標準は500ms〜1秒)待ってタイムアウト処理を行います。

レジスタのデータ型変換

Modbusレジスタは16ビット整数ですが、多くの機器では32ビット浮動小数点数(IEEE 754)を2レジスタで表現します:

// 2レジスタから32ビット浮動小数点数に変換
float modbus_regs_to_float(uint16_t reg_hi, uint16_t reg_lo) {
    uint32_t raw = ((uint32_t)reg_hi << 16) | reg_lo;
    float val;
    memcpy(&val, &raw, sizeof(float));
    return val;
}

他技術との比較

Modbus vs OPC UA

項目ModbusOPC UA
制定年1979年2008年
データモデルシンプル(コイル/レジスタ)複雑・柔軟(オブジェクトモデル)
セキュリティなしTLS・認証・暗号化
対応プロトコルRS-485/EthernetEthernet/Internet
導入コスト低い高い

OPC UAはより高機能で安全なプロトコルですが、Modbusの単純さとレガシー互換性は今も大きな価値があります。

Modbus vs CANopen

CANバス上のCANopenはリアルタイム性に優れ、モーション制御など高速応答が必要な用途に向きます。Modbusはポーリング方式で低速ですが、設定・計測値の読み書きには十分です。

関連用語

参考リンク