Modbus例外応答コードとトラブルシューティング完全マニュアル:0 1から11までの完全な解析

無料無料技术资料

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

Modbus例外応答コードとトラブルシューティング完全マニュアル:0 1から11までの完全な解析

キーワード:Modbus例外コード、Modbusトラブルシューティング、Modbusエラーコード、Modbus Exception Code、Modbus 通信障害

産業オートメーションの分野では、Modbus 通信の障害はエンジニアにとって最大の頭痛の種の1つです。マスターが要求を行うと、スレーブは通常のデータではなく、通信リンクに問題はないがビジネスロジック層にエラーがあることを示す“例外応答”を返します。各例外コードの意味、トリガー条件、およびトラブルシューティング方法を理解することは、すべてのオートメーションエンジニアにとって必須の科目です。

この記事では、Modbusプロトコル仕様(V 1.1 b 3)から始まり、実際の産業現場の事例と組み合わせて、11の標準例外コードすべてのトリガメカニズム、トラブルシューティングプロセス、ソリューションを深く分析します。Modbusを初めて使う人でも、体系的に知識を整理したい人でも、この記事では実用的なリファレンスを見つけることができます。

Modbus例外応答の基本メカニズム

Modbus例外応答コードとトラブルシューティング完全マニュアル:0 1から11までの完全な解析插图
図1:通常のリクエストフレームと例外応答フレームのフォーマットの比較。例外の場合関数コードは上位1(+0 x 80)であり、その直後に1バイトの例外コードが続く。

1.1正常応答と異常応答

Modbusプロトコルでは、マスタ(Master/Client)がスレーブ(Slave/Server)にリクエストメッセージを送信し、スレーブが処理した後にレスポンスメッセージを返す。すべてが正常な場合、応答の関数コードは要求された関数コードと完全に一致します。

