I have modbus mapping setup in my AB Micro820 PLC. I have an array in 40001 for writing, and one in 42001 for reading. Both are 200 elements and REAL type (32-bit float). I can write and read currently, so I know the code works, just incorrectly. The values are read/wrote as very small values (i.e. 4.58577478E-19). Can anyone point me in the right direction?
#!/usr/bin/env python
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.client.sync import ModbusTcpClient
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.INFO)
ip_address = "192.168.2.101"
client = ModbusTcpClient(ip_address)
if client.connect(): # connection is OK
# write float
builder = BinaryPayloadBuilder(endian=Endian.Little)
builder.add_32bit_float(77.77)
payload = builder.build()
result = client.write_registers(1, payload, skip_encode=True)
# read floats
result = client.read_holding_registers(2001, 4)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
print "read_holding_registers: " + str(decoder.decode_32bit_float())
client.close()
Use:
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, Endian.Big, wordorder=Endian.Little)
instead of:
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
Arguments for BinaryPayloadDecoder.fromRegisters for this package are described in docs.
In this case we should pay attention to:
byteorder – The Byte order of each word
wordorder – The endianess of the word (when wordcount is >= 2)
I belive for a value that fits in a modbus register (2 bytes) byteorder is always must be a Endian.Big
wordorder is something like byteorder but for modbus registers.
For Modbus TCP always must be that is byteorder=Endian.Big, wordorder=Endian.Little because byteorder for the values, consisting of more than 2 bytes are exactly specified in the protocol spec OPEN MODBUS/TCP SPECIFICATION(Appendix B. Data Encoding for non-word data) .
For Modbus RTU byteorder for the values, consisting of more than 2 bytes are not exactly specified in the protocol spec Somehow described here.
Most of the implementations takes the Modbus TCP approach and transmitting floats as [2, 1, 4, 3] bytes.
However, there are other possibilities: