Modbus関数コードの完全な解析:基本から高度までの21の標準関数コードの実践ガイド

無料無料技术资料

这篇内容可直接阅读,适合用于基础学习和検索引流。

Modbus関数コードの完全な解析:基本から高度までの21の標準関数コードの実践ガイド

キーワード:Modbus関数コード,Modbus Function Code,Modbus 0 1 0 2 0 3 0 4 0 5 0 6 15 16,Modbusリードレジスタ,Modbus書き込みコイル

コードマスターがスレーブに対して実行する操作(データの読み取りまたは書き込み、操作対象がコイル、ディスクリート入力、ホールドレジスタ、または入力レジスタ)を定義します。各関数コードの目的、メッセージフォーマット、シナリオを理解することは、Modbus 通信をマスターするための基盤です。

Modbusプロトコル仕様V 1.1 b 3をベースに、21の標準機能コード(共通機能コード、ユーザー定義機能コード、予約機能コードを含む)を体系的に解析し、完全なメッセージングサンプルとプログラミング実装を提供し、“熟練したエンジニア”から“真に理解したエキスパート”に移行するのに役立ちます。

Modbusデータモデルと関数コードの関係

Modbus関数コードの完全な解析:基本から高度までの21の標準関数コードの実践ガイド插图
図1:Modbusフィーチャーコードアーキテクチャ-ビットオペレータクラスとレジスタオペレータクラスの完全な分類。

関数コードを掘り下げる前に、Modbusのデータモデルを理解する必要があります。Modbusは4つのデータ領域を定義する。

データ領域アクセスの種類サイズはアドレス範囲典型的な用途
コイル読み取りと書き込み1 bit00001-09999デジタル量出力DO
“入力”rete Inputs読み取り専用1 bit10001-19999数値入力(DI)
レジスターの保持Holding Registers読み取りと書き込み16 bit40001-49999アナログ出力/パラメータ
入力レジスタ読み取り専用16 bit30001-39999アナログ入力(AI)

重要なヒント:実プロトコルメッセージでは,0から始まる“プロトコルアドレス”を用いる.例えば、保持レジスタ40001に対応するプロトコルアドレスは0 x 0000である。この“オフセット1”のデザインは、初心者が最も混同しやすいところです。

2.機能コード分類システム

Modbus関数コードは大きく3つのカテゴリーに分類される。

  • 公開機能コード(1- 6 4、73-99、11 1 - 1 27)Modbus組織によって標準化され、異なるベンダーのデバイス間の相互運用性を保証
  • ユーザー定義機能コード(65- 7 2、100-110):機器メーカーにカスタム実装を任せ、汎用性はない
  • 機能コードの保存:従来の製品(8-11、12-15など)で使用されています。

三、ビット操作機能コードBit Access深度解析

Modbus関数コードの完全な解析:基本から高度までの21の標準関数コードの実践ガイド插图1
図2:4つのビッグデータモデル(コイル/ディスクリート入力/ホールドレジスタ/入力レジスタ)と関数コードの完全なマッピング。

3.1ファンクションコード0x01-リードコイルRead Coils

機能性:スレーブからの連続コイルDOのON/OFF状態を読み取ります。これは最も基本的なビット読み取り操作です。

要求メッセージRTU

駅からの住所|0 x 0 1|開始アドレスが高い|低アドレス開始|高い量の|低ボリュームです|CRCは
例:ステーション1からのコイル0 x 0 0 1 3 ~ 0 x 0 0 3 7(コイル番号20~56、合計37個)の読み取り
0 1 0 1 0 0 13 0 0 25【CD】
→スレーブアドレス=1、ファンクションコード= 0x01、開始アドレス= 0x0013 19、数量= 0x0025 37

メッセージへの応答:

駅からの住所|0 x 0 1| Bytesの数|データは..。| CRCは
0 1 0 1 0 5 CD 6 B 2 0 E 1 B(CRC)
→ 5バイトデータ、CD=1100 1101コイル27-20の

