1

我正在尝试使用 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)

编辑以包括尝试 - 除了

任何帮助表示赞赏!

编辑:链接到设备手册 - h​​ttps: //in-situ.com/en/pub/media/support/documents/Modbus_Manual.pdf 设备是通过制造商电缆连接到 PC 的 Level Troll 400

编辑 2:我试图合并最小的 modbus 结构,但无济于事。

编辑 3:我可以使用 Modbus Poll 读取寄存器。寄存器是 40046,所以我理解这是保持寄存器中的寄存器 45?我如何将它翻译成最小的modbus?

编辑 4:我没有嫁给最小的 modbus - 我很高兴使用任何工具来完成这项工作

编辑 5:我也尝试depth = instrument.read_long(x, x)过不同的值

4

2 回答 2

2

如果有人碰巧遇到此问题并遇到同样的问题,只需更新解决方案即可。正如在其他建议中半暗示的那样,我连接到的设备有一个“睡眠”时间等,需要在成功返回任何后续轮询的值之前轮询一次,但未成功。我为我的电枢代码道歉,但对我有用的解决方案如下 -

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

于 2021-06-07T03:36:35.523 回答
1

设备手册并不清楚寄存器起始地址,但它提到的第一个寄存器的地址为1

同样,mbpoll命令行实用程序(不是带有 GUI 的实用程序)对起始地址也不是很清楚。但它的文档提到-r参数的默认值为1

我认为可以安全地假设两者都使用从1开始的相同寻址,因为命令行工具访问该值没有问题。

但是MinimalModbus API 明确提到它的寄存器起始地址是0。所以在使用这个库的时候,需要用registeraddress = 45for访问温度,而不是46或者40046。

但为什么46不起作用?通常,人们会期望它从下一个寄存器开始抓取数据并打印一些垃圾,但不会超时。但我们无法知道设备内部是如何工作的。也许访问温度寄存器的请求实际上会触发一些测量功能,然后返回一个值。固件可以简单地拒绝访问未对齐数据(具有错误寄存器值)的请求。

如果您仍然遇到超时registeraddress = 45,您的 Python 运行时可能在访问串行端口时遇到了一些问题。正如我在评论中所说,我建议使用逻辑分析仪来查看线路上发生了什么。如果没有这样的工具,你就是在进行盲调试。

于 2021-05-28T12:38:10.247 回答