Как отрицательные числа должны быть представлены во входном регистре pymodbus? - PullRequest
0 голосов
/ 13 апреля 2019

Я хочу назначить отрицательные числа входному регистру на асинхронном сервере pymodbus.У меня есть 5-элементный массив с именем PQV, который содержит числа с амплитудой в диапазоне от 0 до 300, но некоторые элементы являются отрицательными

PQV=[145, -210, 54, 187, -10]

Я использую код ниже, чтобы назначить PQV длявходной регистр (регистр 4), начиная с адреса 0. Я попытался добавить 65536 ко всем отрицательным числам, но это не сработало.

Как сделать так, чтобы отрицательные элементы массива PQV были приемлемы для pymodbus?

context[slave_id].setValues(4, 0, PQV)

1 Ответ

0 голосов
/ 14 апреля 2019

Плавания должны быть представлены в шестнадцатеричном формате IEEE-754 перед записью в хранилище данных.Вы можете сделать что-то подобное, чтобы добиться этого.

# Import BinaryPayloadBuilder and Endian
from pymodbus.payload import BinaryPayloadBuilder, Endian
# Create the builder, Use the correct endians for word and byte
builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big)

В вашей функции обновления

busvoltages = [120.0, 501.3, -65.2, 140.3, -202.4]
builder.reset() # Reset Old entries
for vol in busvoltages:
    builder.add_32bit_float(vol)
payload = builder.to_registers()   # Convert to int values
# payload will have these values [17136, 0, 17402, 42598, 49794, 26214, 17164, 19661, 49994, 26214]
context[slave_id].setValues(2, 0, payload)  # write to datablock

Когда вы прочитаете значения обратно, вы получите необработанные значения int обратно.Вам придется конвертировать их обратно в числа с плавающей запятой, используя BinaryPayloadDecoder

>>> from pymodbus.payload import BinaryPayloadDecoder, Endian
>>> r = client.read_input_registers(0, 10, unit=1)
# Use the same byte and wordorders
>>> d = BinaryPayloadDecoder.fromRegisters(r.registers, byteorder=Endian.Big, wordorder=Endian.Big)
>>> d.decode_32bit_float()
120.0
>>> d.decode_32bit_float()
501.29998779296875
>>> d.decode_32bit_float()
-65.19999694824219
>>> d.decode_32bit_float()
140.3000030517578
>>> d.decode_32bit_float()
-202.39999389648438
>>> # Further reads after the registers are exhausted will throw struct error
>>> d.decode_32bit_float()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/sanjay/.virtualenvs/be3/lib/python3.6/site-packages/pymodbus/payload.py", line 440, in decode_32bit_float
    handle = self._unpack_words(fstring, handle)
  File "/Users/sanjay/.virtualenvs/be3/lib/python3.6/site-packages/pymodbus/payload.py", line 336, in _unpack_words
    handle = unpack(up, handle)
struct.error: unpack requires a buffer of 4 bytes
>>>

Надеюсь, это поможет.

...