Pythonでmodbus rtu通信 ~スレーブ機器にデータ書き込み~
本記事ではPythonでmodbus通信ができるライブラリ「pymodbus」の導入編として基本的な使い方を書いていきます。
modbus通信には通信方式として「RTU」「TCP」「ASCII」の3つがありますが、この記事ではRS-232などのシリアル接続を介して使用する「modbus RTU」を扱います。
前回、スレーブ機器からデータを取得する方法について書きましたが、今回はスレーブ機器に対してデータを書き込む方法について書いていきます。前回の記事はこちらをご参照ください。
環境
・windows 10(64bit)
・python 3.8.2(32bit版)
・エディタ Visual Studio Code 1.53.1
スレーブ機器にデータ書き込み
パソコン側で以下のコードを書いてスレーブ機器からデータを取得します。以下の例では「write_registers」の関数をしようしています。ファンクションコードを使用しています。
COMポート番号やパリティ、ボーレートなどは接続したい機器の通信仕様にあわせて設定してください。
# =================================================
# ライブラリインポート
# =================================================
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
# =================================================
# modbus処理
# =================================================
#---------- 接続開始 ----------#
client = ModbusClient(method = "rtu", port="COM7",stopbits = 1, bytesize = 8, parity = 'E', baudrate= 115200, timeout= 1)
client.connect()
#---------- データ読み出し ----------#
# address : レジスタ番号
# count : 読み出すレジスタ数
# unit : スレーブ装置の番号
result = client.read_holding_registers(address=100, count=1, unit= 1)
# 読み出したデータをコンソール画面に出力
print(result.registers)
#---------- データ書き込み ----------#
# address : レジスタ番号
# values : 書き込みたいデータ
# unit : スレーブ装置の番号
request = client.write_registers(address=100, values=1, unit= 1)
print(request)
#---------- 接続終了 ----------#
client.close()
あとはmodbus通信が実装された機器とハードウェアで接続(例えばUSB-RS232ケーブルなど)して上記のコードを実行すれば良いです。
処理は上から順番に行われていくので、エディタのコンソール画面にはレジスタ番号100の取得データが出力され、そのあとにデータの書き込みが行われ、書き込んだデータがコンソール画面に出力されます。
参考
pymodbusのライブラリにある関数を参照してみると以下のように定義されています。pymodbusはインターネット上に日本語の情報がまだ少ないように感じたので、困ったときはこのように関数の定義を参照してみると良いかもしれません。「Write Multiple Registers」のクラス定義に関してはコードが長くなるので先頭の一部だけ抜粋して記載しておきます。
def write_registers(self, address, values, **kwargs):
'''
:param address: The starting address to write to
:param values: The values to write to the specified address
:param unit: The slave unit this request is targeting
:returns: A deferred response handle
'''
request = WriteMultipleRegistersRequest(address, values, **kwargs)
return self.execute(request)
#---------------------------------------------------------------------------#
# Write Multiple Registers
#---------------------------------------------------------------------------#
class WriteMultipleRegistersRequest(ModbusRequest):
'''
This function code is used to write a block of contiguous registers (1
to approx. 120 registers) in a remote device.
The requested written values are specified in the request data field.
Data is packed as two bytes per register.
'''
function_code = 16
_rtu_byte_count_pos = 6
_pdu_length = 5 #func + adress1 + adress2 + outputQuant1 + outputQuant2
おわりに
ライブラリ化されていてmodbus通信について詳しくない方でも使いやすくなっている点がpymodbusのメリットだと思います。個人的にはESP32などのマイコンと組み合わせて、wifiで受信したデータをPCに取り込んだりということをやってみたいなと考えています。
何かお役に立てたら、サポートしていただけると嬉しいです!モチベーションを高めて、アウトプットしていきます!