rtu Pymodbus 故障读取从设备
rtu Pymodbus trouble reading slave device
我一直在尝试使用串行端口和 RTU Modbus 连接到设备。该设备为变频控制器:
通过以下 RS485 转 USB 转换器连接到我的笔记本电脑:
https://www.amazon.co.uk/gp/product/B01E8JRL6O/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
我所连接设备的使用说明提供了一个使用Modbus读取数据的使用示例,如下图:
根据以上内容,我尝试使用以下代码执行读取请求:
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
modbus = ModbusClient(method='rtu', port='/dev/tty.usbserial-AQ00BYCR', baudrate=9600, timeout=1)
modbus.connect()
test = modbus.read_holding_registers(1, 1, unit=1)
print (test)
我假设在上面那行:
test = modbus.read_holding_registers(1, 1, unit=1)
表示读取寄存器地址1,for 1 reading frame, for device ID 1。根据我的理解,这个请求对应于上面的指令示例。然而,不幸的是,我一直收到错误消息:
Modbus Error: [Input/Output] Modbus Error: [Invalid Message]
Incomplete message received, expected at least 2 bytes (1 received)
有谁知道我为什么会收到这个错误?其次,CRC 是由 pymodbus 即时计算的吗?或者我应该如何计算并包含它?
非常感谢任何帮助!
正如评论中所讨论的,您遇到了一个奇怪的问题。
总结一下:
-您的 PID 控制器支持 RS485 上的 Modbus RTU。
-接线正确:USB 转换器上的 T/R+ 连接到控制器上的 T/R(A),T/R- 连接到控制器上的 T/R(B)。
-USB转换器好像不错,支持Modbus(RS485半双工)。
-您的代码应该可以工作。
-波特率和奇偶校验正确。 (编辑: 根据下面的评论,这实际上是问题所在,手册声称默认的波特率通常在固件的新版本中更改或由其他人操纵自己需要的设备)。
要了解更多详情,您可以添加 debugging/logging,如下所示:
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
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)
modbus = ModbusClient(method='rtu', port='/dev/tty.usbserial-AQ00BYCR', baudrate=9600, timeout=1)
modbus.connect()
test = modbus.read_holding_registers(1, 1, unit=1)
print(test.registers)
试试看,你会说服自己 pymodbus 确实在端口上写入了以下字节:
0x01 0x03 0x00 0x01 0x00 0x01 0xD5 0xCA
查看日志(它应该与我的类似,但在你的日志中你也会看到来自设备的答案):
2019-12-03 18:24:45,262 MainThread DEBUG transaction :111 Current transaction state - IDLE
2019-12-03 18:24:45,262 MainThread DEBUG transaction :116 Running transaction 1
2019-12-03 18:24:45,262 MainThread DEBUG transaction :215 SEND: 0x1 0x3 0x0 0x1 0x0 0x1 0xd5 0xca
2019-12-03 18:24:45,262 MainThread DEBUG sync :73 New Transaction state 'SENDING'
2019-12-03 18:24:45,262 MainThread DEBUG transaction :224 Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2019-12-03 18:24:46,264 MainThread DEBUG transaction :234 Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received))
2019-12-03 18:24:46,265 MainThread DEBUG rtu_framer :235 Frame - [] not ready
2019-12-03 18:24:46,265 MainThread DEBUG transaction :390 Getting transaction 1
2019-12-03 18:24:46,265 MainThread DEBUG transaction :189 Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
在这一点上,我最终得到的都是极其牵强的理论(如果你运行使用的是非常非常旧的 pymodbus 版本,CRC 的字节顺序是错误的,你会看到0xca 0xd5
代替)。
我一直在尝试使用串行端口和 RTU Modbus 连接到设备。该设备为变频控制器:
通过以下 RS485 转 USB 转换器连接到我的笔记本电脑:
https://www.amazon.co.uk/gp/product/B01E8JRL6O/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
我所连接设备的使用说明提供了一个使用Modbus读取数据的使用示例,如下图:
根据以上内容,我尝试使用以下代码执行读取请求:
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
modbus = ModbusClient(method='rtu', port='/dev/tty.usbserial-AQ00BYCR', baudrate=9600, timeout=1)
modbus.connect()
test = modbus.read_holding_registers(1, 1, unit=1)
print (test)
我假设在上面那行:
test = modbus.read_holding_registers(1, 1, unit=1)
表示读取寄存器地址1,for 1 reading frame, for device ID 1。根据我的理解,这个请求对应于上面的指令示例。然而,不幸的是,我一直收到错误消息:
Modbus Error: [Input/Output] Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (1 received)
有谁知道我为什么会收到这个错误?其次,CRC 是由 pymodbus 即时计算的吗?或者我应该如何计算并包含它?
非常感谢任何帮助!
正如评论中所讨论的,您遇到了一个奇怪的问题。
总结一下:
-您的 PID 控制器支持 RS485 上的 Modbus RTU。
-接线正确:USB 转换器上的 T/R+ 连接到控制器上的 T/R(A),T/R- 连接到控制器上的 T/R(B)。
-USB转换器好像不错,支持Modbus(RS485半双工)。
-您的代码应该可以工作。
-波特率和奇偶校验正确。 (编辑: 根据下面的评论,这实际上是问题所在,手册声称默认的波特率通常在固件的新版本中更改或由其他人操纵自己需要的设备)。
要了解更多详情,您可以添加 debugging/logging,如下所示:
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
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)
modbus = ModbusClient(method='rtu', port='/dev/tty.usbserial-AQ00BYCR', baudrate=9600, timeout=1)
modbus.connect()
test = modbus.read_holding_registers(1, 1, unit=1)
print(test.registers)
试试看,你会说服自己 pymodbus 确实在端口上写入了以下字节:
0x01 0x03 0x00 0x01 0x00 0x01 0xD5 0xCA
查看日志(它应该与我的类似,但在你的日志中你也会看到来自设备的答案):
2019-12-03 18:24:45,262 MainThread DEBUG transaction :111 Current transaction state - IDLE
2019-12-03 18:24:45,262 MainThread DEBUG transaction :116 Running transaction 1
2019-12-03 18:24:45,262 MainThread DEBUG transaction :215 SEND: 0x1 0x3 0x0 0x1 0x0 0x1 0xd5 0xca
2019-12-03 18:24:45,262 MainThread DEBUG sync :73 New Transaction state 'SENDING'
2019-12-03 18:24:45,262 MainThread DEBUG transaction :224 Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2019-12-03 18:24:46,264 MainThread DEBUG transaction :234 Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received))
2019-12-03 18:24:46,265 MainThread DEBUG rtu_framer :235 Frame - [] not ready
2019-12-03 18:24:46,265 MainThread DEBUG transaction :390 Getting transaction 1
2019-12-03 18:24:46,265 MainThread DEBUG transaction :189 Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
在这一点上,我最终得到的都是极其牵强的理论(如果你运行使用的是非常非常旧的 pymodbus 版本,CRC 的字节顺序是错误的,你会看到0xca 0xd5
代替)。