Reputation: 461
I am trying to unpack a variable containing a string received from a spectrum analyzer:
#42404?û¢-+Ä¢-VÄ¢-oÆ¢-8æ¢-bÉ¢-ôÿ¢-+Ä¢-?Ö¢-sÉ¢-ÜÖ¢-¦ö¢-=Æ¢-8æ¢-uô¢-=Æ¢-\Å¢-uô¢-?ü¢-}¦¢-=Æ¢-)...
The format is real 32 which uses four bytes to store each value. The number #42404 represents 4 extra bytes present and 2404/4 = 601 points collected. The data starts after #42404. Now when I receive this into a string variable,
$lp = ibqry($ud,":TRAC:DATA? TRACE1;*WAI;");
I am not sure how to convert this into an array of numbers :(... Should I use something like the followin?
@dec = unpack("d", $lp);
I know this is not working, because I am not getting the right values and the number of data points for sure is not 601...
Upvotes: 2
Views: 3219
Reputation: 50338
If the first 4
encodes the number of remaining digits (2404
) before the floats, then something like this might work:
my @dec = unpack "x a/x f>*", $lp;
The x
skips the leading #
, the a/x
reads one digit and skips that many characters after it, and the f>*
parses the remaining string as a sequence of 32-bit big-endian floats. (If the output looks weird, try using f<*
instead.)
Upvotes: 1
Reputation: 164919
First, you have to strip the #42404
off and hope none of the following binary data happens to be an ASCII number.
$lp =~ s{^#\d+}{};
I'm not sure what format "Real 32" is, but I'm going to guess that it's a single precision floating point which is 32 bits long. Looking at the pack docs. d
is "double precision float", that's 64 bits. So I'd try f
which is "single precision".
@dec = unpack("f*", $lp);
Whether your data is big or little endian is a problem. d
and f
use your computer's native endianness. You may have to force endianness using the >
and <
modifiers.
@dec = unpack("f*>", $lp); # big endian
@dec = unpack("f*<", $lp); # little endian
Upvotes: 5