はじめての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 なし

Modbusの仕様 日本語の参考資料 

サンプル・スケッチ

 前回と同様に、MKRシリーズのマイコン・ボードでは、ライブラリはArduinoModbusとArduino RS485の二つが必要です。サンプル・スケッチのWiFiModbusServerLEDを読み込みます。別ファイルのarduino_secrets.hにSSIDとパスフレーズを書き込みます。MKR WiFi1010のインターネット・アクセス関連はWiFiNINAのライブラリを使います。こちらにいくつか解説しています。

 スケッチは変更せずに、コンパイルし実行します。このスケッチは、Modbus/TCPのサーバのアプリケーションです。

 スレーブがアクセスしてきて、ファンクションForce Single Coil(05)を使ってONを指示すると、MKR WiFi1010ボードのLEDが点灯する。OFFを指示すると、LEDは消灯する。
 LEDは、サンプルBlink.inoと同じ場所のD6ポートにつながっている。

 実装されているのは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です。

前へ

はじめてのModbus (1) 電力量モニタKM-N1-FLK

次へ

ESP32入門 通信機能が標準搭載されたマイコン・ボード (10) 測定した温度をWebに表示②