无法使用 Python 读取 MODBUS 寄存器
Trouble reading MODBUS register using Python
我正在尝试使用 Python (PyCharm) 读取 modbus 设备上的寄存器。我已经确认了 COM 端口、波特率和其他通信设置,我可以使用设备应用程序读取值(它是一个水位记录器)。我没有收到仪器的响应。
使用 -
可以在 mbpoll 中读取寄存器
mbpoll -B -m RTU -t 4:float -a 1 -b 19200 -r 46 -c 2 /dev/ttyUSB0
(地址与 Pi 而非 PC 上的 运行 不同)
和 MBPOLL -
我的代码如下-
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 3 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
instrument.clear_buffers_before_each_transaction = True
temperature = instrument.read_float(registeraddress=40046, functioncode=3, number_of_registers=2, byteorder=0) # Registernumber, number of decimals
print(temperature)
收到错误 -
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.1 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
#nstrument.clear_buffers_before_each_transaction = True
temperature = instrument.read_float(registeraddress=45, functioncode=4, number_of_registers=2, byteorder=0) # Registernumber, number of decimals
try:
print(temperature)
except:
print(temperature)
编辑以包含尝试 - 除了
感谢任何帮助!
编辑:
Link 到设备手册 - https://in-situ.com/en/pub/media/support/documents/Modbus_Manual.pdf
设备是通过制造电缆连接到 PC 的 Level Troll 400
编辑 2:
我试图合并最小的 modbus 结构但无济于事。
编辑 3:
我可以使用 Modbus Poll 读取寄存器。寄存器是 40046,所以我理解这是保持寄存器中的寄存器 45?我如何将其转换为 minimalmodbus?
编辑 4:
我没有嫁给最小的 modbus - 我很乐意使用任何工具来完成这项工作
编辑 5:
我也尝试过 depth = instrument.read_long(x, x)
不同的值
设备手册没有明确说明寄存器起始地址,但它提到的第一个寄存器的地址是1。
同样,mbpoll 命令行实用程序(不是带有 GUI 的实用程序)对于起始地址不是很清楚。但是它的文档提到 -r
参数的默认值是 1.
我认为可以安全地假设两者使用从 1 开始的相同寻址,因为命令行工具在访问该值时没有问题。
但是MinimalModbusAPI明确提到它的寄存器起始地址是0。所以在使用这个库时,你需要使用registeraddress = 45
来访问温度,而不是46或40046。
但为什么 46 不起作用?通常,人们会期望它从下一个寄存器开始获取数据并打印一些垃圾,但不会超时。但我们无法知道该设备内部是如何工作的。也许访问温度寄存器的请求实际上触发了一些测量功能,然后 returns 一个值。固件可以简单地拒绝访问未对齐数据(具有错误的寄存器值)的请求。
如果您仍然遇到 registeraddress = 45
超时,您的 Python 运行时可能在访问串行端口时遇到一些问题。正如我在评论中所述,我建议使用逻辑分析仪来查看线路上发生了什么。没有这样的工具,你就是在盲目调试。
如果有人偶然发现这个问题并遇到同样的问题,只需更新解决方案即可。正如在其他建议中半提到的那样,我连接的设备有一个 'sleep' 周期等,需要在成功返回任何后续轮询的值之前进行一次轮询,但未成功。我为我的电枢代码道歉,但对我有用的解决方案如下 -
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 1 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
#nstrument.clear_buffers_before_each_transaction = True
try:
temperature = instrument.read_long(registeraddress=9001, functioncode=3,
byteorder=0) # Registernumber, number of decimals
print(temperature)
except:
pass
try:
temperature = instrument.read_long(registeraddress=9001, functioncode=3,
byteorder=0) # Registernumber, number of decimals
print(temperature)
except:
pass
我正在尝试使用 Python (PyCharm) 读取 modbus 设备上的寄存器。我已经确认了 COM 端口、波特率和其他通信设置,我可以使用设备应用程序读取值(它是一个水位记录器)。我没有收到仪器的响应。
使用 -
可以在 mbpoll 中读取寄存器mbpoll -B -m RTU -t 4:float -a 1 -b 19200 -r 46 -c 2 /dev/ttyUSB0
和 MBPOLL -
我的代码如下-
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 3 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
instrument.clear_buffers_before_each_transaction = True
temperature = instrument.read_float(registeraddress=40046, functioncode=3, number_of_registers=2, byteorder=0) # Registernumber, number of decimals
print(temperature)
收到错误 -
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.1 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
#nstrument.clear_buffers_before_each_transaction = True
temperature = instrument.read_float(registeraddress=45, functioncode=4, number_of_registers=2, byteorder=0) # Registernumber, number of decimals
try:
print(temperature)
except:
print(temperature)
编辑以包含尝试 - 除了
感谢任何帮助!
编辑: Link 到设备手册 - https://in-situ.com/en/pub/media/support/documents/Modbus_Manual.pdf 设备是通过制造电缆连接到 PC 的 Level Troll 400
编辑 2: 我试图合并最小的 modbus 结构但无济于事。
编辑 3: 我可以使用 Modbus Poll 读取寄存器。寄存器是 40046,所以我理解这是保持寄存器中的寄存器 45?我如何将其转换为 minimalmodbus?
编辑 4: 我没有嫁给最小的 modbus - 我很乐意使用任何工具来完成这项工作
编辑 5:
我也尝试过 depth = instrument.read_long(x, x)
不同的值
设备手册没有明确说明寄存器起始地址,但它提到的第一个寄存器的地址是1。
同样,mbpoll 命令行实用程序(不是带有 GUI 的实用程序)对于起始地址不是很清楚。但是它的文档提到 -r
参数的默认值是 1.
我认为可以安全地假设两者使用从 1 开始的相同寻址,因为命令行工具在访问该值时没有问题。
但是MinimalModbusAPI明确提到它的寄存器起始地址是0。所以在使用这个库时,你需要使用registeraddress = 45
来访问温度,而不是46或40046。
但为什么 46 不起作用?通常,人们会期望它从下一个寄存器开始获取数据并打印一些垃圾,但不会超时。但我们无法知道该设备内部是如何工作的。也许访问温度寄存器的请求实际上触发了一些测量功能,然后 returns 一个值。固件可以简单地拒绝访问未对齐数据(具有错误的寄存器值)的请求。
如果您仍然遇到 registeraddress = 45
超时,您的 Python 运行时可能在访问串行端口时遇到一些问题。正如我在评论中所述,我建议使用逻辑分析仪来查看线路上发生了什么。没有这样的工具,你就是在盲目调试。
如果有人偶然发现这个问题并遇到同样的问题,只需更新解决方案即可。正如在其他建议中半提到的那样,我连接的设备有一个 'sleep' 周期等,需要在成功返回任何后续轮询的值之前进行一次轮询,但未成功。我为我的电枢代码道歉,但对我有用的解决方案如下 -
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 1 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
#nstrument.clear_buffers_before_each_transaction = True
try:
temperature = instrument.read_long(registeraddress=9001, functioncode=3,
byteorder=0) # Registernumber, number of decimals
print(temperature)
except:
pass
try:
temperature = instrument.read_long(registeraddress=9001, functioncode=3,
byteorder=0) # Registernumber, number of decimals
print(temperature)
except:
pass