Arduino OPTAは、ディジタル入出力、アナログ入力のほかに、
- Modbus/RTU RS485のツイスト・ペア線を利用
- Modbus/TCP イーサネットを利用
のサーバおよびクライアントになれます。Arduino IDE 2.0.4のスケッチで動作を確認します。
●接続
RS-485で接続するModbus/RTUを利用します。Arduino OPTAには機能が内蔵されていて、A、B、GNDの端子が出ています。接続するのはA、Bの2本です。配線の両端にターミネータ120Ωが必要ですが、今回の実験は室内で、端から端までが3mほどの距離と短いので、何もつけていません。
実験は9600bps パリティなし 8ビット ストップ・ビット1の通信条件行いました。
温度調節器は通信機能があるモデルを選択し、マニュアルに従って、Modbusが使える設定に変更し、通信条件を上記のように設定しておきます。今回利用した温度調節器は、熱電対で温度を測ります。
極性は、次のようになっているのが多いです。ケーブルはツイスト・ペア線を使いますが、実験ならば平行線でかまわないと思います。
- Aがマイナス
- Bがプラス
●スケッチ
ライブラリAIPlc_Optaをインストールします。
ArduinoRS485.hはインストールされていましたが、ArduinoModbus.hは入ってなかったので、ライブラリで、「modbus」で検索して、ArduinoModbusをインストールしました。
The complete code for the Client is shown below:
と書かれたスケッチをベースにして、不要なところを削除します。
必要なのは、温度の値を読み出すために使われるreadHoldingRegisterValues()関数だけです。今回は書き込みはしません。多くのFA用機器では、HoldingRegisterに必要なデータが保存されているので、温度調節器のマニュアルに従って読み出します。
// Name: Opta_Client
#include
#include // ArduinoModbus depends on the ArduinoRS485 library
constexpr auto baudrate { 9600 };
// Calculate preDelay and postDelay in microseconds as per Modbus RTU Specification
// MODBUS over serial line specification and implementation guide V1.02
// Paragraph 2.5.1.1 MODBUS Message RTU Framing
// https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
constexpr auto bitduration { 1.f / baudrate };
constexpr auto preDelayBR { bitduration * 9.6f * 3.5f * 1e6 };
constexpr auto postDelayBR { bitduration * 9.6f * 3.5f * 1e6 };
// constexpr auto preDelayBR { bitduration * 10.0f * 3.5f * 1e6 };
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_D0, OUTPUT);
Serial.println("Modbus RTU Client");
delay(10);
RS485.setDelays(preDelayBR, postDelayBR);
// Start the Modbus RTU client
if (!ModbusRTUClient.begin(baudrate, SERIAL_8N1)) {
Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
void loop() {
digitalWrite(LED_D0, HIGH);
delay(1000);
digitalWrite(LED_D0, LOW);
delay(1000);
readHoldingRegisterValues();
delay(5000);
Serial.println();
}
/**
Reads Holding Register values from the server under specified address.
*/
void readHoldingRegisterValues() {
Serial.print("Reading Holding Register values ...");
// Read HOLDING Register values from (server) id = 2, address 0x2000 2bytes?
if (!ModbusRTUClient.requestFrom(2, HOLDING_REGISTERS, 0x2000, 1)) {
Serial.print("failed! ");
Serial.println(ModbusRTUClient.lastError());
} else {
Serial.println("success");
while (ModbusRTUClient.available()) {
Serial.println("オムロンE5CN-H");
Serial.print(round(ModbusRTUClient.read() / 10.0),1);
Serial.println("`C");
}
Serial.println();
}
Serial.print("Reading Holding Register values ...");
// Read HOLDING Register values from (server) id = 1, address 0x0080 2bytes?
if (!ModbusRTUClient.requestFrom(1, HOLDING_REGISTERS, 0x0080, 1)) {
Serial.print("failed! ");
Serial.println(ModbusRTUClient.lastError());
} else {
Serial.println("success");
while (ModbusRTUClient.available()) {
Serial.println("パナソニックKT-7");
Serial.print(round(ModbusRTUClient.read() / 10.0),1);
Serial.println("`C");
}
Serial.println();
}
}
実行例です。動作中は、四つあるLEDの一番左を点滅させています。
●Modbus/RTUのとても簡単な説明
物理的な配線に使われるRS-485は差動なので、ノイズに強いと言われています。
最大247個のアドレスを扱えますが、機器によっては31個までという製品もあります。
デバイスのアドレスという呼び名は、ライブラリやユーティリティによって次のようにも呼ばれます。
- アドレス
- スレーブ・アドレス
- ID
- Slave Addr
- Device
- Device Address
アドレスは1からふられますが、論理的な指定を0から行うソフトウェアもあります。
通信には、次のパラメータの設定が必要です。
- ボーレート デフォルトは9600が多い。2400~19200bpsが選べる場合もある
- データ・ビット 7もしくは8ビット。8ビットが多い
- ストップ・ビット 「1、1.5、2」もしくは「1、2」から選択。1が多い
- パリティ なし、偶数、奇数から選択。「なし」が多い
海外製品は、「9600、8、1、なし」がデフォルトになっていることが多いです。逆に、日本製品では、そうなっていない場合があります。取扱説明書には書かれていないことも多く、確かめるには、機器のパネルを操作し該当するパラメータを表示します。確認できないこともあるので、その時は、テクニカル・サポートに電話で確認しておきます。
でも、Arduino.ccのサンプルは、パリティありになっていました。
代表的なファンクションの例です。ファンクションとは、どのレジスタに対して読むのか書き込むのかをいくつか定義したものです。下記に示した例よりもっとたくさん規格ではきめられていますが、多くの製品では、下記のファンクションの一部だけが実装されています。
https://modbus.org/docs/PI_MBUS_300.pdf
ファンクションの01~04が読み出すときに、05と06、16は設定値を書き込むときに使われます。
温度などを読み出すときは、03もしくは04のどちらかが使われます。
ファンクションのコード | 機能名 | 機能 | 備考 |
---|---|---|---|
01 | Read Coil Status | スレーブのDOのON/OFFを読み出す | |
02 | Read Input Status | スレーブのDIのON/OFFを読み出す | |
03 | Read Holding Register | スレーブの保持レジスタの内容を読み出す | 装置によって大きく長さや内容は異なる |
04 | Read Input Register | スレーブの入力レジスタの内容を読み出す | |
05 | Force Single Coil | スレーブのDOをONもしくはOFFする | ONは0xff,0x00、OFFは0x00,0x00 |
06 | Preset Single Register | スレーブの保持レジスタの内容を変更する | |
16 | Preset Multiple Registers | スレーブの連続した複数の保持レジスタの内容を変更する | |
以下略 |
温度を読み出すときに使われるModbusの規格と、今回利用する温度調整器の名称を次に示します。03と04の使い分けは、メーカによってまちまちです。
ファンクション・コード | データのある場所の名称 | |
---|---|---|
規格 |
03 Read Holding Register もしくは04 Read Input Register |
「保持レジスタ」は40001からスタート。 もしくは「入力レジスタ」は30001からスタート |
オムロンE5CN-H | ファンクション・コード03の変数読み出し | 「設定データのアドレス」は0000からスタート |
パナソニックKT-7 | 機能コード03のスレーブの設定値,情報の読み取り | 「データ項目」は、0x0001からスタート |
●本ブログの関連記事
センサ・シリーズ 温度②温度調節器 その1 Modbusの設定
センサ・シリーズ 温度②温度調節器 その2 Modbusで読み書き
Modbusの利用 (5) E820-AIO アナログ入力①
Modbusの利用 (9) 回すだけ EVALKIT-ROBOT-1ブラシレス・モータ・キット②
Simulink Support Package for Raspberry Pi ⑦ Modbus/TCP 熱電対
●資料