0

I have the following Modbus response:16736 I can convert it to hex and binary: hex: 0x41600000 binary: 0b100000101100000

I should convert Modbus reponse to float, and the result should be 14.0. If I go to http://gregstoll.dyndns.org/~gregstoll/floattohex/ , 0x41600000 converts to 14.0.

I have tried all sorts of struct.unpack kung-fu, but I cannot get 14.0. (I heave read all of the Stackoverflow posts that I could find before I decided to post yet another conversion question, but I definitely don't understand how this works)

What am I missing? Thanks a lot.

5
  • 1
    What do you get? How? Commented Jul 22, 2014 at 12:26
  • Yeah, can you post the results of your kung-fu? Commented Jul 22, 2014 at 12:27
  • Have you looked up the documentation of the library you attempt to use? Commented Jul 22, 2014 at 12:28
  • Since I cannot answer my own question for the next 7 hours or so, here is the answer: struct.unpack('!f', data.decode('hex'))[0] I wasn't decoding, that was the problem. Thank you all. Commented Jul 22, 2014 at 12:32
  • @Dejan: you did not show us what data was received then; next time use repr(response) to show us what exactly you have. At least then we could have advised you on converting from a literal hex representation to bytes too. Commented Jul 22, 2014 at 12:35

1 Answer 1

5

You have a single-precision float, in big-endian byte order:

response = '\x41\x60\x00\x00'
struct.unpack('>f', response)

Demo:

>>> import struct
>>> struct.unpack('>f', '\x41\x60\x00\x00')
(14.0,)
Sign up to request clarification or add additional context in comments.

7 Comments

Warning about your opening words (since the OP was specifically regarding the modbus protocol): its not always safe to assume that modbus properly delivers 32bit datatypes in big endian. Although modbus does deliver in big endian, its typically addressed as 16bit registers. Those individual registers will be big endian, but if the modbus server is on a little endian platform, you will likely need to do a CD-AB byte swap before you pack your hex string down the pipeline.
@user2097818: right, I am not familiar with modbus, I merely identified the exact byte sequence shown here. Is there anything in the protocol to indicate the endianess of the source platform that would help the receiver decide on when to apply the CD-AB swap?
Not unless the application developer intentionally planted a static sequence of known values as a signature to reference (and some do, but there is no such requirement). Platform ambiguity is the beauty of modbus ... but it is designed for a Realtime stage, where BOOLs, SHORT-INTs, and 12-bit Analog signals (scaled into a UINT16) are all that usually matter. The protocol has a lot of flexibility to do more, but anything else is outside the scope of the standard and consequently becomes platform, application, and/or company specific.
@user2097818: right; then I'll assume that in this case my answer suffices for the specific protocol used. :-) We can always hash out Python approaches to the CD-AB swap in another question.
You were right for sure, but someone googling modbus+iee754 might get into trouble if they didn't know better.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.