主な制約:

  • 1回の読み取りで最大2,000コイル(0 x 0 7 D0)
  • 応答におけるビットパッキング規則:最初のバイトのLSBが開始アドレスコイルに対応する
  • リクエストの数が8の倍数でない場合、最後のバイトの上位ビットは0で埋められます。

3.2ファンクションコード0x02-ディスクリート入力を読み取りRead Discrete Inputs

機能性:スレーブステーションから連続離散入力(DI)の状態を読み取ります。メッセージ形式は0 x 0 1とまったく同じですが、読み取り専用のディスクリート入力領域を操作します。

0 x 0 1との違い:0 x 01は読み書き可能なコイル(通常は物理 DO)を読み取り、0 x 02は読み取り専用のディスクリート入力(通常はリミットスイッチ、センサ状態などの物理 DI)を読み取ります。

例:ステーション1からのディスクリート入力0 x 0 0 C 4 ~ 0 x 0 0 DB(197~220、合計24個)を読み取る
要求01 02 00 C4 00 18 [CRC]
応答01 02 03 AC DB 35 [CRC]
→ 3バイト、AC=1010 1100、DB=1101 1011、35=0011 0101

3.3ファンクションコード0x05-単一コイルに書き込むWrite Single Coil

機能性:個々のコイルをONまたはOFFにします。これは最も簡単な書き込み操作です。

メッセージのリクエスト:

駅からの住所|0 x 0 5|コイルアドレスHigh| Coil Address Lowシングル|出力が高い。|出力値が低い。|CRCは
出力値0xFF00はON、0x0000はOFF

例スレーブ1のコイル0 x 00AC(No. 173)をONにする
0 1 0 5 0 0 AC FF 00(CRC)

メッセージへの応答:通常のレスポンスはリクエストと完全に一致しています(エコー)。

プログラミング例Python

minimalmodbusのインポート
instr = minimalmod.Instrument/dev/ttyUSB01
instrument.serial.baudrate = 96 00
#単一コイルへの書き込みアドレス0x00 AC = ON
instrument.write_bit 0x00AC 1

3.4ファンクションコード0x0F-複数のコイルを書き込むWrite Multiple Coils

機能性:複数の連続したコイルを一度に書き込む。複数のDOを同時に制御する必要がある場合、0 x 0Fは0 x 0 5を複数回呼び出すよりもはるかに効率的です。

要求メッセージ形式
駅からの住所|0 x 0 F|開始アドレスが高い|低アドレス開始|高い量の|低ボリュームです|Bytesの数|データは..。| CRCは

例:スレーブステーション1のコイル0 x 0 0 1 3 ~ 0 x 0 01 C(20~29、合計10コイル)をそれぞれVrefとします。
20 ON、21 OFF、22 ON、23 ON、24 OFF、25 ON、26 ON、27 OFF、28 ON、29 OFF
2进01 0110 1101 →上位补0 → 0xCD01...ここでは慎重な計算が必要です
実際のメッセージ01 0F 00 13 00 0A 02 CD 01 [CRC]

レジスタ操作関数コード(16ビットアクセス)の詳細解析

4.1機能コード0 x 03 -リード·ホールド·レジスタRead Holding Registers

機能性:连続保持レジスタの値を読み込む。これはModbusで最も頻繁に使用される関数コードの1つではない。ほとんどのデータ収集シナリオでは0 x 03が使用されます。

要求メッセージ形式
駅からの住所|0 x 0 3|開始アドレスが高い|低アドレス開始|レジスタ数が多い。|レジスタ数が少ない|CRCは

例:スレーブ1の保持レジスタ0 x 006B~ 0 x 006D(108~110、计3レジスタ)を読み出す
要求01 03 00 6B 00 03 [CRC]
応答01 03 06 02 2B 00 00 00 64 [CRC]
6バイト= 3レジスタ× 2
→レジスタ108 0x022 B = 555
→レジスタ109 0 x 0000 = 0
→レジスタ110 0x0064 = 100

