Gunnar Kjemphol
Gunnar Kjemphol

Reputation: 53

Python unpack hex floating numbers from an UDP message

I will extract/unpack floating numbers from an UDP message and using unpack. The recieved floating values are not decoded correctly. A sample of the recieved values:

value_1; value_2; value_3; value_4; value_5; value_6; value_7; value_8; value_9
113; 25; 99; -5,935507590692059e-21; 3,6735358238220215; 9,607040496462105e-09; 3,105335657942221e+16; 1,677943189259233e-31; -1,1667551647054353e-10; 158 
113; 25; 99; 1,6007581002917826e-13; -2,7373925907322235e+32; -5,90081314613487e+37; -1,1715147514317771e-33; -84894,453125; 1,6881092411861532e-15; 214
113; 25; 99; 89819568,0; -7,121651712793664e-09; -1,0874276739486488e-12; 5,0595508846403285e+31; 7,212918281555176; -9,193915300799425e-38; 21

The 113, 25 and 99 are correct and the last value is a checksum and also correct.

The floating numbers should be more like a 0.0003234 value as the next example.

-1.5357945225e-004 -2.3622182564e-004  8.0991359160e-005 -1.4786999673e-003  2.0443745889e-003  4.9047302455e-002
1.9647086933e-004 -2.3016422241e-004  3.8992474000e-004 -1.4826891711e-003  2.0534156356e-003  4.9040760845e-002
1.3971551841e-004 -6.4107143726e-005  3.6151042455e-004 -1.4849692816e-003  2.0616210531e-003  4.9035679549e-002

Here is a picture of the recieved UDP message captured from wireshark. enter image description here

How to extract the correct floating numbers in this data?

Here is the essential of my code:

sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) 
sock.bind( (UDP_IP,UDP_PORT) )
f.write("'value_1', value_2, value_3, value_4, value_5, value_6, value_7, value_8, value_9" '\n')

while i < NumberOfSamples:
  data, addr = sock.recvfrom( 4096 ) # buffer size is 1024 bytes
  print >>f, struct.unpack("<BBBffffffB", data)

for line in f:
  f2.write(line.replace(',',';').replace('.',',').replace('(',' ').replace(')',' '))

Upvotes: 0

Views: 1293

Answers (1)

Martin Evans
Martin Evans

Reputation: 46779

You could try splitting the unpacking up into 2 parts, for example:

import struct

data = "\x71\x19\x63\xb6\xd5\x38\x53\x36\x81\x4c\x59\xb6\xa0\x93\xac\xba\xa5\x9a\x76\x3a\x3f\xcb\x8f\x3d\x48\xfd\xab\x69"

print struct.unpack("4B", data[:3] + data[-1])
print struct.unpack(">6f", data[3:-1])

This would display:

(113, 25, 99, 105)
(-6.3544516706315335e-06, 3.853387624985771e-06, -4.785562850884162e-06, -0.0012634533923119307, 0.0007316404371522367, 0.04907004162669182)

You could also make use of Python's CSV library to help with writing:

import struct
import csv

data = "\x71\x19\x63\xb6\xd5\x38\x53\x36\x81\x4c\x59\xb6\xa0\x93\xac\xba\xa5\x9a\x76\x3a\x3f\xcb\x8f\x3d\x48\xfd\xab\x69"

with open("output.csv", 'wb') as f_output:
    csv_output = csv.writer(f_output, delimiter=';')
    csv_output.writerow(["value_{}".format(v) for v in range(1, 10)])
    csv_output.writerow(struct.unpack(">3B6fB", data))

This would give you an output.csv file as follows:

value_1;value_2;value_3;value_4;value_5;value_6;value_7;value_8;value_9
113;25;99;-6.3544516706315335e-06;3.853387624985771e-06;-4.785562850884162e-06;-0.0012634533923119307;0.0007316404371522367;0.04907004162669182;105

Upvotes: 1

Related Questions