Я читаю два 16-битных регистра из tcp-клиента с помощью модуля pymodbus . Два регистра составляют 32-битное IEEE 754 кодированное число с плавающей запятой. В настоящее время у меня есть 32-битное двоичное значение регистров, показанных в коде ниже.
start_address = 0x1112
reg_count = 2
client = ModbusTcpClient(<IP_ADDRESS>)
response = client.read_input_registers(start_address,reg_count)
reg_1 = response.getRegister(0)<<(16 - (response.getRegister(0).bit_length())) #Get in 16 bit format
reg_2 = response.getRegister(1)<<(16 - (response.getRegister(1).bit_length())) #Get in 16 bit format
volts = (reg_1 << 16) | reg_2 #Get the 32 bit format
Вышеприведенное работает нормально, чтобы получить закодированное значение, проблема заключается в его декодировании. Я собирался кодировать что-то вроде этого видео , но я наткнулся на формат 'f' в модуле struct для кодирования IEEE 754. Я попытался декодировать 32-разрядный код с плавающей запятой, хранящийся в вольт в приведенном выше коде, используя метод unpack в модуле struct, но натолкнулся на следующие ошибки.
val = struct.unpack('f',volts)
>>> TypeError: a bytes-like object is required, not 'int'
Хорошо, попытался преобразовать его в 32-битную двоичную строку.
temp = bin(volts)
val = struct.unpack('f',temp)
>>> TypeError: a bytes-like object is required, not 'str'
Попытка преобразовать его в подобный байту объект, как в этом посте , и отформатировать по-разному.
val = struct.unpack('f',bytes(volts))
>>> TypeError: string argument without an encoding
temp = "{0:b}".format(volts)
val = struct.unpack('f',temp)
>>> ValueError: Unknown format code 'b' for object of type 'str'
val = struct.unpack('f',volts.encode())
>>> struct.error: unpack requires a buffer of 4 bytes
Куда добавить этот буфер и где в документации говорится, что мне нужен этот буфер с помощью метода unpack? В документации сказано:
Строка должна содержать именно тот объем данных, который требуется для формата (len (строка) должна равняться calcsize (fmt)).
Функция calcsize (fmt) возвращает значение в байтах, но len (строка) возвращает значение длины строки, нет?
Любые предложения приветствуются.
РЕДАКТИРОВАТЬ
Существует решение для декодирования ниже, однако лучшее решение для получения 32-битного значения регистра из два 16-битных значения регистра показаны ниже по сравнению с оригиналом в вопросе.
start_address = 0x1112
reg_count = 2
client = ModbusTcpClient(<IP_ADDRESS>)
response = client.read_input_registers(start_address,reg_count)
reg_1 = response.getRegister(0)
reg_2 = response.getRegister(1)
# Shift reg 1 by 16 bits
reg_1s = reg_1 << 16
# OR with the reg_2
total = reg_1s | reg_2