産業用ArduinoでのModbus RTU実践ガイド
RS-485の配線から、内蔵命令によるMPINOコントローラのModbus RTUマスター/スレーブ実装、HMI・SCADA連携までを解説します。
読了 9 分
Modbus RTUとは何か、なぜ産業ネットワークを支配するのか
Modbus RTUは1979年にModiconが発表したシリアル通信プロトコルであり、今日でもフィールド機器、PLC、HMI、SCADAシステムを接続する産業オートメーションの事実上の標準です。マスタ・スレーブ構成の簡潔なバイナリ要求応答メッセージをシリアル物理層(多くの場合RS-485)上で伝送し、すべてのトランザクションは16ビットCRCで保護されるため、工場現場の電気的ノイズがプロセスデータを破損させることはありません。
本プロトコルは機器メモリを4つのアドレス空間に構成します。すなわちディスクリート入力(読み取り専用ビット)、コイル(読み書きビット)、入力レジスタ(読み取り専用16ビットワード)、保持レジスタ(読み書き16ビットワード)です。この単純なモデルはILOGICS MPINOコントローラの物理I/Oにそのまま対応します。デジタル入力はディスクリート入力へ、リレーおよびトランジスタ出力はコイルへ、アナログチャネルは入力レジスタへマッピングされます。
MPINO-8A8RやMPINO-16A8R8Tのような産業用ArduinoにおいてModbus RTUは、低コストで開放的にプログラム可能なハードウェアと既存の計装設備とを結ぶ架け橋です。ほぼすべてのHMIおよびSCADAパッケージがModbus RTUドライバを標準搭載するため、MPINOをModbusスレーブとして公開すれば、独自プロトコル開発なしに多数のベンダの機器と相互運用できます。
Modbus RTUのためのRS-485物理配線
MPINOファミリのModbus RTUは2線式(共通線を含む)RS-485バス上で動作します。すべての機器はデイジーチェーンのマルチドロップトポロジで接続し、AはA同士、BはB同士、そしてデータ対とともに共通信号グランド(GND/COM)を配線します。スター配線や長いスタブは反射を生じさせ、CRCが依存するビットタイミングを破損させるため避けてください。
MPINOはオートディレクションRS-485トランシーバを使用するため、ファームウェアが送信前後に別個のドライバイネーブル(DE/RE)ピンを制御する必要はありません。トランシーバがUART送信ラインを検出し、ドライブと受信を自動的に切り替えるため、マスタがバスを早すぎる、または遅すぎるタイミングで解放する一般的なタイミング不具合が解消されます。
バス両端の物理的終端にはA-B間に120Ωの終端抵抗を接続してケーブルの特性インピーダンスに整合させ、フェイルセーフバイアス抵抗を追加してアイドルラインが定義された状態を保つようにします。RS-485定格のシールド付きツイストペアケーブルを使用し、シールドは片端のみで接地し、VFDやモータ動力ケーブルから離して配線してください。MPINO-8A8R-SとMPINO-16A16RはRS-485とI²Cを、ATmega2560ベースのMPINO-8A8R、MPINO-16A8R8T、MPINO-16A8RはRS-485に加えてRS-232とUARTを備えます。
マスタ対スレーブ:MPINOの役割選択
Modbus RTUでは正確に1台の機器のみがマスタとなってすべてのトランザクションを開始し、他の機器はアドレス指定されたときのみ応答するスレーブとなります。MPINOは両方の役割を担うことができ、ILOGICS SDK の内蔵命令はModbus RTUマスタとスレーブの両スタックを実装します。
既存のHMI、SCADAフロントエンド、またはPLCがMPINOの入力を読み取りリレーを制御する必要がある場合は、MPINOをスレーブとして構成します。このときHMIがマスタとなり、一定のスキャン周期で保持レジスタとコイルをポーリングします。これが最も一般的な構成であり、MPINOはあらゆるModbusマスタがアドレス指定できるリモートI/Oブロックのように動作します。
MPINOが他のフィールド機器を制御する必要がある場合、例えばModbus電力計、温度トランスミッタ、インバータ(VFD)を読み取りローカルで反応する場合はマスタとして構成します。マスタモードではMPINOスケッチがスケジュールに従って読み書きファンクションコードを発行し、応答を処理します。単一のRS-485セグメントでは1台の機器が一度に1つの役割のみを保持します。
MPINO I/Oのためのレジスタおよびコイルマッピング
明確に文書化されたレジスタマップは、MPINOファームウェアと通信するすべてのクライアントとの間の契約です。マッピングを一度決めたら、ファームウェアの改訂全体にわたって安定的に維持してください。MPINO-8A8Rの典型的な慣例は、8つのデジタル入力をディスクリート入力10001-10008に、8つのリレー出力をコイル00001-00008に、4つのアナログ入力を入力レジスタ30001-30004に公開することです。
アナログ値には特別な注意が必要です。MPINOのアナログフロントエンドはanalogReference(EXTERNAL)を要求し、10ビットADCは0-1023カウントを返します。これを入力レジスタに生値として公開するか、ファームウェアで工学単位にスケーリングできます。レジスタ30001が生カウントなのか、ミリボルトなのか、プロセス値なのかをHMI統合担当者が把握できるよう、スケーリング係数をレジスタマップに記録してください。
MPINO-16A8R8Tのような大型コントローラは、16のデジタル入力、8つのリレーおよび8つのトランジスタ出力をコイルとして、4つのアナログ入力と2つのアナログ出力をレジスタとして、2つのNTC温度チャネルを追加の入力レジスタとして拡張マッピングします。完全なマップを製品とともに1ページの文書として公開すれば、MPINOはあらゆるModbusマスタ向けの即時適用可能なリモートI/Oノードとなります。
内蔵命令によるModbus RTUの実装
ILOGICS SDK の内蔵命令はMPINOハードウェアとオートディレクションRS-485トランシーバに最適化されたModbus RTU実装を提供するため、プロトコルの配管作業ではなくアプリケーションロジックに集中できます。ボードは標準のArduino IDEでプログラムします。MegaCoreベースのボードパッケージであるアイロジックスのARDUINO SDKをインストールすると、ATmega128またはATmega2560機種のボード定義が追加されます。
以下のスニペットはMPINO-8A8Rをアドレス1、19200 baudのModbus RTUスレーブとして構成し、8つのデジタル入力と8つのリレーコイルをマッピングすることで、HMIマスタがリアルタイムの入力状態を読み取りリレーを制御できるようにします。トランシーバがオートディレクションであるため、スケッチはDE/REピンを一切扱いません。
書き込み後、任意のModbus RTUマスタをスレーブアドレス1に向け、マッピングされたコイルとディスクリート入力をポーリングして、上位制御システムと統合する前に配線とCRCが健全であることを確認してください。
/*
MPINO-16A8R8T example: Modbus RTU slave
使用する命令:
- ImodbusRTUMem(), ImodbusRTUAdr(), ImodbusRTUInit()
- ImodbusRTU(), ImodbusRTU(serialPort)
- ImodbusRTUmasterInit(), ImodbusRTUmasterAdd(), ImodbusRTUmasterRun()
MPINO-16A8R8T のポート:
- Serial1 = RS-232
- Serial2 = RS-485
*/
#if !defined(M16A8R8T)
#warning "This example is written for MPINO-16A8R8T."
#endif
void setup() {
// M ビット128点、D ワード128点を通信メモリとして確保する。
ImodbusRTUMem(128, 128);
// 外部アドレスと内部配列のインデックス開始点を0に合わせる。
ImodbusRTUAdr(0, 0);
// RS-485ポート Serial2 を Modbus RTU スレーブ ID 1、9600bps で開始する。
ImodbusRTUInit(Serial2, 1, 9600);
// 複数ポートを使う場合は Init を追加する。M/D メモリは共有される。
// ImodbusRTUInit(Serial1, 2, 9600);
}
void loop() {
// 登録されたすべての Modbus RTU ポートを順に処理する。
ImodbusRTU();
// 特定のポートだけ処理する場合は serialPort 引数を渡す。
// ImodbusRTU(Serial2);
// HMI/PLC が読む値を内部メモリに反映する。
M[0] = digitalRead(22); // コイル領域の例
D[0] = analogRead(A0); // 保持レジスタの例
// HMI/PLC が書いた M[10] で R(62) を制御する。
digitalWrite(62, M[10]);
}
/*
Modbus RTU マスタスケジューラの例:
void setup() {
ImodbusRTUmasterInit(Serial2, 9600);
ImodbusRTUmasterAdd(Serial2, 1, 0x03, 0x00, 1, &D[1]);
ImodbusRTUmasterAdd(Serial2, 1, 0x03, 0x01, 1, &D[2]);
}
void loop() {
ImodbusRTUmasterRun();
}
*/HMIおよびSCADAとの統合
MPINOがModbus RTUに正常に応答すれば、HMIまたはSCADAプラットフォームとの統合は設定作業となります。HMIドライバでMPINOのbaud rate、パリティ、ストップビットに一致するModbus RTUシリアルチャネルを作成し、構成済みのアドレスでスレーブを追加して、公開したマップのコイル、ディスクリート入力、レジスタに画面オブジェクトをバインドします。
ポーリング周期は現実的に保ってください。数十点を処理するATmega128またはATmega2560は100-500 msのスキャン周期に安定して応答しますが、多数のレジスタを50 ms未満で過度にポーリングするとアプリケーションループが枯渇する可能性があります。関連する点を連続したレジスタブロックにまとめれば、マスタが単一のファンクション呼び出しで読み取り、バストラフィックと遅延が削減されます。
アラームやインターロックを駆動するSCADAタグについては、MPINOが起動中にプレースホルダではなく実際の値を公開することを確認してください。setup()でレジスタを既知の安全状態に初期化し、ソースが一度読み取られた後にのみ点を有効として表示します。この原則がMPINOを運用制御ネットワークの信頼できるノードとして維持します。
対象コントローラ



