現在、RaspberryPi を使用したデータ取得のプロジェクトに取り組んでいます。リクエスト スクリプトを起動すると、スレーブ (コンピュータ) が CRC エラーまたは無効な長さを検出することがあります (まれではありますが、頻繁に発生します)。私のスクリプトは高速で、数秒で数百のレジスタを要求するため、メッセージが不完全で、スレーブがそれを間違ったメッセージとして検出することがあるという事実から、エラーが発生する可能性があると推測しています。私は、minimalmodbus のタイミングが適切でなく、間違った、またはリクエストの一部 (不完全) を送信する可能性があるかどうかを知りたかったのです。
スレーブで返されたエラー:
invalid request: Invalid CRC in request
これは、スレーブが何を答えればよいかわからない場合に、マスターで発生する典型的なエラーです。
error = SLAVE_ERRORS[str(e)]
KeyError: "Checksum error in rtu mode: '\\x8aÿ' instead of '\\x8fF' . The response is: '4ÿ\\x07$Ê\\x8aÿ' (plain response: '4ÿ\\x07$Ê\\x8aÿ')"**
スレーブで modbus_tk を使用して modbus スレーブをエミュレートします。次は通常、値の型に依存するスレーブからの値を要求するコードの一部です。
try:
try:
var_register = file_var[i]['varRegister']
var_type = file_var[i]['varType']
var_use = file_var[i]["varUse"]
var_name = file_var[i]["varName"].strip()
if '#' in var_register:
continue
elif var_type=='U16' or var_type=='I16' or var_type=='S16':
value = inst.read_register(
int(var_register),
0,
3,
not bool(file_var[i]['varSigned'])
)
elif var_type=='U32' or var_type=='I32' or var_type=='S32':
value = inst.read_long(
int(var_register),
3,
not bool(file_var[i]['varSigned'])
)
私の最初の推測はタイミングの問題だったので、「time.sleep」をランダムに挿入してリクエストの時間を計りましたが、まだエラーが発生しています。そして、それは完全にランダムで、最初の CRC エラーの前に 5 分間機能することもあれば、ほんの数秒しか機能しないこともあります。私がどこを調べればよいか、何か考えはありますか?よろしくお願いします。
編集: 私の PC は、複数のスレーブをエミュレートする modbus_tk スクリプトを使用してスレーブとして機能します。RPI は、レジスターとその値を要求するマスターです。スレーブはすべて、IllegalAddress エラーを回避するために、これらの特定のレジスタに値を持つように構成されています。物理的な接続は USB から RS485 へのコンバーターで、RPI には RS485 入出力を処理する HAT が装備されています。つまり、実際には ModBus RTU 通信です。スレーブは、リクエストが来るとループして応答を送信します。
EDIT2: それで、もう少し調査したところ、興味深いものが見つかりました。エラーを受け取りました (今回はマスターで) スレーブが間違ったチェックサムを送信したようです...調べているうちに、modbus_tk によって生成されたチェックサムは問題ないことがわかりましたが、マスターが受け取った回答は同じではありませんでした。途中でいくつかのバイトが変更されたように見えますが、これは奇妙なことです。それはどこから来たのでしょうか?ハードウェアの問題?ただし、複数のレジスタをポーリングする場合にのみこのエラーが発生します (一度に 2 つ以上)。要求されたレジスタの数が 1 または 2 の場合、他のすべての要求は問題ありません。