主な制約:

  • 最大125個のレジスタ(0 x 0 0 7 D)を1回に読み出す
  • 32ビットデータ(float32/int32)を読み込む場合は、レジスタ数が偶数であることを確認します。
  • エンディアンの問題:異なるデバイスがビッグエンディアンまたはリトルエンディアンを使用してマルチバイトのデータを格納することがある

4.2機能コード0 x 0 4-リード入力レジスタRead Input Registers

機能性:連続入力レジスタの値を読み出す。メッセージ形式は0 x 0 3とまったく同じですが、読み取り専用の入力レジスタ領域(ADCサンプル値、センサ生値など)を操作します。

例:ステーション1から入力レジスタ0 x 0 0 08(アドレス9、AIチャネル1)を読み取る
要求01 04 00 08 00 01 [CRC]
応答01 04 02 00 0A [CRC]
入力レジスタ9の値= 0 x 000A = 10

4.3ファンクションコード0x06-単一レジスタへの書き込みWrite Single Register

機能性:単一の保持レジスタに16ビットの値を書き込む。

要求メッセージ形式
駅からの住所|0 x 0 6|レジスタアドレスが高い|レジスタアドレスが低い|書き込み値が高い|書き込み値が低い|CRCは

例:ステーション1の保持レジスタ0 x 00 01から0 x 00 03への書き込み
リクエスト01 06 00 01 00 03 [CRC]
応答01 06 00 01 00 03 [CRC]エコー

