[ubuntu-uk] Reverse engineering data files
Paul Sladen
ubuntu at paul.sladen.org
Thu Nov 27 13:49:54 UTC 2014
On Thu, 27 Nov 2014, Gareth France wrote:
> I really don't understand what you have done here.
> >>>> > >>F3 01 90 B7 - 42.79 - 0x90b7 & 0x7fff => 0x10b7 => 4279 decimal
> >>>> > >>F3 01 97 78 - 60.08 - 0x9778 & 0x7fff => 0x1778 => 6008 decimal
The two bytes we're interested in (0x90b7) together give us 16 bits of
information. This is split into two, 1-bit for one value (true or
false) and 15-bits for a measurement value (zero to 32k).
0x90b7
1001000010110111 (binary)
When we split it, the two parts are:
1 and 001000010110111
We can pass these to Python to convert from binary to decimal; the
'0b' prefix means binary, just like '0x' means hexadecimal:
python -c 'print 0b1, 0b001000010110111'
1 4279
The first value is actually a boolean (True/False) and is inverted,
and the second is multipled by 100:
python -c 'print bool(not 0b1), 0.01*0b001000010110111'
False 42.79
We don't need to go to the binary representation at all, we can split
the field using bitwise arithmatic AND (&) and right shift (>>) :
https://en.wikipedia.org/wiki/Bitwise_operation#AND
https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift
python -c 'print bool(not 0x90b7 >> 15), 0.01 * (0x90b7 & 0x7fff)'
False 42.79
We can test this another result too:
python -c 'print bool(not 0x9778 >> 15), 0.01 * (0x9778 & 0x7fff)'
False 60.08
python -c 'print bool(not 0x48db >> 15), 0.01 * (0x48db & 0x7fff)'
True 186.51
In this case, this is above >99.99, which the new meter shows as
'99.99' so we need to cap it with the minimum function:
python -c 'print bool(~0x48db>>15),min(99.99,0.01*(0x48db&0x7fff))'
True 99.99
and just to re-check with the others:
python -c 'print bool(not 0x9778>>15),min(99.99,0.01*(0x9778&0x7fff))'
False 60.08
-Paul
More information about the ubuntu-uk
mailing list