rikuya-h
2025年3月28日 10時02分
お世話になっております。
Armadillo-IoT G4 にて開発を進めておりますが
RS-485通信を行う必要が出てきたため、以下のUSBとのコンバータを使用
https://www.switch-science.com/products/8426
RS-485通信にあまり知見が無く...試しに
PCとArmadillo-IoT G4間で通信させたく思うのですが
上手く通信させる事が出来ておりません。
ご教授頂けると大変助かります。
※PC(ドライバーインストール済み)及びArmadillo側でのコンバータ認識は出来ております。
コメント
rikuya-h
> アットマークテクノの下山です。
>
> まず、お互いのコンバータのA+・B+・GNDを接続した状態であることを確認してください。
> PC側のコンバータをTeratermなどで表示している場合は、改行コードを送信・受信ともにLFに設定してください。
>
> ■通信設定
> G4の通信設定を以下のように設定します
> ここでは、baudrateを115200として設定してます、PC側も同じbaudrateに設定してください
>
> armadillo:~# stty -F /dev/ttyACM0 speed 115200 parenb -parodd brkint ignpar -icrnl -ixon -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke >
>
> ■G4から送信する場合
> 以下のコマンドでPC側に文字は表示されますでしょうか?
>
> armadillo:~# echo "hello" > /dev/ttyACM0 >
>
> ■G4が受信する場合
> 以下のコマンドを実行してから、PC側で文字入力+EnterでG4側のコンソールに文字は表示されますでしょうか?
>
> armadillo:~# while read var ; do echo $var ; done < /dev/ttyACM0 >
>
> よろしくお願いします
上記手順でPC側及びG4側で文字出力を確認出来ました!
ありがとうございます。
続けてで恐縮ですが、
これらで実験的にModbus Protocolを用いた通信を行いたいのですが、
どの様に設定し、操作すれば良いかもご教授頂けると大変助かります。
at_shota.shimoyama
rikuya-h
at_shota.shimoyama
> 実運用でもPythonを使用しようと考えていました。
> G4がマスター側になります。
本来はABOSDEでPythonプロジェクトから実行環境などを用意するのが望ましいのですが、
実験的に手っ取り早く確かめるなら、ABOS上に直接インストールしてスクリプトを実行することもできます。
■パッケージ等のインストール
armadillo:~# apk update armadillo:~# apk add python3 py3-pip armadillo:~# pip3 install pymodbus pyserial --break-system-packages
■スクリプト
例えばスレーブIDが1のデバイスの入力レジスタ0x07d0から10ワード読み取る(read_input_registers)処理は次のようになります。
そのあたりやbaudrateについては適宜変更してください。
from pymodbus.client import ModbusSerialClient client = ModbusSerialClient( port='/dev/ttyACM0', baudrate=115200, parity='N', stopbits=1, bytesize=8, timeout=3, ) if client.connect(): print("client.connect() OK") else: print("client.connect() Failed") exit() reg = client.read_input_registers(0x07d0, count=10, slave=1) if not reg.isError(): r = reg.registers print(r) else: print("Error read_input_registers 0x07d0") client.close()
また、/dev/ttyACM0がデバイスファイル名になるだけで、RS-485やModbus/RTUの使用方法においてArmadilloに固有の操作などは特にありませんので、インターネットから得られる一般的な情報を参考にできます。
PyModbusの使用方法などについては
https://pymodbus.readthedocs.io/en/v3.8.6/
などを参照してください。
rikuya-h
ご無沙汰しております。
頂いたコメントにて参考にArmadilloを"マスター"にした際の方法で開発を進めています。
ただ、最近Armadilloを"スレーブ"にした際の簡単な検証をしたところレジスタの初期化が上手くいかず悩んでいます。
Armadillo G4 Slave side
import asyncio import pymodbus from pymodbus.server import StartAsyncSerialServer from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext async def run(): store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100)) slaves = { 0x01: store, } context = ModbusServerContext(slaves=slaves, single=False) await StartAsyncSerialServer(context=context, port="/dev/ttyACM0", baudrate=115200, stopbits=1, bytesize=8, parity="N") if __name__ == "__main__": pymodbus.pymodbus_apply_logging_config("DEBUG") asyncio.run( run(), debug=True )
PC Master side
from pymodbus.client import ModbusSerialClient import pymodbus def run(): client = ModbusSerialClient( port='COM15', baudrate=115200, parity='N', stopbits=1, bytesize=8, timeout=3, ) if client.connect(): print("client.connect() OK") else: print("client.connect() Failed") exit() # ホールディングレジスタを読み取る reg = client.read_holding_registers(0x00, count=10, slave=1) if not reg.isError(): r = reg.registers print("HR読み取ったレジスタ:", r) else: print("Error read_holding_registers 0x00") # インプットレジスタを読み取る reg = client.read_input_registers(0x00, count=10, slave=1) if not reg.isError(): r = reg.registers print("IR読み取ったレジスタ:", r) else: print("Error read_input_registers 0x00") client.close() if __name__ == "__main__": pymodbus.pymodbus_apply_logging_config("DEBUG") run()
Armadillo G4 側出力
2025-06-20 12:06:28,510 DEBUG transport:256 Awaiting connections server_listener 2025-06-20 12:06:28,516 INFO base:85 Server listening. 2025-06-20 12:06:28,518 DEBUG transport:277 Connected to server 2025-06-20 12:06:32,706 DEBUG transport:329 recv: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd old_data: addr=None 2025-06-20 12:06:32,706 DEBUG base:91 Processing: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd 2025-06-20 12:06:32,707 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-06-20 12:06:32,707 DEBUG base:101 Frame advanced, resetting header!! 2025-06-20 12:06:32,711 DEBUG context:121 getValues: fc-[3] address-1: count-10 2025-06-20 12:06:32,712 DEBUG transport:386 send: 0x1 0x3 0x14 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xa3 0x67 2025-06-20 12:06:32,723 DEBUG transport:329 recv: 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd old_data: addr=None 2025-06-20 12:06:32,724 DEBUG base:91 Processing: 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd 2025-06-20 12:06:32,724 DEBUG decoders:113 decoded PDU function_code(4 sub -1) -> ReadInputRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-06-20 12:06:32,724 DEBUG base:101 Frame advanced, resetting header!! 2025-06-20 12:06:32,726 DEBUG context:121 getValues: fc-[4] address-1: count-10 2025-06-20 12:06:32,727 DEBUG transport:386 send: 0x1 0x4 0x14 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x95 0x81
PC 側出力
client.connect() OK 2025-06-20 12:06:32,746 DEBUG base:91 Processing: 0x1 0x3 0x14 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xa3 0x67 2025-06-20 12:06:32,746 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersResponse(dev_id=0, transaction_id=0, address=0, count=0, bits=[], registers=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], status=1) 2025-06-20 12:06:32,747 DEBUG base:101 Frame advanced, resetting header!! HR読み取ったレジスタ: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 2025-06-20 12:06:32,761 DEBUG base:91 Processing: 0x1 0x4 0x14 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x95 0x81 2025-06-20 12:06:32,761 DEBUG decoders:113 decoded PDU function_code(4 sub -1) -> ReadInputRegistersResponse(dev_id=0, transaction_id=0, address=0, count=0, bits=[], registers=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], status=1) 2025-06-20 12:06:32,761 DEBUG base:101 Frame advanced, resetting header!! IR読み取ったレジスタ: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
以下コードで初期値を設定しているはずですが、"0"が値としては返ってきてしまっています。
store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100))
"マスター:Armadillo G4","スレーブ:PC"の関係だと正しく動作するのですが、 "スレーブ:Armadillo G4"だと正しく動作しない様に見えます。
私の勉強不足かもしれませんが、何か分かればご教示頂けると助かります。
at_shota.shimoyama
rikuya-h 様
こちらでも再現できました(マスターがPC・Armadillo G4のどちらであっても起こりました)
原因を調べてみたのですが、pymodbusライブラリ内のバグ(仕様?)でした…
ModbusSlaveContext(...)
のところで、di=...
の引数も指定しないと、他のco=... , ir=... , hr=...
は無効になります
例えば、添付いただいたコードでは、
store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100))
となっていますが、di=...
の指定がないため、hrとirはデフォルトの [0]*65536 になってしまいます。(そのため0しか読み取れない)
ですので、何かテキトーな数値でよいので、以下のようにdi=...
も指定してください
store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [1]), hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100))
ちなみに、pipでインストールできるpymodbusの最新バージョン(3.9.2)だと上記のバグがありますが、
githubで公開されているレポジトリでは4月末に修正されたようです↓
https://github.com/pymodbus-dev/pymodbus/commit/eb84cfef92ddab8780652bd…
3.9.2より新しいバージョンが公開されたら、もしかしたらこのバグも治るかもしれません
rikuya-h
> rikuya-h 様
>
> こちらでも再現できました(マスターがPC・Armadillo G4のどちらであっても起こりました)
>
> 原因を調べてみたのですが、pymodbusライブラリ内のバグ(仕様?)でした…
> ModbusSlaveContext(...)
のところで、di=...
の引数も指定しないと、他のco=... , ir=... , hr=...
は無効になります
>
> 例えば、添付いただいたコードでは、
>
> store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100)) >
> となっていますが、di=...
の指定がないため、hrとirはデフォルトの [0]*65536 になってしまいます。(そのため0しか読み取れない)
>
> ですので、何かテキトーな数値でよいので、以下のようにdi=...
も指定してください
>
> store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [1]), hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100)) >
>
> ちなみに、pipでインストールできるpymodbusの最新バージョン(3.9.2)だと上記のバグがありますが、
> githubで公開されているレポジトリでは4月末に修正されたようです↓
> https://github.com/pymodbus-dev/pymodbus/commit/eb84cfef92ddab8780652bd…
>
> 3.9.2より新しいバージョンが公開されたら、もしかしたらこのバグも治るかもしれません
at_shota.shimoyama様
ご丁寧な回答ありがとうございます!
バグ(仕様)だったとの事で現時点での修正案
diを追加する事で私の環境でも期待通りの動作になりました。
これで開発を進められます。ありがとうございました。
rikuya-h
以前の投稿ではありがとうございました。
続けてで申し訳ありません。
現在Armadillo 実機を用いてデイジーチェーン接続した際の検証をしています。
開発環境手元にrs485通信可能な他デバイスが無い為、Armadilloにてpymodbusを使用してエミュレートしています。
検証中、エラーとなり手詰まりを感じているので知見がありましたらご教授頂けますと幸いです。
構成としてはArmadillo A9E 2台と Armadillo G4 1台(usb to rs485コンバータ使用)をデイジーチェーン接続をして検証しています。
Armadillo A9E 001 をマスター側として設定
Armadillo A9E 002 及び Armadillo G4を
それぞれ Slave 01 , Slave 02 として設定
Master コード (Armadillo A9E 001)
from pymodbus.client import ModbusSerialClient import pymodbus def run(): client = ModbusSerialClient( port='/dev/ttyrpmsg1', baudrate=115200, parity='N', stopbits=1, bytesize=8, timeout=3, ) if client.connect(): print("client.connect() OK") else: print("client.connect() Failed") exit() # slave 001 ホールディングレジスタを読み取る reg = client.read_holding_registers(0x00, count=10, slave=1) if not reg.isError(): r = reg.registers print("Slave 001 HR読み取ったレジスタ:", r) else: print("Slave 001 Error read_holding_registers 0x00") # slave 001 インプットレジスタを読み取る reg = client.read_input_registers(0x00, count=10, slave=1) if not reg.isError(): r = reg.registers print("Slave 001 IR読み取ったレジスタ:", r) else: print("Slave 001 Error read_input_registers 0x00") # slave 002 ホールディングレジスタを読み取る reg = client.read_holding_registers(0x00, count=10, slave=2) if not reg.isError(): r = reg.registers print("Slave 002 HR読み取ったレジスタ:", r) else: print("Slave 002 Error read_holding_registers 0x00") # slave 002 インプットレジスタを読み取る reg = client.read_input_registers(0x00, count=10, slave=2) if not reg.isError(): r = reg.registers print("Slave 002 IR読み取ったレジスタ:", r) else: print("Slave 002 Error read_input_registers 0x00") client.close() if __name__ == "__main__": pymodbus.pymodbus_apply_logging_config("DEBUG") run()
Slave 001 コード (Armadillo A9E 002)
import asyncio import pymodbus from pymodbus.server import StartAsyncSerialServer from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext async def run(): store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [1]), hr=ModbusSequentialDataBlock(0, [20] * 100),ir=ModbusSequentialDataBlock(0, [21] * 100)) slaves = { 0x01: store, } context = ModbusServerContext(slaves=slaves, single=False) await StartAsyncSerialServer(context=context, port="/dev/ttyrpmsg1", baudrate=115200, stopbits=1, bytesize=8, parity="N") if __name__ == "__main__": pymodbus.pymodbus_apply_logging_config("DEBUG") asyncio.run( run(), debug=True )
Slave 002 コード (Armadillo G4)
import asyncio import pymodbus from pymodbus.server import StartAsyncSerialServer from pymodbus.datastore import ModbusSequentialDataBlock from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext async def run(): store = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [1]), hr=ModbusSequentialDataBlock(0, [18] * 100),ir=ModbusSequentialDataBlock(0, [19] * 100)) slaves = { 0x02: store, } context = ModbusServerContext(slaves=slaves, single=False) await StartAsyncSerialServer(context=context, port="/dev/ttyACM0", baudrate=115200, stopbits=1, bytesize=8, parity="N") if __name__ == "__main__": pymodbus.pymodbus_apply_logging_config("DEBUG") asyncio.run( run(), debug=True )
Master エラー (Armadillo A9E 001)
client.connect() OK 2025-07-01 12:47:15,978 DEBUG base:91 Processing: 0x1 0x80 0xb 0x0 0x7 2025-07-01 12:47:15,979 DEBUG decoders:109 decode PDU failed for function code 128 2025-07-01 12:47:15,980 WARNING decoders:121 Unable to decode frame Modbus Error: Unknown response 128 Traceback (most recent call last): File "//vol_app/observe_lib/modbus_master_simple.py", line 53, in <module> run() File "//vol_app/observe_lib/modbus_master_simple.py", line 20, in run reg = client.read_holding_registers(0x00, count=10, slave=1) File "/usr/local/lib/python3.9/dist-packages/pymodbus/client/mixin.py", line 114, in read_holding_registers return self.execute(no_response_expected, pdu_reg.ReadHoldingRegistersRequest(address=address, count=count, dev_id=slave)) File "/usr/local/lib/python3.9/dist-packages/pymodbus/client/base.py", line 203, in execute return self.transaction.sync_execute(no_response_expected, request) File "/usr/local/lib/python3.9/dist-packages/pymodbus/transaction/transaction.py", line 113, in sync_execute return self.sync_get_response(request.dev_id) File "/usr/local/lib/python3.9/dist-packages/pymodbus/transaction/transaction.py", line 87, in sync_get_response used_len, pdu = self.framer.processIncomingFrame(databuffer) File "/usr/local/lib/python3.9/dist-packages/pymodbus/framer/base.py", line 76, in processIncomingFrame data_len, pdu = self._processIncomingFrame(data[used_len:]) File "/usr/local/lib/python3.9/dist-packages/pymodbus/framer/base.py", line 98, in _processIncomingFrame raise ModbusIOException("Unable to decode request") pymodbus.exceptions.ModbusIOException: Modbus Error: [Input/Output] Unable to decode request
Slave 001 エラー (Armadillo A9E 002)
2025-07-01 12:47:11,049 DEBUG transport:256 Awaiting connections server_listener 2025-07-01 12:47:11,059 INFO base:85 Server listening. 2025-07-01 12:47:11,062 DEBUG transport:277 Connected to server 2025-07-01 12:47:15,930 DEBUG transport:329 recv: 0x1 old_data: addr=None 2025-07-01 12:47:15,931 DEBUG base:91 Processing: 0x1 2025-07-01 12:47:15,931 DEBUG rtu:108 Short frame: 0x1 wait for more data 2025-07-01 12:47:15,932 DEBUG transport:341 recv, unused data waiting for next packet: 0x1 2025-07-01 12:47:15,933 DEBUG transport:329 recv: 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd old_data: 0x1 addr=None 2025-07-01 12:47:15,934 DEBUG base:91 Processing: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd 2025-07-01 12:47:15,935 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 12:47:15,935 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 12:47:15,940 DEBUG context:120 validate: fc-[3] address-1: count-10 2025-07-01 12:47:15,941 DEBUG context:132 getValues: fc-[3] address-1: count-10 2025-07-01 12:47:15,942 DEBUG transport:386 send: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 2025-07-01 12:47:15,945 DEBUG transport:329 recv: 0x1 0x80 0xb 0x0 0x7 old_data: addr=None 2025-07-01 12:47:15,945 DEBUG base:91 Processing: 0x1 0x80 0xb 0x0 0x7 2025-07-01 12:47:15,946 DEBUG decoders:109 decode PDU failed for function code 128 2025-07-01 12:47:15,947 WARNING decoders:121 Unable to decode frame Modbus Error: Unknown response 128 2025-07-01 12:47:15,948 ERROR pdu:128 Exception response 168 / 1 2025-07-01 12:47:15,948 DEBUG transport:386 send: 0x1 0xa8 0x1 0x9e 0x0
Slave 002 エラー (Armadillo G4)
2025-07-01 12:47:13,156 DEBUG transport:256 Awaiting connections server_listener 2025-07-01 12:47:13,161 INFO base:85 Server listening. 2025-07-01 12:47:13,162 DEBUG transport:277 Connected to server 2025-07-01 12:47:15,956 DEBUG transport:329 recv: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd old_data: addr=None 2025-07-01 12:47:15,957 DEBUG base:91 Processing: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd 2025-07-01 12:47:15,957 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 12:47:15,957 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 12:47:15,961 ERROR requesthandler:112 requested slave does not exist: 1 2025-07-01 12:47:15,962 DEBUG transport:386 send: 0x1 0x80 0xb 0x0 0x7 2025-07-01 12:47:15,983 DEBUG transport:329 recv: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 0x1 0xa8 0x1 0x9e 0x0 old_data: addr=None 2025-07-01 12:47:15,984 DEBUG base:91 Processing: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 0x1 0xa8 0x1 0x9e 0x0 2025-07-01 12:47:15,984 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 12:47:15,984 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 12:47:15,985 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 12:47:15,985 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 12:47:15,985 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. Exception in callback SerialTransport.intern_read_ready() handle: <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> source_traceback: Object created at (most recent call last): File "/tmp/test_slave01_simple.py", line 17, in <module> asyncio.run( File "/usr/lib/python3.12/asyncio/runners.py", line 195, in run return runner.run(main) File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) File "/usr/lib/python3.12/asyncio/base_events.py", line 678, in run_until_complete self.run_forever() File "/usr/lib/python3.12/asyncio/base_events.py", line 645, in run_forever self._run_once() File "/usr/lib/python3.12/asyncio/base_events.py", line 1991, in _run_once handle._run() File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 44, in setup self.async_loop.add_reader(self.sync_serial.fileno(), self.intern_read_ready) File "/usr/lib/python3.12/asyncio/selector_events.py", line 357, in add_reader self._add_reader(fd, callback, *args) File "/usr/lib/python3.12/asyncio/selector_events.py", line 280, in _add_reader handle = events.Handle(callback, args, self, None) Traceback (most recent call last): File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 134, in intern_read_ready self.intern_protocol.data_received(data) # type: ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 304, in data_received self.datagram_received(data, None) File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 338, in datagram_received cut = self.callback_data(self.recv_buffer, addr=addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/server/requesthandler.py", line 79, in callback_data used_len = super().callback_data(data, addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transaction/transaction.py", line 217, in callback_data used_len, pdu = self.framer.processIncomingFrame(self.trace_packet(False, data)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 76, in processIncomingFrame data_len, pdu = self._processIncomingFrame(data[used_len:]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 97, in _processIncomingFrame if (result := self.decoder.decode(frame_data)) is None: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/pdu/decoders.py", line 112, in decode pdu.decode(frame[1:]) File "/usr/lib/python3.12/site-packages/pymodbus/pdu/register_message.py", line 26, in decode self.address, self.count = struct.unpack(">HH", data) ^^^^^^^^^^^^^^^^^^^^^^^^^^ struct.error: unpack requires a buffer of 4 bytes Executing <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> took 0.343 seconds ^C2025-07-01 12:48:59,451 INFO base:89 Server graceful shutdown.
コード及びエラーは以上になります。
at_shota.shimoyama
Master から Slave 001 宛てにデータを送ると、通信線を共有しているため Slave 002 にも当然そのデータが送られることになるのですが、
「Slave 002 エラー (Armadillo G4)」ログの方で、「slave 1が見つかりません」というエラーが出ていて、その直後にSlave 002から「0x1 0x80 0xb 0x0 0x7」(エラーコード?)を送っているようです↓
2025-07-01 12:47:15,956 DEBUG transport:329 recv: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd old_data: addr=None ... 2025-07-01 12:47:15,961 ERROR requesthandler:112 requested slave does not exist: 1 2025-07-01 12:47:15,962 DEBUG transport:386 send: 0x1 0x80 0xb 0x0 0x7
requested slave does not exist
は以下の部分で出力されています。その後のExceptionResponse(...)
が「0x1 0x80 0xb 0x0 0x7」に対応しているかもしれません。
https://github.com/pymodbus-dev/pymodbus/blob/e73e28c1eb7d42949e03ded7f…
おそらくですが、対象ではないslaveからエラーコードを送らせないようにするためには、
ignore_missing_slaves
を True に設定する必要があると思います(デフォルトはFalse)
両方のslaveでこのオプションを追加してみてください。
await StartAsyncSerialServer(context=context, port="/dev/ttyrpmsg1", baudrate=115200, stopbits=1, bytesize=8, parity="N", ignore_missing_slaves=True)
await StartAsyncSerialServer(context=context, port="/dev/ttyACM0", baudrate=115200, stopbits=1, bytesize=8, parity="N", ignore_missing_slaves=True)
rikuya-h
頂いたアドバイスにてオプションを追加しましたが、状況変わらずでした。
Master エラー
client.connect() OK 2025-07-01 16:18:45,987 DEBUG base:91 Processing: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 2025-07-01 16:18:45,988 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersResponse(dev_id=0, transaction_id=0, address=0, count=0, bits=[], registers=[20, 20, 20, 20, 20, 20, 20, 20, 20, 20], status=1) 2025-07-01 16:18:45,989 DEBUG base:101 Frame advanced, resetting header!! Slave 001 HR読み取ったレジスタ: [20, 20, 20, 20, 20, 20, 20, 20, 20, 20] 2025-07-01 16:18:46,011 DEBUG base:91 Processing: 0x1 0x4 0x14 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x4a 0x15 2025-07-01 16:18:46,012 DEBUG decoders:113 decoded PDU function_code(4 sub -1) -> ReadInputRegistersResponse(dev_id=0, transaction_id=0, address=0, count=0, bits=[], registers=[21, 21, 21, 21, 21, 21, 21, 21, 21, 21], status=1) 2025-07-01 16:18:46,013 DEBUG base:101 Frame advanced, resetting header!! Slave 001 IR読み取ったレジスタ: [21, 21, 21, 21, 21, 21, 21, 21, 21, 21] 2025-07-01 16:18:58,023 ERROR transaction:123 No response received after 3 retries, continue with next request Traceback (most recent call last): File "//vol_app/observe_lib/modbus_master_simple.py", line 53, in <module> run() File "//vol_app/observe_lib/modbus_master_simple.py", line 35, in run reg = client.read_holding_registers(0x00, count=10, slave=2) File "/usr/local/lib/python3.9/dist-packages/pymodbus/client/mixin.py", line 114, in read_holding_registers return self.execute(no_response_expected, pdu_reg.ReadHoldingRegistersRequest(address=address, count=count, dev_id=slave)) File "/usr/local/lib/python3.9/dist-packages/pymodbus/client/base.py", line 203, in execute return self.transaction.sync_execute(no_response_expected, request) File "/usr/local/lib/python3.9/dist-packages/pymodbus/transaction/transaction.py", line 124, in sync_execute raise ModbusIOException(txt) pymodbus.exceptions.ModbusIOException: Modbus Error: [Input/Output] No response received after 3 retries, continue with next request
Slave 001 エラー
2025-07-01 16:18:44,272 DEBUG transport:256 Awaiting connections server_listener 2025-07-01 16:18:44,281 INFO base:85 Server listening. 2025-07-01 16:18:44,284 DEBUG transport:277 Connected to server 2025-07-01 16:18:45,957 DEBUG transport:329 recv: 0x1 0x3 old_data: addr=None 2025-07-01 16:18:45,958 DEBUG base:91 Processing: 0x1 0x3 2025-07-01 16:18:45,958 DEBUG rtu:108 Short frame: 0x1 0x3 wait for more data 2025-07-01 16:18:45,959 DEBUG transport:341 recv, unused data waiting for next packet: 0x1 0x3 2025-07-01 16:18:45,960 DEBUG transport:329 recv: 0x0 0x0 0x0 0xa 0xc5 0xcd old_data: 0x1 0x3 addr=None 2025-07-01 16:18:45,961 DEBUG base:91 Processing: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd 2025-07-01 16:18:45,962 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:45,962 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:45,967 DEBUG context:120 validate: fc-[3] address-1: count-10 2025-07-01 16:18:45,968 DEBUG context:132 getValues: fc-[3] address-1: count-10 2025-07-01 16:18:45,969 DEBUG transport:386 send: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 2025-07-01 16:18:45,982 DEBUG transport:329 recv: 0x1 0x4 old_data: addr=None 2025-07-01 16:18:45,983 DEBUG base:91 Processing: 0x1 0x4 2025-07-01 16:18:45,983 DEBUG rtu:108 Short frame: 0x1 0x4 wait for more data 2025-07-01 16:18:45,984 DEBUG transport:341 recv, unused data waiting for next packet: 0x1 0x4 2025-07-01 16:18:45,985 DEBUG transport:329 recv: 0x0 0x0 0x0 0xa 0x70 0xd old_data: 0x1 0x4 addr=None 2025-07-01 16:18:45,986 DEBUG base:91 Processing: 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd 2025-07-01 16:18:45,987 DEBUG decoders:113 decoded PDU function_code(4 sub -1) -> ReadInputRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:45,987 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:45,992 DEBUG context:120 validate: fc-[4] address-1: count-10 2025-07-01 16:18:45,992 DEBUG context:132 getValues: fc-[4] address-1: count-10 2025-07-01 16:18:45,994 DEBUG transport:386 send: 0x1 0x4 0x14 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x4a 0x15 2025-07-01 16:18:46,006 DEBUG transport:329 recv: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe old_data: addr=None 2025-07-01 16:18:46,007 DEBUG base:91 Processing: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe 2025-07-01 16:18:46,008 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:46,009 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:46,013 ERROR requesthandler:115 requested slave does not exist: 2 2025-07-01 16:18:49,011 DEBUG transport:329 recv: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe old_data: addr=None 2025-07-01 16:18:49,012 DEBUG base:91 Processing: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe 2025-07-01 16:18:49,013 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:49,013 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:49,018 ERROR requesthandler:115 requested slave does not exist: 2 2025-07-01 16:18:52,013 DEBUG transport:329 recv: 0x2 0x3 0x0 0x0 old_data: addr=None 2025-07-01 16:18:52,014 DEBUG base:91 Processing: 0x2 0x3 0x0 0x0 2025-07-01 16:18:52,014 DEBUG rtu:116 Frame - not ready 2025-07-01 16:18:52,015 DEBUG transport:341 recv, unused data waiting for next packet: 0x2 0x3 0x0 0x0 2025-07-01 16:18:52,016 DEBUG transport:329 recv: 0x0 0xa 0xc5 0xfe old_data: 0x2 0x3 0x0 0x0 addr=None 2025-07-01 16:18:52,017 DEBUG base:91 Processing: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe 2025-07-01 16:18:52,018 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:52,018 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:52,023 ERROR requesthandler:115 requested slave does not exist: 2 2025-07-01 16:18:55,016 DEBUG transport:329 recv: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe old_data: addr=None 2025-07-01 16:18:55,017 DEBUG base:91 Processing: 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe 2025-07-01 16:18:55,018 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:55,019 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:55,023 ERROR requesthandler:115 requested slave does not exist: 2
Slave 002 エラー
2025-07-01 16:18:39,999 DEBUG transport:256 Awaiting connections server_listener 2025-07-01 16:18:40,005 INFO base:85 Server listening. 2025-07-01 16:18:40,006 DEBUG transport:277 Connected to server 2025-07-01 16:18:45,996 DEBUG transport:329 recv: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd old_data: addr=None 2025-07-01 16:18:45,996 DEBUG base:91 Processing: 0x1 0x3 0x0 0x0 0x0 0xa 0xc5 0xcd 2025-07-01 16:18:45,996 DEBUG decoders:113 decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersRequest(dev_id=0, transaction_id=0, address=0, count=10, bits=[], registers=[], status=1) 2025-07-01 16:18:45,997 DEBUG base:101 Frame advanced, resetting header!! 2025-07-01 16:18:46,001 ERROR requesthandler:112 requested slave does not exist: 1 2025-07-01 16:18:46,013 DEBUG transport:329 recv: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 old_data: addr=None 2025-07-01 16:18:46,014 DEBUG base:91 Processing: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 Exception in callback SerialTransport.intern_read_ready() handle: <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> source_traceback: Object created at (most recent call last): File "/tmp/test_slave01_simple.py", line 17, in <module> asyncio.run( File "/usr/lib/python3.12/asyncio/runners.py", line 195, in run return runner.run(main) File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) File "/usr/lib/python3.12/asyncio/base_events.py", line 678, in run_until_complete self.run_forever() File "/usr/lib/python3.12/asyncio/base_events.py", line 645, in run_forever self._run_once() File "/usr/lib/python3.12/asyncio/base_events.py", line 1991, in _run_once handle._run() File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 44, in setup self.async_loop.add_reader(self.sync_serial.fileno(), self.intern_read_ready) File "/usr/lib/python3.12/asyncio/selector_events.py", line 357, in add_reader self._add_reader(fd, callback, *args) File "/usr/lib/python3.12/asyncio/selector_events.py", line 280, in _add_reader handle = events.Handle(callback, args, self, None) Traceback (most recent call last): File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 134, in intern_read_ready self.intern_protocol.data_received(data) # type: ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 304, in data_received self.datagram_received(data, None) File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 338, in datagram_received cut = self.callback_data(self.recv_buffer, addr=addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/server/requesthandler.py", line 79, in callback_data used_len = super().callback_data(data, addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transaction/transaction.py", line 217, in callback_data used_len, pdu = self.framer.processIncomingFrame(self.trace_packet(False, data)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 76, in processIncomingFrame data_len, pdu = self._processIncomingFrame(data[used_len:]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 97, in _processIncomingFrame if (result := self.decoder.decode(frame_data)) is None: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/pdu/decoders.py", line 112, in decode pdu.decode(frame[1:]) File "/usr/lib/python3.12/site-packages/pymodbus/pdu/register_message.py", line 26, in decode self.address, self.count = struct.unpack(">HH", data) ^^^^^^^^^^^^^^^^^^^^^^^^^^ struct.error: unpack requires a buffer of 4 bytes 2025-07-01 16:18:46,024 DEBUG transport:329 recv: 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd old_data: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 addr=None 2025-07-01 16:18:46,357 DEBUG base:91 Processing: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd 2025-07-01 16:18:46,357 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,358 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,358 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,358 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,358 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,359 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,359 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,359 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. Exception in callback SerialTransport.intern_read_ready() handle: <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> source_traceback: Object created at (most recent call last): File "/tmp/test_slave01_simple.py", line 17, in <module> asyncio.run( File "/usr/lib/python3.12/asyncio/runners.py", line 195, in run return runner.run(main) File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) File "/usr/lib/python3.12/asyncio/base_events.py", line 678, in run_until_complete self.run_forever() File "/usr/lib/python3.12/asyncio/base_events.py", line 645, in run_forever self._run_once() File "/usr/lib/python3.12/asyncio/base_events.py", line 1991, in _run_once handle._run() File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 44, in setup self.async_loop.add_reader(self.sync_serial.fileno(), self.intern_read_ready) File "/usr/lib/python3.12/asyncio/selector_events.py", line 357, in add_reader self._add_reader(fd, callback, *args) File "/usr/lib/python3.12/asyncio/selector_events.py", line 280, in _add_reader handle = events.Handle(callback, args, self, None) Traceback (most recent call last): File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 134, in intern_read_ready self.intern_protocol.data_received(data) # type: ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 304, in data_received self.datagram_received(data, None) File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 338, in datagram_received cut = self.callback_data(self.recv_buffer, addr=addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/server/requesthandler.py", line 79, in callback_data used_len = super().callback_data(data, addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transaction/transaction.py", line 217, in callback_data used_len, pdu = self.framer.processIncomingFrame(self.trace_packet(False, data)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 76, in processIncomingFrame data_len, pdu = self._processIncomingFrame(data[used_len:]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 97, in _processIncomingFrame if (result := self.decoder.decode(frame_data)) is None: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/pdu/decoders.py", line 112, in decode pdu.decode(frame[1:]) File "/usr/lib/python3.12/site-packages/pymodbus/pdu/register_message.py", line 26, in decode self.address, self.count = struct.unpack(">HH", data) ^^^^^^^^^^^^^^^^^^^^^^^^^^ struct.error: unpack requires a buffer of 4 bytes Executing <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> took 0.675 seconds 2025-07-01 16:18:46,699 DEBUG transport:329 recv: 0x1 0x4 0x14 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x4a 0x15 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe old_data: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd addr=None 2025-07-01 16:18:46,700 DEBUG base:91 Processing: 0x1 0x3 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x0 0x14 0x67 0x72 0x1 0x4 0x0 0x0 0x0 0xa 0x70 0xd 0x1 0x4 0x14 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x0 0x15 0x4a 0x15 0x2 0x3 0x0 0x0 0x0 0xa 0xc5 0xfe 2025-07-01 16:18:46,700 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:46,700 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. : 同メッセージが繰り返し出力のため省略 : 2025-07-01 16:18:55,409 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. 2025-07-01 16:18:55,409 DEBUG rtu:123 Frame check failed, possible garbage after frame, testing.. Exception in callback SerialTransport.intern_read_ready() handle: <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> source_traceback: Object created at (most recent call last): File "/tmp/test_slave01_simple.py", line 17, in <module> asyncio.run( File "/usr/lib/python3.12/asyncio/runners.py", line 195, in run return runner.run(main) File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) File "/usr/lib/python3.12/asyncio/base_events.py", line 678, in run_until_complete self.run_forever() File "/usr/lib/python3.12/asyncio/base_events.py", line 645, in run_forever self._run_once() File "/usr/lib/python3.12/asyncio/base_events.py", line 1991, in _run_once handle._run() File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 44, in setup self.async_loop.add_reader(self.sync_serial.fileno(), self.intern_read_ready) File "/usr/lib/python3.12/asyncio/selector_events.py", line 357, in add_reader self._add_reader(fd, callback, *args) File "/usr/lib/python3.12/asyncio/selector_events.py", line 280, in _add_reader handle = events.Handle(callback, args, self, None) Traceback (most recent call last): File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/lib/python3.12/site-packages/pymodbus/transport/serialtransport.py", line 134, in intern_read_ready self.intern_protocol.data_received(data) # type: ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 304, in data_received self.datagram_received(data, None) File "/usr/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 338, in datagram_received cut = self.callback_data(self.recv_buffer, addr=addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/server/requesthandler.py", line 79, in callback_data used_len = super().callback_data(data, addr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/transaction/transaction.py", line 217, in callback_data used_len, pdu = self.framer.processIncomingFrame(self.trace_packet(False, data)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 76, in processIncomingFrame data_len, pdu = self._processIncomingFrame(data[used_len:]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/framer/base.py", line 97, in _processIncomingFrame if (result := self.decoder.decode(frame_data)) is None: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/site-packages/pymodbus/pdu/decoders.py", line 112, in decode pdu.decode(frame[1:]) File "/usr/lib/python3.12/site-packages/pymodbus/pdu/register_message.py", line 26, in decode self.address, self.count = struct.unpack(">HH", data) ^^^^^^^^^^^^^^^^^^^^^^^^^^ struct.error: unpack requires a buffer of 4 bytes Executing <Handle SerialTransport.intern_read_ready() created at /usr/lib/python3.12/asyncio/selector_events.py:280> took 0.693 seconds
at_shota.shimoyama
rikuya-h 様
追加したオプションによって、Slave1とSalve2が自分以外宛てのMasterからのクエリは無視できるようにはなりましたが(Slave1が最後までうまくいっている)、
Slave1 ⇒ Master のレスポンスを、Salve2がMaster ⇒ Salve1のクエリと勘違いして、struct.error: unpack requires a buffer of 4 bytes
というエラーが出力されていますね。
File "/usr/lib/python3.12/site-packages/pymodbus/pdu/register_message.py", line 26, in decode self.address, self.count = struct.unpack(">HH", data)
このエラー文のように、本来 data には Master ⇒ Salve のクエリのようにaddress(2byte)とcount(2byte)合わせて4byteがdataに入っているはずなのですが、
Slave1 ⇒ Master のレスポンスでは data に21byte入るため、dataが4byteではないというエラーが出力されています。
pymodbusのgithubレポジトリでは、dataが4byteより大きいときにこのエラーにならないように修正されています
https://github.com/pymodbus-dev/pymodbus/commit/ef44d0f1b645d7e41770616…
これを参考に、slaveで /usr/lib/python3.12/site-packages/pymodbus/pdu/register_message.py の26行目を以下のように変更したところ、こちらではなんとか動作するようになりました。
self.address, self.count = struct.unpack(">HH", data[:4])
ただ調べてみたところ、どうやらpymodbusのModbusRTUは、マルチポイント(デイジーチェーン)接続下ではサーバーとしての使用に対応していないと記載されています…
(マルチポイント接続下でのマスターとしての使用には対応しています)
https://pymodbus.readthedocs.io/en/v3.9.2/source/server.html
https://github.com/pymodbus-dev/pymodbus/discussions/2597
上記の修正を行っても、マルチポイント(デイジーチェーン)接続下でサーバーとして問題なく使用できる保証は無さそうです
よろしくおねがいします
rikuya-h
at_shota.shimoyama様
ご確認及びご回答ありがとうございます!
> ただ調べてみたところ、どうやらpymodbusのModbusRTUは、マルチポイント(デイジーチェーン)接続下ではサーバーとしての使用に対応していないと記載されています…
> (マルチポイント接続下でのマスターとしての使用には対応しています)
> https://pymodbus.readthedocs.io/en/v3.9.2/source/server.html
> https://github.com/pymodbus-dev/pymodbus/discussions/2597
そうだったのですね...
私のドキュメントの読み込みが甘く...申し訳ありませんでした。
pymodbusでマルチポイントのスレーブサーバをエミュレート出来ないのであれば他、実機を用意する等を検討します。
いつもフォーラムによる回答には大変助かっております。
貴社のご期待に添えるように、開発を進めて参ります。
今後ともよろしくお願いします。
at_shota.shimoyama
2025年3月28日 12時04分
アットマークテクノの下山です。
まず、お互いのコンバータのA+・B+・GNDを接続した状態であることを確認してください。
PC側のコンバータをTeratermなどで表示している場合は、改行コードを送信・受信ともにLFに設定してください。
■通信設定
G4の通信設定を以下のように設定します
ここでは、baudrateを115200として設定してます、PC側も同じbaudrateに設定してください
■G4から送信する場合
以下のコマンドでPC側に文字は表示されますでしょうか?
■G4が受信する場合
以下のコマンドを実行してから、PC側で文字入力+EnterでG4側のコンソールに文字は表示されますでしょうか?
よろしくお願いします