ArduinoでModbusをマスターする:ステップバイステップガイド
必要な部品と材料
| 部品 | 数量 |
|---|---|
| Arduino UNO | 1 |
| Arduino用プロフェッショナルRS422/RS485シールド | 1 |
| USB-RS485変換アダプタ | 1 |
| ブレッドボード(汎用) | 1 |
| LED(汎用) | 1 |
| 抵抗 10kΩ | 1 |
| 抵抗 221Ω | 1 |
| ジャンパーワイヤー(汎用) | 1 |
| SparkFun プッシュボタンスイッチ 12mm | 1 |
使用するアプリとオンラインサービス
- Arduino IDE
- ModbusTester(Modbusマスターソフトウェア)
プロジェクト概要
Modbusはシリアル通信の標準規格として、産業用電子機器の接続に広く採用されているデファクトスタンダードプロトコルです。Modbus RTUおよびModbus ASCIIでは、物理層としてRS-485が使用されます。ArduinoをModbusスレーブ(制約付きでマスターも可能)として使用できますが、RS-485インターフェースが必要です。ここで使用するRS422/RS485シールドは、Arduino UNOおよび互換ボード(Arduino 101、STM Nucleoなど)向けに設計された完全絶縁型シリアル通信シールドで、この種のアプリケーションに最適です。
このドキュメントでは、Arduino UNOを使ってシンプルなModbusスレーブデバイスを作成する手順を解説します。ModbusマスターとしてPCを使用します。
必要なツールと材料
- Arduino UNO
- Arduino用RS-485シールド
- PC接続用RS-485-USBアダプタ
オプション(動作確認用):
- ブレッドボード
- プッシュボタン
- 赤色LED
- 220Ω抵抗
- 10kΩ抵抗
- ジャンパーワイヤー
ソフトウェア
- Arduino IDE
- ModbusTester
RS-485配線
配線は非常にシンプルです。シールドのA端子とB端子を、ModbusシステムのA線とB線にそれぞれ接続するだけです。Y端子とZ端子はこの用途では使用しません。長距離伝送の場合は、A線とB線にツイストペアケーブルを使用することを推奨します。
Arduino配線(オプション)
Modbus通信の効果を視覚的に確認するため、LEDとボタンをArduinoに追加することを推奨します。これはオプションで、必須ではありません。
DIPスイッチ設定
RS422/RS485シールドには3つのDIPスイッチバンクがあります。Modbus用に以下のように設定してください。
- スイッチ1: 1-OFF、2-ON、3-ON、4-OFF
- スイッチ2: 1-OFF、2-OFF、3-ON、4-ON
- スイッチ3: 1-OFFまたはON*、2-OFF、3-OFF、4-OFF
* RS422/RS485シールドがModbusラインのどの位置にあるかにより、終端抵抗をON/OFFします。シールドがバスラインの端にある場合のみONにし、それ以外ではOFFにしてください。
ジャンパー設定
シールド上には3つのジャンパーエリアがあります。特に重要なのは電源電圧設定用のJP1です。Arduino UNOは内部的に5Vで動作するため、このジャンパーを5V位置に設定してください(Arduino 101などの3.3Vボードの場合は3.3V位置)。
さらに、左上の通信ポート用ジャンパーを画像のように設定します。これにより、内部UART(ポート0と1)がシールドのRS-485インターフェースに接続されます。
最後にRX/TX制御ポート用ジャンパーですが、自動RX/TX切り替えが設定されているため、このジャンパーは使用しません。
PCへのModbusTesterソフトウェアインストール
この例ではPCをModbusマスターとして使用します。ModbusTesterをダウンロードし、ZIPアーカイブをハードディスク上の新しいディレクトリに解凍してください。ソフトウェアを起動し、画像のように設定項目を変更します。USB-RS485アダプタを接続してから、ModbusTesterで正しいCOMポートを選択してください。
Arduinoソフトウェア
Arduino IDEにファームウェアを読み込み、コンパイルして書き込んでください。
動作テスト
いよいよ動作テストです!
ModbusTesterの「Read」ボタンを押すと、スレーブデバイスのメモリから8バイトが読み取れます。アドレス400008にはボタンの状態が、アドレス400001〜400006にはADCポートの値が格納されています。
「Write」ボタンでスレーブのレジスタを操作できます。アドレス400007に0または1を書き込むと、LEDのON/OFFを制御できます。
サンプルコード(Arduino UNO用)
/*
* Arduino RS422/RS485シールド用テストプログラム
* Version 1.0
* Copyright (C) 2018 Hartmut Wendt www.zihatec.de
* (https://github.com/angeloc/simplemodbusng をベースに作成)
*
* このプログラムはフリーソフトウェアです。GNU General Public License v3以降の条件で再配布・変更可能です。
* 詳細: https://www.gnu.org/licenses/
*/
#include <SimpleModbusSlave.h>
#define ledPin 12 // オンボードLED
#define buttonPin 7 // プッシュボタン
/* このサンプルコードは9つのホールディングレジスタを使用します。
* 6つのアナログ入力、1つのボタン、1つのデジタル出力、1つのエラーカウントレジスタ。
* ファンクション5(単一コイル書き込み)は未実装のため、ファンクション16でレジスタ全体を使ってLEDを制御します。
* modbus_update()メソッドはholdingRegs配列を更新し、通信をチェックします。
*/
enum {
ADC0, ADC1, ADC2, ADC3, ADC4, ADC5,
LED_STATE, BUTTON_STATE, TOTAL_ERRORS,
TOTAL_REGS_SIZE // レジスタ総数(ファンクション3と16で共有)
};
unsigned int holdingRegs[TOTAL_REGS_SIZE];
void setup() {
// modbus_configure(ボーレート, スレーブID, 送信イネーブルピン, レジスタ数, 低レイテンシ)
// 送信イネーブルピン: 半二重通信でMAX485等を制御。無効化する場合は2未満(0,1はRx/Tx予約)を指定
modbus_configure(9600, 1, 6, TOTAL_REGS_SIZE, 0);
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop() {
// modbus_update()はエラー総数を返す。マスター側での故障診断に有用
holdingRegs[TOTAL_ERRORS] = modbus_update(holdingRegs);
// アナログ入力6チャネルを読み取り
for (byte i = 0; i < 6; i++) {
holdingRegs[i] = analogRead(i);
delayMicroseconds(50);
}
// ボタン状態読み取り
byte buttonState = digitalRead(buttonPin);
holdingRegs[BUTTON_STATE] = buttonState;
// LED_STATEレジスタの値でオンボードLEDを制御(ファンクション16経由)
byte ledState = holdingRegs[LED_STATE];
if (ledState) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
holdingRegs[LED_STATE] = 0;
}
}
製造プロセス
- Arduino MegaでPWM制御:プッシュボタン付きLEDフェード制御チュートリアル
- Arduino NanoとMPU-6050で作るリアルタイムジャイロスコープゲーム
- Unopad: Ableton Live連携シームレスなArduino MIDIコントローラー
- Arduinoでシンプルな障害物センサーを自作 – IR LEDとフォトダイオード入門
- ArduinoとBluetoothで作るスマート紛失防止タグ「Find Me」
- ゲーム用カスタムArduinoジョイスティックハンドルの製作
- サーミスタを使った温度測定: Arduinoステップバイステップガイド
- Arduinoで楽器演奏:音階生成のステップバイステップガイド
- ArduinoをNMEA-0183に接続するステップバイステップガイド
- Arduinoと超音波センサーで自動ドアを制御:LCD・ブザー付き完全ガイド
- C# Queue完全ガイド:Enqueue、Dequeue、FIFO操作の実例解説