要求[従局アドレス] [コード0x03] [アドレスハイバイト] [アドレスハイバイト] [レジスタ数ハイバイト][レジスタ数ハイバイト] [CRCロー] [CRCハイ]
通常の応答[スレーブアドレス] [ファンクションコード0x03] [バイト数] [データ..] [CRC[低] [CRC高]

スレーブがリクエストを適切に処理できない場合、関数コードの最上位ビット(ビット7)を1に設定し、データ領域に1バイトの例外コードを設定します。つまり、例外機能コード=要求機能コード+0 x 80。例えば、リクエスト関数コード0 x 0 3に例外が発生した場合、レスポンス関数コードは0 x 83になります。

例外応答メッセージ構造(RTUモード)
[スレーブアドレス] [機能コード+0 x 80] [例外コード] [CRC低] [CRC高]

例-存在しないレジスタアドレスを要求
要求01 03 27 10 00 01 [CRC]
例外応答01 83 02 [CRC]  
関数コード0 x 83 = 0 x 0 3 + 0 x 80、例外コード0 x 0 2 =不正なデータアドレス

1.2異常応答の判定ロジック

Modbus例外応答コードとトラブルシューティング完全マニュアル:0 1から11までの完全な解析插图1
図2:通信トラブルシューティングDecision Tree-物理層からアプリケーション層までの体系的な診断プロセス。

Modbus Poll、ModScanなどのデバッグツールでステーションから返されたデータを見ると、例外応答かどうかを判断するのは簡単です。

  1. 応答関数コードが0 x 80(すなわち、上位ビットが1)より大きいかどうかを確認します。
  2. 関数コードが0 x 80の場合、2番目のバイトが例外コードです。
  3. 例外コードルックアップテーブルに基づいてエラーのタイプを決定する

プログラミングの実装では、検出ロジックは次のとおりです。

// C言語の例外応答検出の例
if_function_code 0x80 {
    uint 8_t exception_code = response_data [0];
    switch exception_code {
        case 0x01//不正な機能コード
        case 0x02//不正なデータアドレス
        case 0x03//不正なデータ値
        // ...その他の例外コード処理
    }
}

11の標準異常コードを完全に解析

Modbusプロトコル仕様は11の標準例外コード(0 x 0 1 ~ 0 x 0B)を定義している。以下では、各例外コードの意味、トリガー条件、典型的なシナリオ、およびトラブルシューティング方法を詳しく説明します。

例外コード0x01-不正な機能Illegal Function

Modbus例外応答コードとトラブルシューティング完全マニュアル:0 1から11までの完全な解析插图2
図3:8つの標準異常コードクイックチェックシート-すべての異常の原因と解決策を把握する1つの表。

意味は:スレーブは要求された機能コードをサポートしません。これは最も一般的な例外コードの1つであり、マスターがスレーブが実装していない機能コードを使用する場合に発生します。

典型的なトリガーシナリオ:

  • 範囲外の機能コード:マスターは関数コード0 x 14(読み取りファイルレコード)を送信したが、スレーブは0 x 0 3、0 x 0 4、0 x 0 6、0 x 10のみを実装した。
  • PLCモデルでサポートされていない:一部のローエンドPLCは0 x 0 3と0 x 0 6しかサポートしておらず、0 x 10(複数のレジスタを書き込む)を使用すると0 x 0 1が返される。
  • デバイス構成エラー一部のデバイスのModbus実装では、スイッチを設定して関数コードを有効/無効にし、対応する機能が無効になると0 x 0 1を返します。
  • ゲートウェイ変換の問題:Modbus TCPからRTUへのゲートウェイは特定の機能コードの透過をサポートしない場合がある

チェック手順:

  1. デバイスマニュアルを参照して、スレーブがサポートする機能コードを確認してください。
  2. Modbus Pollなどのツールを使用して関数コードを1つずつテストし、問題を絞り込む
  3. ゲートウェイ/コンバータのファンクションコードフィルタリング構成の確認
  4. 自社開発プログラムを使用する場合、関数コード定数の定義が正しいことを確認する

実際の事例:ある水処理プロジェクトでは、ホストコンピュータが機能コード0 x 17(複数のレジスタの読み取り/書き込み)を使用してシュナイダー PM800電力メーターを操作し、常に例外コード0 x 0 1を返します。PM800は0 x 0 3と0 x 10しかサポートしていません。解決策:最初の0 x 0 3読み取りと0 x 10書き込みの2ステップ操作に分割します。

例外コード0x02 -不正なデータアドレス

意味は:要求されたレジスタアドレスはスレーブに存在しません。これは、デバッグ段階でエンジニアが遭遇する最も一般的な例外コードです。

典型的なトリガーシナリオ:

  • アドレスオフセットエラー:PLCのModbusアドレスは通常0から始まりますが、ホストコンピュータは1から始まるアドレスを設定することができます。
  • レジスタ範囲外:要求の開始アドレス+数がスレーブの最大レジスタ範囲を超えている
  • アドレスマップエラー:異なるアドレスマップテーブルを使用するデバイスもあります(40001は内部アドレス0、1など)。
  • データ型の混乱:32ビット浮動小数点数は2つのレジスタを占有し、1つのレジスタのみを要求するとアウトブレイクが発生する可能性がある。

チェック手順:

  1. 0 x 0 3関数コードを使用して、アドレス0から1つずつ読み取り、有効なアドレス範囲を決定します。
  2. 機器マニュアルのアドレスが“プロトコルアドレス”または“PLCアドレス”であることを確認します。
  3. 32ビットデータの場合は、要求されるレジスタ数が偶数であることを確認します。
  4. メッセージ内のアドレスのサイズサイドエンディアンが正しいかどうかを確認する

例外コード0x03-不正なデータ値Illegal Data Value

意味は:リクエスト内の数値がスレーブの許容範囲外です。これはアドレスの問題ではなく、“値”の問題です。

典型的なトリガーシナリオ:

  • 値が範囲外です温度設定値の範囲は0~100°Cですが、マスターステーションは150を書き込みます。
  • 不正なレジスタ数:0 x 10関数コードの“レジスタ数”フィールドが0であるか、スレーブが一度に処理できる最大値(通常は123)を超えている。
  • バイト数が一致しない:0 x 10関数コードの“バイト数”フィールドが“レジスタ数× 2”と一致しない
  • メッセージ長エラー:メッセージ全体の実際の長さがヘッダで宣言された長さと一致しない

チェック手順:

  1. 0 x 10(複数のレジスタを書き込む)のメッセージ構造を確認する-これは最もエラーが発生しやすいシナリオです。
  2. “バイト数 =レジスタ数× 2”が成立するかを検证する
  3. 書き込み値がデバイスマニュアルに規定された範囲内であることを確認する
  4. 0 x 0 6(単一レジスタに書き込む場合)の場合、書き込み値の範囲(0 x 0000 ~ 0 x FFFF)をチェックします。

例外コード0 x 04 -スレーブデバイス障害Slave Device Failure

意味は:スレーブで要求の処理中に回復不能な内部エラーが発生しました。これは、ステーション自体に深刻な問題があることを示す“黄金油”異常コードです。

典型的なトリガーシナリオ:

  • EEPROM/Flashの書き込みに失敗しましたスレーブから不揮発性ストレージへの構成の書き込みが失敗しました
  • センサーの故障:スレーブ接続のセンサーが破損し、有効な読み取りができない
  • 内部通信障害:スレーブ局内部のマスタチップと周辺機器との通信異常
  • ファイルシステムエラー:ファイル操作に関連する関数コード(0 x 14,0 x 15)でファイルシステム例外が発生しました。

チェック手順:

  1. スレーブデバイスの電源が安定しているかどうかを確認します
  2. スレーブステーションのLEDステータスを確認する通常は障害LEDが表示されます
  3. スレーブの電源オフ再起動の試行
  4. 診断ツールまたはファームウェアのアップグレードについては、機器メーカーに問い合わせる

例外コード0x05-確認Acknowledge

意味は:スレーブはリクエストを受け付けていますが、処理に時間がかかります。これはエラーではなく、“お待ちください”というメッセージです。スレーブは操作を実行しており、処理が完了すると通常の応答が返されます。

典型的なトリガーシナリオ:

  • EEPROMの書き込みに時間がかかる一部のデバイスでは、不揮発性メモリの書き込みに数百ミリ秒かかる場合がある
  • ファームウェアのアップグレード:プログラムメモリへの書き込みに時間がかかる
  • モーターの動作:スレーブは物理的な動作(バルブの開閉など)を実行しています。

プログラミングアドバイス:プライマリ局が例外コード0 x 0 5を受信した後、直ちに再試行またはエラーを報告せず、適切な時間待ってから再ポーリングしてください。ステートマシン処理を推奨します。

//確認応答の非同期処理ステートマシン
enum { IDLE WAITING POLLING }= IDLE;

void modbus_handler uint8_t func uint8_t* data {
    if c 0x80 {
        if data[0] = 0x05 {
            state = POLLING
            start_poll_timer 500; // 500ms後にクエリーを再実行
        }
    }
}

例外コード0 x 0 6-スレーブデバイスがビジー Slave Device Busy

意味は:スレーブは時間のかかるコマンドを処理しており、新しいリクエストに一時的に応答できません。0 x 0 5との違いは、0 x 0 5は“あなたが送ったリクエストを処理しています”、0 x 0 6は“今はリクエストを処理できません”です。

典型的なトリガーシナリオ:

  • スタンドから時間のかかる操作を実行するには:ファームウェアのアップグレード、大量のデータコピーなど
  • スレーブのCPU負荷が高すぎるModbusリクエストをタイムリーに処理できないハードウェア性能の制限
  • スレーブステーションで自己診断中:一部のデバイスは起動時にセルフテストを実行し、その間は通信に応答しない

チェック手順:

  1. プライマリ局のポーリング間隔を適切に増やす(例えば、100msから500msに増やす)
  2. 同時に通信するスレーブ数の削減
  3. スレーブのファームウェアのバージョンを確認して、既知のパフォーマンス問題がないか確認します

例外コード0x07- 否定確認Negative Acknowledge

意味は:スレーブは要求されたプログラム機能を実行できません。これは0 x 0D(プログラミング機能)用に特別に設計された例外コードで、プログラミング要求が拒否されたことを示します。

典型的なトリガーシナリオ:

  • プログラミング要求タイプはサポートされていませんスレーブのプログラミング機能は限られており、特定のプログラミング操作はサポートされていない。
  • 無効なプログラミングパラメータ要求にサポートされていないプログラミングパラメータが含まれています

注意事項:例外コード0 x 0 7はModbusプロトコル仕様V 1.1 b 3で定義されていますが、実際にはほとんどのModbusデバイスは関数コード0 x 0Dを実装していないため、この例外コードは現実にはめったに遭遇しません。

例外コード0x08-メモリパリティエラー Memory Parity Error

意味は:スレーブがファイルレコードを読み出しているときに、メモリパリティエラーが検出された。ファイル操作関数コード(0 x 14、0 x 15)にのみ関連します。

典型的なトリガーシナリオ:

  • ファイルの破損:電源障害などの原因でファイルストレージ領域がデータ破損
  • Flashメモリの劣化:頻繁な書き込みによるFlashストレージユニットの信頼性低下

例外コード0x0A-ゲートウェイパスが使用できないGateway Path Un

意味は:ゲートウェイがターゲットデバイスへの内部通信パスを確立できませんでした。これは通常、ゲートウェイが複数のダウンストリームデバイスを接続している場合に発生します。

典型的なトリガーシナリオ:

  • オフライン機器:ゲートウェイの背後にあるModbus RTUデバイスの電源オフまたは切断
  • ダウンストリームデバイスアドレスエラーゲートウェイは、存在しないスレーブアドレスに転送するように構成されている
  • ゲートウェイ内部ルーティングテーブルエラーゲートウェイのルーティング構成が正しくない

チェック手順:

  1. ゲートウェイダウンストリームデバイスの通信ステータスLEDを確認します
  2. Modbus Pollを使用してダウンストリームデバイスを直接接続し、デバイス自体をトラブルシューティング
  3. ゲートウェイのルーティングテーブル構成の確認
  4. ダウンストリームデバイスのModbusアドレスとボーレート設定の確認

例外コード0x0B-ゲートウェイ·ターゲット·デバイスの応答失敗Gateway Target Device Failed to Respond

意味は:ゲートウェイは通信パスを確立できましたが、ターゲット·デバイスが有効な応答を提供できませんでした。0 x 0 Aとの違い:0 x 0 Aはゲートウェイ内部パスが利用できない場合、0 x 0Bはパスが通過しているがターゲットデバイスが応答しない場合です。

典型的なトリガーシナリオ:

  • ターゲット·デバイスがビジーデバイスは前の命令を処理しています
  • ターゲット·デバイスのレスポンス·タイムアウトModbus RTUの3.5文字タイムアウトメカニズム
  • データ形式の不一致下流デバイスの通信パラメータ(ボーレート、検証方式)がゲートウェイ設定と一致しない

3.異常コードスピードチェック

異常コード。名前(英語)名前(中国語)共通のレベル
0x01Illegal Function違法な機能★★★★★
0x02Illegal Data Address違法なデータアドレス★★★★★
0x03Illegal Data Value不正なデータ値★★★★☆
0x04Slave Device Failureスレーブ機器の障害★★★☆☆
0x05Acknowledge確認(保留中)★★★☆☆
0x06Slave Device Busy駅の設備が忙しい★★★☆☆
0x07Negative Acknowledge否定的な確認★☆☆☆☆
0x08Memory Parity Errorメモリエラー★☆☆☆☆
0x0AGateway Path Unavailableゲートウェイパスが使用できません★★☆☆☆
0x0BGateway Target Failedゲートウェイターゲットの応答に失敗しました★★☆☆☆

4.深いトラブルシューティング方法論

4.1階層的検査法

産業通信のトラブルシューティングは、物理層から上位層へと段階的にチェックする“ボトムアップ”の原則に従う必要があります。

  1. 物理レベル:ケーブル接続、端末抵抗、許褚の、の点検
  2. データリンク層:オシロスコープまたはロジックアナライザによるRS-485 信号品質の確認
  3. ネットワーク層:Modbus TCPシナリオでWiresharkパケット解析を使用する
  4. アプリケーション層:Modbus Pollなどのツールを使用して問題を特定する最小化リクエストを送信する

4.2除外法の比較

現場に同じタイプの機器が複数ある場合、コントラスト除去法を使用することが最も効率的な位置決め方法です。

  1. 故障の疑いのある機器と正常に動作している機器の場所を交換する
  2. 同じマスターツールを使用して2つのデバイスを個別にテストする
  3. 2つのデバイス間の応答の違いを比較する

4.3最小化再帰法

複雑なリクエストを最も単純な正当なリクエストに単純化し、徐々に複雑さを増します。

ステップ1最小要求01 03 00 00 01 [CRC]--アドレス0の1レジスタを読み出す
手顺2成功すれば、レジスタ数00 02、00 03を徐々に増やす。。。
ステップ3:失敗した場合、アドレスのスコープを絞り込む

RTUモードとTCPモードの異常な違い

例外コードの定義はRTUモードとTCPモードでは完全に同じですが、例外処理の流れは2つのモードで異なります。

次元の比較Modbus RTUModbus TCP
タイムアウト処理3.5文字時間応答なし判定タイムアウトTCP接続のタイムアウトはオペレーティング·システムによって制御される
異常検出。CRCチェックエラーダイレクトドロップメッセージTCP層によるデータ整合性の保証
MBAPヘッダなしなし。トランザクション識別子の一致をチェックする必要があります
ゲートウェイ·シーン関与は少ない。例外コード0 x 0 A/0 x 0Bが一般的

プログラミング実装:例外処理のベストプラクティス

以下は、組込みシステム開発のためのC言語を使用したModbus例外処理の完全な例です。

/**
 * Modbus例外コード処理関数
 * @param func      関数コードのリクエスト
 * @param exception例外コード
 * @return人間が読めるエラー記述文字列。
 */
const char* modbus_exception_str uint8_t func uint8_t exception {
    static char buf[128];
    const char* exc_name;
    
    switch exception {
        case 0x01 exc_name = "不正な関数コード"; break;
        case 0x02 exc_name = "不正なデータアドレス"; break;
        case 0x03 exc_name = "不正なデータ値"; break;
        case 0x04 exc_name = "スレーブデバイス障害"; break;
        case 0x05 exc_name = "確認待機中"; break;
        case 0x06 exc_name = "スレーブデバイスがビジー"; break;
        case 0x07 exc_name = "否定"; break;
        case 0x08 exc_name = "メモリチェックエラー"; break;
        case 0x0A exc_name = "ゲートウェイパスが利用できません"; break;
        case 0x0B exc_name = "ゲートウェイターゲット応答失敗"; break;
        default:   exc_name = "不明な例外コード"; break;
    }
    
    snprintf buf sizeof buf 
             “Modbus例外機能コード0x % 02X →例外コード0x % 02X %s”
             func exception exc_name;
    バックアップを参照。
}

/**
 * Modbusレスポンスの処理
 * 0を返すと通常の応答、負の値は例外を表す
 */
int mod_le_uint8_t* rsp int rsp_
                           uint8_t expected_func {
    if rsp_len2 return -1; //応答長例外
    
    uint 8_t func = rsp[1]; // RTUモードでは、2番目のバイトは関数コードです。
    
    if c 0x80 {
        //異常な応答
        uint8_t例外= rsp[2];
        log_error mod_exception_c 0x7F exception;
        
        //例外コードに基づいて異なる再試行戦略を取る
        switch exception {
            case 0x01//ファンクションコード未サポート-再試行しません
            case 0x02//不正なアドレス-再試行しない
                リターン-例外;
            case 0x05//確認-待機後に再試行
            case 0x06//デバイスがビジー-再試行を遅延
                return-exception; //呼び出し元は再試行ロジックを処理する
            default:
                リターン-例外;
        }
    }
    
    // 正常応答処理。..
    return 0;
}

7.よくある質問FAQ

Q 1:Modbusスレーブから例外コード0 x 0 2が返されましたが、アドレスは正しいように見えます。

最も一般的な原因は、“アドレスオフセット1”の問題です。一部のデバイス(特にPLC)のModbusアドレスはプロトコルアドレスから1オフセットしています。例えば、PLC側の設定アドレスは40001ですが、Modbusプロトコルの対応する内部アドレスは(1ではなく)0です。アドレスマッピング関係については、機器マニュアルを参照してください。

Q2スレーブ局が正常なデータを返したり、異常コード0x06を返すことがあるのはなぜですか

これは、通常、スレーブのCPU処理能力が不十分であることを意味します。ポーリング頻度が高すぎると、スレーブはすべてのリクエストを処理できず、0 x 0 6を返します。解決策:ポーリング頻度を下げるか、1回のリクエストで必要なレジスタ数を減らします。

Q3例外コード0 x 05と0 x 06の違いは何ですか?

0 x 0 5(確認):スレーブが送信した特定のリクエストをすでに処理中で、完了を待つ必要があります。0 x 0 6(デバイスがビジー):スレーブは現在、任意の操作のために新しいリクエストを処理できません。0 x 0 5は“私はあなたのことをしています”、0 x 0 6は“私は今忙しくて誰も来ない”です。

Q4:スレーブが全く応答しない(タイムアウト)、例外コードを返さない場合はどうすればよいですか?

完全に応答しないことは、通常、物理層またはデータリンク層の問題を意味します。

  1. スレーブのアドレスが正しいかどうかを確認します(アドレスの不一致はスレーブの沈黙の最も一般的な原因です)
  2. RS-485のA/Bラインが反転しているかどうかを確認します。
  3. ボーレートと検証方式が一致するかどうかを確認する
  4. 終端抵抗とバイアス抵抗の確認
  5. オシロスコープを使用してバスに信号があるか確認する

VIII.まとめ

Modbusの例外応答メカニズムは、プロトコル設計のハイライトです。単に通信を失敗させるのではなく、例外コードを介してマスターステーションに“何が間違っているのか”を正確に伝えます。これらの異常コードの意味とトラブルシューティング方法を理解することで、障害の特定時間を数時間から数分に短縮できます。

この記事の例外コードクイックチェックシートを印刷してワークステーションに貼り付けるか、デバッグツールに例外コードの自動解析機能を統合することをお勧めします。産業現場では、1分のダウンタイムはリアルマネーの損失を意味します。Modbusの異常コードをすばやく見つけることは、しばしば問題解決の第一歩です。

関連する読書:Modbus関数コード完全解析|Modbus RTUとTCPの比較|Modbus CRC検証原理とプログラミング実装

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

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

エンジニア会員

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

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

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

发表回复

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