はじめてのModbus (2) Lチカ
前回、Modbusの種類の中にModbus/TCPがありました。ArduinoModbusライブラリには、イーサネットのネットワークにつないで利用するこのプロトコルに対応したサンプル・スケッチが入っています。ここでは、Wi-Fiネットワークに対応しているモデルMKR WiFi1010を利用します。
前回利用したMKRZEROにはETHシールドが用意されていて、ネットワークに接続できます。MKRシリーズでは、最初にWiFi1000が出荷されましたが、技適コードが見つかりません。MKR WiFi1010は無線モジュールのNINA-W102が使われていて、2018年6月15日に技適(204-810001)に登録されています。
●ファンクション
Modbusでは、読み書きの方法がいくつかのファンクションで規定されています。おもなものを取り上げます。前回は03 Read Holding Registerを使いました。
コード | 機能名 | 機能 | |
---|---|---|---|
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 | スレーブの保持レジスタの内容を変更する | |
以下略 |
問い合わせと返事(問い合わせとほぼ同じ、省略)のフォーマットは次のように規定されています。スレーブ・アドレスは複数RS-485につながっているときの識別するためのコードです。多くの装置は購入時1に設定されていて、DIPスイッチやユーティリティを用いて1~127の範囲で変更できます。
フィールド | RTUの例 | TCPの例 |
---|---|---|
スレーブ・アドレス(ID) | 0x01 | 0x01 |
ファンクション(Read Holding Registerの場合) | 0x03 | 0x03 |
開始アドレス(上位) | 0x00 | 0x00 |
(下位) | 0xe0 | 0xe0 |
レジスタの数(上位) | 0x00 | 0x00 |
(下位) | 0x03 | 0x03 |
エラーチェック | CRC | なし |
ここではForce Single Coil(05)を使います。TCP/IPではデータは正しく送れるので、RTUのようにCRCはありません。
フィールド | RTUの例 | TCPの例 |
---|---|---|
スレーブ・アドレス(ID) | 0x01 | 0x01 |
ファンクション | 0x05 | 0x05 |
開始アドレス(上位) | 0x00 | 0x00 |
(下位) | 0x00 | 0x00 |
レジスタの数(上位) | OFFのとき0x00、ONのとき0xff | OFFのとき0x00、ONのとき0xff |
(下位) | 0x00 | 0x00 |
エラー・チェック | CRC | なし |
●サンプル・スケッチ
前回と同様に、MKRシリーズのマイコン・ボードでは、ライブラリはArduinoModbusとArduino RS485の二つが必要です。サンプル・スケッチのWiFiModbusServerLEDを読み込みます。別ファイルのarduino_secrets.hにSSIDとパスフレーズを書き込みます。MKR WiFi1010のインターネット・アクセス関連はWiFiNINAのライブラリを使います。こちらにいくつか解説しています。
スケッチは変更せずに、コンパイルし実行します。このスケッチは、Modbus/TCPのサーバのアプリケーションです。
スレーブがアクセスしてきて、ファンクションForce Single Coil(05)を使ってONを指示すると、MKR WiFi1010ボードのLEDが点灯する。OFFを指示すると、LEDは消灯する。 実装されているのはForce Single Coil(05)のみ。 |
実行しているときのシリアルモニタの様子です。MKR WiFi1010ボードは192.168.111.100が振られています。スレーブがアクセスすると、最下行のようにnew clientとメッセージを表示します。
●スレーブの用意
サーバーが動きました。アクセスするためにスレーブが必要です。Windows10で実行できるModbusスキャナを探して実験しました。CAS Modbus Scanner が情報量が多かったので利用します。
Edit画面のAdd conectionで、TCP、192.168.111.100、ポート502を作成します。その下にDevice ID 1のDevice1を作ります。その下に、ファンクションの実行を並べていきます。
ここでは、下記の画像のように、Force Single Coilの実行名のWrite Single Coilを利用します。at 1:1がON、1:0がOFFの指示です。
右上にあるpollで、選んだファンクションが実行されます。クリックすると、すぐにLEDが点灯/消灯します。うまくつながらないときは、Disconnectをクリックします。このユーティリティを動かすと、ポート502はすぐには開放されません。
●スレーブのプログラム
Pythonのプログラムで上記と同様の操作を行います。環境はWindows10です。Python2を入れた後Python3をインストールしたので、Python3はpyで実行できます。ユーティリティpipを使ってインストールしたライブラリは、Python3側にインストールされます。
次のように、コマンドプロンプト内でpyModbusTCPライブラリをインストールします。
pip install pyModbusTCP |
デスクトップにテキスト・エディタで下記のプログラムを作り、保存します。mod03.pyとしました。write_single_coil(0,1)の1はONの指示です。OFFは、write_single_coil(0,0)と書き換えます。
from pyModbusTCP.client import ModbusClient
SERVER_HOST = "192.168.111.100"
SERVER_PORT = 502
c = ModbusClient()
c.host(SERVER_HOST)
c.port(SERVER_PORT)
c.unit_id(1)
c.open()
regs = c.write_single_coil(0,1)
c.close()
CAS Modbus Scanner が起動していると、同時にこのプログラムからはアクセスできません。
py mod03.py |
で、LEDが点灯もしくは消灯します。
コラム リレーをON/OFF
LEDのON/OFFができるので、リレーをつなぎました。大きな問題が起こりました。Arduino UNOはこちらで調べたように、ほとんどのI/Oは、電源を入れてからスケッチが動き出すまでずっとLOWです。MKR WiFi1010の6番を観測した様子です。ほかのポートは未確認です。
コンパイルしている途中から、かなりの速さで、HIGH/LOWが繰り返されます。リレーをつないでおくと、ON/OFFが間に合わないくらいバタバタと開閉の音がします。
したがって、リレーの電源は、書き込みが終わって、リセットがかかった後にONにするように運用します。
コラム デバッグ情報
接続がうまくいかないときに、情報が必要です。loggingというライブラリが少しだけ情報を提供してくれます。
from pyModbusTCP.client import ModbusClient
import time
import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s '
'%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
SERVER_HOST = "192.168.111.100"
SERVER_PORT = 502
c = ModbusClient()
# uncomment this line to see debug message
c.debug(True)
# define modbus server host, port
c.host(SERVER_HOST)
c.port(SERVER_PORT)
c.unit_id(1)
c.open()
#regs = c.write_single_coil(1,True)
regs = c.write_single_coil(0,0)
log.debug(regs)
c.close()
コラム パケット・キャプチャ
ネットワークのアクセスは目に見えません。解析ソフトWireSharkを利用します。実行しているPCは192.168.111.109、MKR WiFi1010は192.168.111.100です。