Haroon
Haroon

Reputation: 3

Python/Simulink/MATLAB: How to properly read single-type 4bytes data from Simulink in Python?

I have a program in Simulink to send some values through TCP-IP and to read them in Python 2.7. The data is sent as "single" values. The code in Python reads that as 4 strings as its 32 bits long (string of length 4).

print "x0:", ord(data[0])
print "x1:", ord(data[1])
print "x2:", ord(data[2])
print "x3:", ord(data[3])

The problem is, I get some different values in Python than that being sent.

0.125 is read as x0: 62, x1: 0, x2: 0, x3: 0
13.65 is read as x0:65, x1=90, x2: 96, x3: 0
51.79 is read as x0:66, x1=79, x2: 42, x3: 128
113.4 is read as x0:66, x1=226, x2: 200, x3: 220

So how to get these values... 0.125, 13.65, 51.79, 113.4, ... as proper numbers on the receive side (Python)?

Upvotes: 0

Views: 427

Answers (1)

BoarGules
BoarGules

Reputation: 16952

Use struct to unpack the 4-byte float that you are getting off the wire.

>>> import struct
>>> patt='!f'    # big-endian single-precision float, 4 bytes
>>> _0_125 = chr(62)+chr(0)+chr(0)+chr(0)
>>> struct.unpack(patt,_0_125)
(0.125,)   
>>> _13_65 = chr(65)+chr(90)+chr(96)+chr(0)
>>> struct.unpack(patt,_13_65)
(13.6484375,) 
>>> _51_79 = chr(66)+chr(79)+chr(42)+chr(128)
>>> struct.unpack(patt,_51_79)
(51.79150390625,)

This gives you a tuple back because there could be more than one data item in the bytestring you pass to unpack.

I've had to recreate the bytestrings from your question using chr(). If you already have a bytestring in x then struct.unpack(patt,x) will do the trick.

The data you see in byte form appears unrelated to the values you are expecting because it is in IEEE754 format. The data is binary and byte boundaries are meaningless:

  • Bit 31: Sign (0 = positive, 1 = negative)
  • Bits 30 to 23: Exponent, biased by 127
  • Bits 22 to 0: Fraction f of the number 1.f (where . means a binary point)

Upvotes: 1

Related Questions