我正在尝试从PM5300仪表获取电压或电流,但始终只能使用32768。编码:
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
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)
UNIT = 0x01
def run_sync_client():
client = ModbusClient(method='rtu', port='COM15', timeout=1, baudrate=19200, parity='E', stopbits=1, bytesize=8)
client.connect()
request = client.read_holding_registers(address=43010, count=2, unit=UNIT)
result = request.registers
print(result)
decoder = BinaryPayloadDecoder.fromRegisters(result, Endian.Little, wordorder=Endian.Big)
#dc2 = (decoder.decode_32bit_float() + 32768 /1000)
#print(dc2)
print(decoder.decode_32bit_float())
client.close()
if __name__ == "__main__":
run_sync_client()
寄存器列表中的地址3010与电流匹配(4是保持寄存器)。
使用Endian.Little进行日志和打印:
2020-06-16 20:11:24,349 MainThread DEBUG transaction :115 Current transaction state - IDLE
2020-06-16 20:11:24,349 MainThread DEBUG transaction :120 Running transaction 1
2020-06-16 20:11:24,350 MainThread DEBUG transaction :219 SEND: 0x1 0x3 0xa8 0x2 0x0 0x2 0x45 0xab
2020-06-16 20:11:24,350 MainThread DEBUG sync :75 New Transaction state 'SENDING'
2020-06-16 20:11:24,350 MainThread DEBUG transaction :228 Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2020-06-16 20:11:24,364 MainThread DEBUG transaction :304 Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2020-06-16 20:11:24,365 MainThread DEBUG transaction :233 RECV: 0x1 0x3 0x4 0x80 0x0 0x80 0x0 0xb2 0x33
2020-06-16 20:11:24,365 MainThread DEBUG rtu_framer :180 Getting Frame - 0x3 0x4 0x80 0x0 0x80 0x0
2020-06-16 20:11:24,365 MainThread DEBUG factory :266 Factory Response[ReadHoldingRegistersResponse: 3]
2020-06-16 20:11:24,365 MainThread DEBUG rtu_framer :115 Frame advanced, resetting header!!
2020-06-16 20:11:24,366 MainThread DEBUG transaction :383 Adding transaction 1
2020-06-16 20:11:24,366 MainThread DEBUG transaction :394 Getting transaction 1
2020-06-16 20:11:24,366 MainThread DEBUG transaction :193 Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
[32768, 32768]
**2020-06-16 20:11:24,366 MainThread DEBUG payload :312 [32768, 32768]**
2020-06-16 20:11:24,367 MainThread DEBUG payload :368 [b'\x00\x80', b'\x00\x80']
1.1755122874426309e-38
使用Endian.Big,结果为-4.591774807899561e-41
非常感谢!
您的问题出在您要读取的寄存器号中。在pymodbus上,您必须将寄存器指示为绝对地址号;您不必像以前一样向Modbus映射添加40000。
只需更改此行:
request = client.read_holding_registers(address=43010, count=2, unit=UNIT)
至:
request = client.read_holding_registers(address=3010, count=2, unit=UNIT)
根据您的仪表图,应该可以得到当前的平均值。
我现在无法使用仪表,但是如果我的注释正确无误,则字节序应该是正确的,byteorder=Endian.Big, wordorder=Endian.Little
因此您可能也想在代码中弄弄它。
阅读此问题可能值得您花时间,它具有一些我认为针对同一系列Schneider Electric设备的代码。
我会认为,如果不是一个看似正确的阅读而是出现一个错误的地址错误,那就更好了,这是在这种情况下应该得到的。我想他们想保持打开选项以向地图添加更多寄存器,并且使它们不受限制。
编辑:正如下面的评论所讨论的,当前平均读取的正确寄存器为3009,因此请求应为:
request = client.read_holding_registers(address=3009, count=2, unit=UNIT)
有些设备给你拿着从40001开始对寄存器号pymodbus和其他第一保持寄存器编号为0,因此,如果设备的的Modbus地图,你应该读寄存器号45125,例如,你需要减去40001得到address
的pymodbus:
address=45125-40001=5124
您在这里处理的情况更令人讨厌:映射以寄存器1开头,因此您需要减去1。
如下面的屏幕截图所示:
ModbusPoll遵循相同的逻辑:默认情况下,必须为寄存器40001输入0(或为寄存器40011输入10)。如果单击复选框PLC地址,则必须输入1才能从地址40001读取。
是的,我知道,令人困惑!
请注意,上面链接中的问题未提及-1偏移量。某些设备(例如您的设备!)将不允许您读取“错误的”寄存器。这样,如果您想读取当前平均值(这是一个FLOAT32,因此占用两个寄存器),则需要从寄存器3009开始读取并读取两个寄存器(是的,映射表示3010,但要记住-1偏移量)。相反,如果从寄存器3010开始,则实际上是在尝试读取当前平均值的上半部分和下一个变量(电流不平衡)的下半部分。由于您正在读取两个混合变量,因此无法获取任何有用的数据,因此会出现错误。同样,这不是最好的错误;它至少应该给您一些提示,说明您在做什么错,但是but!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句