使用Python读取MODBUS寄存器时出现问题

2024-04-25 14:25:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Python(PyCharm)读取modbus设备上的寄存器。我已确认COM端口、波特率和其他通信设置,我可以使用设备应用程序读取值(它是水位记录器)。我没有收到仪器的回应

寄存器在mbpoll中可读,使用-

mbpoll -B -m RTU  -t 4:float -a 1 -b 19200 -r 46 -c 2 /dev/ttyUSB0

enter image description here (与在Pi而非PC上运行的地址不同)

和MBPOLL- enter image description hereenter image description hereenter image description here

我的代码如下:

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)
 

收到错误- enter image description here

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)

编辑以包含try-except

感谢您的帮助

编辑: 链接到设备手册-https://in-situ.com/en/pub/media/support/documents/Modbus_Manual.pdf 该设备是一个通过电缆连接到PC的电平控制器400

编辑2: 我曾尝试合并最小modbus结构,但没有效果

编辑3: 我能够使用Modbus轮询读取寄存器。寄存器是40046,所以我知道这是持有寄存器中的寄存器45?我该如何将其翻译成中文

编辑4: 我没有嫁给minimal modbus——我很乐意使用任何工具来完成这项工作

编辑5: 我还尝试了使用不同的值depth = instrument.read_long(x, x)


Tags: nameimport编辑numberisportaddressserial
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

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

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

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

但是modbusAPI清楚地提到它的寄存器开始地址是0。因此,在使用这个库时,需要使用registeraddress = 45来访问温度,而不是46或40046

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

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

相关问题 更多 >