プログラミングの例(C#):

//NModbus4ライブラリの使用
Modbus.Deviceの使用
システム.IO.Portsの使用

var port = new SerialPort(“COM3”,96 00,Parity.None,8,StopBits.One);
port.Open;
var master = ModbusSerialMaster. Rport;
master.WriteSingleRegister 1 0x0001 3; //スレーブ1アドレス1値3

4.4ファンクションコード0 x 10 -複数のレジスタを書き込むWrite Multiple Registers

機能性:複数の連続保持レジスタを一度に書き込む。これは、バッチ構成パラメータの効率ツールです。

要求メッセージ形式
駅からの住所|0 x 10|開始アドレスが高い|低アドレス開始|レジスタ数が多い。|レジスタ数が少ない|Bytesの数|データは..。| CRCは

例:スレーブ1のレジスタ0 x 00 01と0 x 00 02にそれぞれ0 x 000Aと0 x 0102を書き込む
要求01 10 00 01 00 02 04 00 0A 01 02 [CRC]
→バイト数=4(レジスタ2個×2)
応答01 10 00 01 00 02 [CRC]
→レスポンスは開始アドレスとレジスタ数のみを返します。

主な制約:

  • 1回の書き込みで最大123個のレジスタ(0 x 0 0 7 B)
  • バイト数は“レジスタ数× 2”になること。
  • 書き込み失敗によりスレーブのパラメータが混乱する可能性があるため、バックアップを先に推奨

5.高度な機能コードの詳細

5.1機能コード0x07-読み取り例外ステータスRead Exception Status

機能性:スレーブステーションの8つの異常状態ビットを高速に読み取ります。これはシンプルで強力な診断機能コードで、リクエストはわずか2バイト(アドレス+機能コード)で、レスポンスはわずか3バイトです。

要求01 07 [CRC]
応答01 07 6D [CRC]
→ステータスバイト0 x 6 D = 0 1 10 1101、各ベンダーが定義したビットの意味

5.2機能コード0x08-診断

機能性:通信リンク診断には16のサブ機能コードがあります。最も一般的な使用法は、スレーブがオンラインでメッセージを正常に処理できるかどうかを検出する“ループバックテスト”(サブファンクションコード0 x 0000)です。

サブ機能コード名前は目的は
0x0000ループテスト要求データのエコー、通信リンクの検証
0x000Aクリアカウンター。通信イベントカウンタをクリア
0x000Bリードバスメッセージ数スレーブ検出されたバス·メッセージの合計数の読み取り
0x000C読み取り通信エラー数CRCチェックエラーの読み取り回数
0x000D読み取り例外エラー数ステーションから返された例外応答の読み取り回数
0x000E読み取りスレーブメッセージ数スレーブで処理されたメッセージの読取り数
0x000F読み取りスレーブ応答数ブロードキャストのために応答が不要なメッセージの読み取り数
回路テスト例
要求01 08 00 00 12 34 [CRC] →サブファンクションコード= 0x0000、データ= 0x1234
レスポンス01 08 00 00 12 34 [CRC] →要求データを完全にエコーする必要があります

5.3機能コード0 x 0B -読み取り通信イベントカウンタ

通信品質を監視するためにスレーブの通信イベントカウンタとステータスワードを返します。

5.4機能コード0 x 16 -マスク書き込みレジスタ

機能性:ANDマスクとORマスクを使用して、単一のレジスタをビット操作します。これはModbusの最も独創的な関数コードの1つで、現在の値を読み取ることなくレジスタの特定のビットをアトミックに変更することができます。

要求メッセージ形式
駅からの住所|0 x 16|アドレスは高い。|アドレスは低い。|マスクが高い。|マスクが低い。|マスクが高い。|マスクが低い。|CRCは

オペレーションロジックResult = Current_Value AND And_Mask OR Or_Mask AND NOT And_Mask

例:レジスタ0 x 00 04のビット0~3をクリアし、ビット4~7 = 0 b 1010を設定します。
ANDマスク= 0xFFF0下位4ビットをクリア、ORマスク= 0x00 A0ビット5とビット7を
要求01 16 00 04 FF F0 00 A0 [CRC]

六、機能コード比較クイックチェック表

関数コードの特徴名前はオペレーショナルオブジェクトオペレーションの種類最大の量。使用頻度は
0x01Read Coilsコイルコイルコイル読書をする。2000★★★★☆
0x02Read Discrete Inputsショップ型入力読書をする。2000★★★☆☆
0x03Read Holding Registersレジスタを保持する。読書をする。125★★★★★
0x04Read Input Registers入力レジスタ。読書をする。125★★★★☆
0x05Write Single Coilコイルコイルコイル書くこと。1★★★☆☆
0x06Write Single Registerレジスタを保持する。書くこと。1★★★★★
0x0FWrite Multiple Coilsコイルコイルコイル書くこと。1968★★★☆☆
0x10Write Multiple Registersレジスタを保持する。書くこと。123★★★★★
0x16Mask Write Registerレジスタを保持する。読み取りと書き込み1★★☆☆☆
0x17Read/Write Multiple Regsレジスタを保持する。読み取りと書き込み125/121★★☆☆☆

関数コード選択決定木

実際の開発では、適切な作業コードを選択することが重要な決定です。選択の意思決定プロセスを次に示します。

  • デジタル出力ステータスが必要ですか?→ 0 x 0 1(コイル)/0 x 0 2(ディスクリート入力)
  • シミュレーションやパラメータが必要ですか?→ 0 x 0 3(保持レジスタ)/0 x 0 4(入力レジスタ)
  • 単一のデジタル出力が必要ですか?→ 0x05
  • 単一パラメータが必要?→ 0x06
  • パラメータが必要?→ 0x10
  • デジタル出力が必要ですか?→ 0x0F
  • 他のビットに影響を与えずにパラメータの一部を変更する必要がありますか?→ 0x16
  • 読み書きを同時に行う必要がありますか(古いパラメータを読み取り、新しいパラメータを書き込むアトミック操作など)。→ 0x17

一般的な落とし穴とベストプラクティス

8.1バイトオーダー·トラップ

Modbusプロトコルは16ビットレジスタでビッグエンディアンを使用することを規定しているが、32ビットデータ(float32など)のエンディアンはプロトコルレベルでは規定されていない。一般的には4つの設定がある。

設定の仕方レジスタ1。レジスタ2。通常のメーカー。
ABCD (Big-Endian)トップ16。背番号は16。シュナイダー、ABB
CDAB (Little-Endian)背番号は16。トップ16。シーメンスS 7 - 200
BADC (Word-Swap Big)バイトスワップ-一部の国産ブランド
DCBA (Word-Swap Little)完全に逆さま。-少数の特殊装備

8.2アドレス(アドレス0)

RTUモードでは、ブロードキャストはスレーブアドレス0を使用します。すべてのスレーブがコマンドを実行しますが、応答は返されません。ブロードキャストは、書き込み機能コード(0 x 0 5、0 x 0 6、0 x 0F、0 x 10)のみサポートされます。

8.3 1回のリクエストは不要。

0 x 0 3は一度に125個のレジスタを読み取ることができるが、一度に多くのレジスタを読み取ることは推奨されない。理由は:

  • 通信遅延の増加(ボーレート96 00で125レジスタで約270ms)
  • CRCチェックエラーの確率を高める
  • 一部のスレーブのメモリ制限によりバッファオーバーフローが発生する可能性がある

推奨事項:単回の読み出しは20~50レジスタ以内に抑え、の小ロットに分けて読み出す。

ケーススタディ:Modbusデータ収集システムの構築

以下は、異なる関数コードを組み合わせる方法を示す典型的なModbusデータ収集フローです。

// C擬似コード- 典型的なModbus取得プロセス
void modbus_acquisition_task void {
    //ステップ1デバイスステータスの読み取りディスクリート入力
    uint8_t di_data[2];
    mod_read_inputs 0x02 di_data 16; //16个のDIを読み込む
    
    //ステップ2アナログ量を読み込む(レジスタ入力)
    uint16_t ai_data[8];
    mod_read_input_regs 0x00 ai_data 8; //8つのAIチャネルを読み込む
    
    //ステップ3ランパラメータの読み込み(レジスタを保持)
    uint16_t params[20];
    mod_read_hing_regs 0x00 params 20;
    
    //ステップ4ビジネスロジックに基づいて制御コマンドを書き込む
    if need_start_motor {
        modbus_write_coil 0 x 0005,1; //モーターを始動
    }
    
    //手順5パラメータを変更する必要がある場合
    if need_set_temp {
        mod__register 0x0010 250; //温度 25.0°C
    }
}

X.サマリー

関数コードはModbusプロトコルの“動詞”であり、マスターがスレーブに対して行うことを定義します。ファンクションコードのメッセージフォーマットと適用シナリオをマスターすることは、Modbus 通信のコア構文をマスターすることに等しい。本稿の関数コードクイックチェックテーブルと決定木は、日常開発のリファレンスマニュアルとして使用し、実際のデバッグで徐々に理解を深めることを提案する。

次の記事では、Modbus RTUとModbus TCPの2つの伝送モードの違いを深く比較し、物理層からアプリケーション層までの適用シナリオと性能特性を包括的に分析します。

関連する読書:Modbus例外応答コードとトラブルシューティング完全マニュアル|Modbus RTUとTCPの比較|Modbus CRC検証原理とプログラミング実装

この資料を実際のプロジェクトに活用しませんか?

ツールセンターで電文解析、CRCチェック、デバイスデバッグを行うか、要件を送信して選定と接続のアドバイスを受けましょう。

エンジニア会員

この記事を実行可能なデバッグ資料に

登録すると、高度な電文解析、資料パックのダウンロード、コード例、エンジニアリングケース、優先技術サポートが利用可能に。実際のプロジェクト納品に最適です。

高度なツール無制限
資料パックとコードパック
完全なエンジニアリングケースライブラリ
優先技術サポート窓口

发表回复

あなたのメールアドレスアドレス不会被公开。 必須項目已用 * 标注