quick number conversion question
electricsmith
Posts: 20
I struggle with these, any advice would be appreciated:
I'm trying to code the following:
·· I have an ADIS16405 which gives me gyro, acceleration, and magnetometer data in 3 axis.· When I retrieve the data from the device I get binary data that is 16 bits long.· The 2 most significant bits (15,14) are flags and are not data that has to be converted.· The data within the 16bit stream is in the form of 14 bit twos complement.· I have to shed the two most significant bits, take the 14bit twos complement data, convert that to decimal that is signed, then take that and multiply it times a floating point conversion number to get it in the proper units (0.05 for gyro, 3.33 for accel, 0.5 for magn).·
I've attempted it and I get garbage:
'xgyro is my data for x axis gyro data
'I have it declared as a word in the Dat section
'lets assume it is the 16bit stream I just obtained
'i have declared FM as "FloatMath"
xgyro<<=2·· 'i was doing this to shift out the two flags and put zeros in their place
xgyro>>=2
If xgyro > 8191
·· xgyro:=xgyro-16384··· 'I was doing this to convert the two's complement to the right decimal number
xgyro:=fm.fmul(0.05, fm.ffloat(xgyro))
I'm trying to code the following:
·· I have an ADIS16405 which gives me gyro, acceleration, and magnetometer data in 3 axis.· When I retrieve the data from the device I get binary data that is 16 bits long.· The 2 most significant bits (15,14) are flags and are not data that has to be converted.· The data within the 16bit stream is in the form of 14 bit twos complement.· I have to shed the two most significant bits, take the 14bit twos complement data, convert that to decimal that is signed, then take that and multiply it times a floating point conversion number to get it in the proper units (0.05 for gyro, 3.33 for accel, 0.5 for magn).·
I've attempted it and I get garbage:
'xgyro is my data for x axis gyro data
'I have it declared as a word in the Dat section
'lets assume it is the 16bit stream I just obtained
'i have declared FM as "FloatMath"
xgyro<<=2·· 'i was doing this to shift out the two flags and put zeros in their place
xgyro>>=2
If xgyro > 8191
·· xgyro:=xgyro-16384··· 'I was doing this to convert the two's complement to the right decimal number
xgyro:=fm.fmul(0.05, fm.ffloat(xgyro))
Comments
The first shifts the 14 bits so the sign bit is in bit 31 of the long. The second shifts the 14 bits extending the sign and leaving the value right justified. This works because the intermediate results are all 32 bits, but the initial value and final result fit in 16 bits. Note that the sign is not extended when the word value is used unless you use the sign extend operator (since all immediate results are 32 bits). You need to use ~~xgyro in the call to the floating point routine ffloat.
Post Edited (Mike Green) : 7/10/2010 4:28:22 AM GMT
You don't need an explicit long variable since all intermediate values are 32 bits.
(x<<16)~>16)
So you have a couple of options
1. change xgyro to long then the initial (xgyro << 18)~>18 will sign extend it to 32bits and everything is 32bits from there
2. you sign extend it to 16 bits xgyro := (xgyro<<18)~>18 - note its the same as above because spin works with 32bit numbers but the assignment to xgyro truncates to 16bits and then us ~~xgyro everywhere you need to use xgyro to sign extend it back to 32bits
Thanks again for the help.
obj
fm = "floatmath"
fs = "floatstring"
debug = "simpledebug"
main
debug.start(115200)
getxgyroreading 'calls code that sets xgryo to the 14bit two's complement discussed initially
convertreading 'calls routine to convert xgyro to the correct reading
debug.dec(xgyro) 'this gives me crazy number, when I comment out all the fs and fm object code, it gives me a good signed integer number
debug.str(xgyro_str) 'this gives me "@......." with some strange character which i believe is the string pointer, then the remaining "...." declared in DAT unchanged
convertreading
xgyro:=(xgyro<<18)~>18
fs.setprecision(3)
xgyro:= fm.ffloat(xgyro)
xgyro_str:=fs.floattostring(fm.fmul(0.05,xgyro))
dat
xgyro long 0
xgyro_str byte "........",0
I'm not a float user, but you should find something similar.
Just a suggestions.. use the parallax serial terminal object to debug (PST). It is really easy to use.
In any case every terminal function handle strings and decimal. If you have float you must convert it to string and use the "tostr" function available to send it to the terminal.
ok... you already are there..
use the string handling embedded in your terminal object
take it as a pseudo code....
pst.str(float.tostring(YourFloatNumber))
Massimo