MPINO-16A8R8T
MPINO-16A8R8T 産業用Arduinoコントローラ
関連ガイド
FAQ
どのMPINOモデルがRS-485ベースのModbus RTUに対応していますか?▾
列挙したすべてのMPINOコントローラはRS-485を備え、内蔵命令でModbus RTUを実行します。MPINO-8A8R-SとMPINO-16A16RはATmega128でRS-485とI²Cを使用し、MPINO-8A8R、MPINO-16A8R8T、MPINO-16A8RはATmega2560でRS-485に加えRS-232とUARTを備えます。
RS-485の送信方向制御のためにDE/REピンを制御する必要がありますか?▾
いいえ。MPINOはUART送信ラインに基づいてドライブと受信を自動的に切り替えるオートディレクションRS-485トランシーバを使用します。スケッチと内蔵命令はドライバイネーブルピンを一切トグルしないため、Modbusタイミングエラーの頻繁な原因が排除されます。
1台のMPINOがModbusマスタであると同時にスレーブになれますか?▾
単一のRS-485セグメントでは1台の機器が一度に1つの役割のみを保持します。内蔵命令はマスタとスレーブの両スタックに対応するため、複数のシリアルポートを持つMPINOは1つのポートで上位SCADAマスタに対するスレーブとして、別のポートで下位機器に対するマスタとして動作できます。
