【第5回】Pythonで外部計測機器とModbus通信をしてみた!
IT技術
PythonでModbus 通信をしてみよう!
今回は、計測機器を制御する通信プロトコルである「Modbus 通信」を Python で行う方法を紹介します。
オシロスコープを外部から制御する通信プロトコルには NI-VISA がありますが、一般的には Modbus プロトコルの方が主流です。
通常の Modbus 通信には、制御命令を送信する中継装置「PLC」が必要です。
しかし、今回はこうした PLC を使わずに、PC 上の Python のみで Modbus 通信をしてみましょう!
前回の記事はこちら
Modbus プロトコルとは?
PLC との通信のために開発されたプロトコル
先述の中継装置「PLC」は、あらかじめ設定された複数の制御命令を、接続された機器に対して送信する役割を持っています。
Modbus は、その際の通信プロトコルとして開発されました。
仕様が一般公開されているため、製品を問わず簡単に実装することができます。
1つのマスターに対して、複数のスレーブと同時に通信することに長けており、幅広い産業機器で採用されています。
Modbus のモードは3つ
Modbus には、下記の3つのモードがあります。
- ASCII 方式(連続した ASCII コードを送信)
- RTU 方式(短時間で通信可能)
- TCP 方式(TCP/IP に対応)
今回は、最も主流なモードである「RTU 方式」を採用します。
Python で Modbus 通信を行うメリット
では、わざわざ Python で Modbus 通信を行うメリットは何でしょうか?
ずばり、「他の計測機器や制御機器との連携」です。
今までの記事で紹介したオシロスコープ連携の手法と組み合わせることで、幅広い応用が可能です。
例えば、「外部制御機器に特定の動作命令を出しつつ、その時の電気信号の波形を測定する」なんてことも、完全自動化できますよ!
①minimalmodbus モジュールをインストール
それでは、さっそく準備にかかりましょう。
まずは、Modbus 通信を行うために必要な「minimalmodbus モジュール」をインストールします。
minimalmodbus モジュールは、通信したいアドレスやデータ値を引数に設定するだけでリード・ライトが行えます。
モジュールのインポートと設定
モジュールをインポートしたら、モジュールのクラス変数を設定していきます。
1import minimalmodbus as modbus
2import serial
3
4modbus.baudrate = 57600
5modbus.bytesize = 8
6modbus.stopbits = 1
7modbus.timeout=1 #[sec]
8modbus.parity= serial.PARITY_NONE
9modbus.CLOSE_PORT_AFTER_EACH_CALL=True
baudrate
通信レートのことです。
通信する対象が対応するレート値にしなければなりません。
ここでは、仮で「57600bps」という設定にしています。
bytesize
1バイトあたりのデータ点数です。
その名の通り、8bit で8個分というのが一般的です。
stopbits
データの終わりを示す目印の設定です。
通常は「1」です。
timeout
データ送信後に応答が返ってきていないとみなすまでの時間です。
ここでは、1秒としておきます。
parity
通信データが正常かを簡易的に判断するためのビットです。
通信の全 bit 値を合計したときの 1bit 目の値で、データが破損していないかを判断します。
送信側があらかじめ計算しておいた parity 値をデータに合わせて送信し、受信側が独自に計算した parity 値が一致すれば、正常に通信が行われたと判断されます。
設定では、合計値が偶数と奇数のどちらかで「1」とするかを決められます。
ここでは、parity を使用しないため、「serial.PARITY_NONE」を設定します。
CLOSE_PORT_AFTER_EACH_CALL
通信終了時に、毎回ポートをクローズするかを選択できます。
毎回クローズした方が通信不具合を防げるので、「True」を選択するのが一般的です。
インスタンス生成で通信準備
設定が済んだら、pyvisa と同じように、インスタンスを生成することで通信ができるようにします。
1inst = modbus.Instrument('COM5',1,modbus.MODE_RTU)
接続するポートは、PC であれば USB ポート番号にあたります。
ここでは、仮で「COM5」と設定しました。
後ろにある1は、通信を行う対象スレーブの番号で、1対1の場合は、そのまま1となります。
最後に、Modbus モードを設定して準備は完了です。
②特定アドレスへの読み出しと書き込み
読み出し
「読み出し」は、接続されている機器の状態や検出値を取得するために使用されます。
エラーが発生しているか調べたり、マルチメータの表示値を知ることもできます。
特定のアドレスから読み出しを行うには、以下のようにします。
1rd_data = inst.read_register(int(0x1001),functioncode=3,signed = False)
「アドレス」「ファンクションコード」「読み出し値の符号有無」を選択すると、読み出し値を変数に格納できます。
読み出しのファンクションコードは「3」です。
特定アドレスへの書き込み
次は、書き込みです。
「書き込み」は、接続されている機器に命令を与えたり、設定を変える時に使用します。
例として、モータドライバならモータの駆動を開始したり、駆動速度を変えたりすることができるのです。
1inst.write_register(int(0x1001),value = 16,functioncode=6,signed = False)
このように「アドレス」「書き込む値」「ファンクションコード」「書き込む値の符号有無」を選択すると、処理が実行されます。
書き込みのファンクションコードは「6」を指定してください。
Minimalmodbus による Modbus 通信コード
最後に、Modbus RTU による書き込みと読み出しができるコードのサンプルを紹介します。
実際に接続する機器の仕様をよく確認し、設定を書き換えた上で使用してください。
1import minimalmodbus as modbus
2import serial
3
4#minimalmodbusの設定
5modbus.baudrate = 57600 #接続する機器に応じて設定変更
6modbus.bytesize = 8 #接続する機器に応じて設定変更
7modbus.stopbits = 1 #接続する機器に応じて設定変更
8modbus.timeout=1 #単位sec:接続先に合わせる必要はない
9modbus.parity= serial.PARITY_NONE #接続する機器に応じて設定変更
10modbus.CLOSE_PORT_AFTER_EACH_CALL=True
11inst = modbus.Instrument('COM__',1,modbus.MODE_RTU) #COM_は使用するパソコンのシリアルポートに合わせる
12
13#アドレス0x1001への読み出し処理
14rd_data = inst.read_register(int(0x1001),functioncode=3,signed = False)
15print(rd_data)
16
17#アドレス0x1001への書き込み処理
18inst.write_register(int(0x1001),value = 16,functioncode=6,signed = False)
さいごに
今回は、「Python で Modbus 通信を行う方法」を解説しました。
Modbus 対応機器であれば、minimalmodbus モジュールを使うことで、オシロスコープの遠隔制御と同様のことが再現可能です。
また、minimalmodbus は、通信データ生成で本来必要な CRC の計算も不要なので、非常に便利ですよ。
オシロスコープなどと連携して、計測を効率よく自動化しましょう!
第1回はこちら!
こちらの記事もオススメ!
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
2020.07.30Python 特集実装編※最新記事順Responder + Firestore でモダンかつサーバーレスなブログシステムを作ってみた!P...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit