Pymodbus: Get 32 bit float

BigTuna

Member
Join Date
Mar 2014
Location
Nova Scotia
Posts
9
I posted this over on the pymodbus google group but just in case someone has experience with this I'll try here as well...

Maybe someone can help me figure out what I'm missing here. I'm following the example exactly:
#!/usr/bin/env python
'''
Pymodbus Payload Building/Decoding Example
--------------------------------------------------------------------------
'''
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.client.sync import ModbusTcpClient as ModbusClient


client = ModbusClient('192.168.0.10)
client.connect()

rr = client.read_holding_registers(2654, 2)
decoder = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Little)
print decoder.decode_32bit_float()

client.close()
What I'm suppose to get is 33.87. What it prints is 1.46638408846e-34

Using MacModbus App (http://www.modbusapps.com/) I can see the binary in the memory locations:

42654 0111011111101010
42655 0100001000000111

Putting the 2 registers together (01000010000001110111011111101010) and checking here:

http://www.h-schmidt.net/FloatConverter/IEEE754.html

I get my 33.87.

Since I've confirmed everything is there in memory does anyone see what I'm doing wrong with my pymodbus code?

Thanks!
 
Last edited:
register 42654 01110111111101010 has 17 bits, not 16.

Which is the bad zero, the leading zero or the trailing zero?

This is why hexadecimal was invented, to avoid the zero and one confusion.
 
register 42654 01110111111101010 has 17 bits, not 16.

Which is the bad zero, the leading zero or the trailing zero?

This is why hexadecimal was invented, to avoid the zero and one confusion.

Just my typo.. it's correct in the register:

0111011111101010

Fixed in edit.
 
You are using the wrong word and byte order.

There are four combinations of word order and byte order for the single precision 32 bit floating point. The diagram below shows the Big Endian format, with the byte order 4,3,2,1. My examples use that byte designation.

2d2m3q.jpg


Two of the four formats are commonly used in Modbus, Big Endian (FP B) and a form of Little Endian (FP LB) as shown in the graphic below.

Your format is FP BB, what I would call Big Endian byte swapped, which is rarely, if ever, used as floating point format in Modbus.

There is an Excel floating point calculator on the Simply Modbus site.

www.simplymodbus.ca/ieeefloats.xls

Download it and poke your value, in hex, 0742 EA77, into the 2 word (32 bit FP) cells and the float will calculate as 1.466xxxx E-34

Poke the Big Endian hex value 4207 77EA into the 2 word cells and the float calculates as 3.3867 E01

Here are the 4 word/byte format combinations in binary and hex

Big Endian (FP B) 4,3,2,1
byte 4 byte 3 byte 2 byte 1
0100 0010 0000 0111 0111 0111 1110 1010
4 2 0 7 7 7 E A

Little Endian (FP LB) 2,1,3,4
byte 2 byte 1 byte 4 byte 3
0111 0111 1110 1010 0100 0010 0000 0111
7 7 E A 4 2 0 7

FP L 1,2,3,4
byte 1 byte 2 byte 3 byte 4
1110 1010 0111 0111 0000 0111 0100 0010
E A 7 7 0 7 4 2

FP BB 3,4,1,2
byte 3 byte 4 byte 1 byte 2
0000 0111 0100 0010 1110 1010 0111 0111
0 7 4 2 E A 7 7

I can't solve your programming issue, I can only show you how the word/byte order affects the outcome.

Dan
 
This was a huge help. Thank you!

When I switch the program to use Big Endian I get 9.50263014475e+33 as my output.

As you indicated Big Endian gives me the right values. The pymodbus function just reads the two registers in the wrong order since it seems the m340 writes to the registers with the first half second and second half first.

At least I know what the problem is and can troubleshoot the code properly now.


Thanks again!

You are using the wrong word and byte order.

There are four combinations of word order and byte order for the single precision 32 bit floating point. The diagram below shows the Big Endian format, with the byte order 4,3,2,1. My examples use that byte designation.

2d2m3q.jpg


Two of the four formats are commonly used in Modbus, Big Endian (FP B) and a form of Little Endian (FP LB) as shown in the graphic below.

Your format is FP BB, what I would call Big Endian byte swapped, which is rarely, if ever, used as floating point format in Modbus.

There is an Excel floating point calculator on the Simply Modbus site.

www.simplymodbus.ca/ieeefloats.xls

Download it and poke your value, in hex, 0742 EA77, into the 2 word (32 bit FP) cells and the float will calculate as 1.466xxxx E-34

Poke the Big Endian hex value 4207 77EA into the 2 word cells and the float calculates as 3.3867 E01

Here are the 4 word/byte format combinations in binary and hex

Big Endian (FP B) 4,3,2,1
byte 4 byte 3 byte 2 byte 1
0100 0010 0000 0111 0111 0111 1110 1010
4 2 0 7 7 7 E A

Little Endian (FP LB) 2,1,3,4
byte 2 byte 1 byte 4 byte 3
0111 0111 1110 1010 0100 0010 0000 0111
7 7 E A 4 2 0 7

FP L 1,2,3,4
byte 1 byte 2 byte 3 byte 4
1110 1010 0111 0111 0000 0111 0100 0010
E A 7 7 0 7 4 2

FP BB 3,4,1,2
byte 3 byte 4 byte 1 byte 2
0000 0111 0100 0010 1110 1010 0111 0111
0 7 4 2 E A 7 7

I can't solve your programming issue, I can only show you how the word/byte order affects the outcome.

Dan
 
Thanks to Dan I've solved the problem. Once I figured out the correct Endian to use and determined the registers were being read in the wrong order I used the struct module directly instead of going through the pymodbus functions.

raw = struct.pack('>HH', rr.getRegister(1) ,rr.getRegister(0))
value = struct.unpack('>f', raw)[0]

33.87!
 
Ah - the big and little endian problem. Have seen that one a few times. It is really nice when a manufacturer of a device has big and little endian selection in the device - saves a lot of work. Unfortunately many manufacturers do not provide the selection and you spend hours sorting out words and bytes!
PITA!
 

Similar Topics

See the screenshot of EIP tag list. We are trying to read in a digital input that is hard-wired. It is shown here as I31.1. I believe we cannot...
Replies
7
Views
280
A couple days ago I accidentally toggled an alwasyoff bit. The issue is it was set up as a single OTU on a rung, nothing else, and used as XICs...
Replies
3
Views
226
Hi I have an old panel builder 32 that I’m replacing for a factory talk me hmi . In the plc for the old panel builder there is a coms bit for the...
Replies
0
Views
73
Hello, Haven't been on in a while. I need to generate a bit level pdf of the I/O for RSLogix 500. I can generate a report but it just shows the...
Replies
1
Views
157
I tried researching but I still don't quite get it. As far as I understood, it's used after a function is called in STL and then if the function...
Replies
1
Views
143
Back
Top Bottom