Shop OBEX P1 Docs P2 Docs Learn Events
quick number conversion question — Parallax Forums

quick number conversion question

electricsmithelectricsmith Posts: 20
edited 2010-07-12 11:21 in Propeller 1
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))

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-07-10 04:21
    Much easier is: xgyro := (xgyro << 18) ~> 18

    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
  • electricsmithelectricsmith Posts: 20
    edited 2010-07-10 04:37
    So should i use a separate variable instead of working directly on the data variable that is declared as a word in the Dat section? I tried the shift left and sign and extend and it gave me zero. If I used a different variable that is declared as a Long to do this intermediate stuff, then that should work like you say?
  • Mike GreenMike Green Posts: 23,101
    edited 2010-07-10 14:51
    I'm not sure what you're describing. You might give a code fragment to show what you mean.

    You don't need an explicit long variable since all intermediate values are 32 bits.
  • TimmooreTimmoore Posts: 1,031
    edited 2010-07-10 16:12
    Spin works with 32bit variables, So when Mike sign extended he sign extended 32bits, if xgyro is 16bits this get truncated. When you pass to ffloat its not a 32bit sign extended no, its a 16bit signed extended but 0 filled to 32bit so you need to sign extend from 16 to 32 bits that is what the ~~ operator does (its the same as
    (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
  • electricsmithelectricsmith Posts: 20
    edited 2010-07-12 10:50
    Thank you guys so much. I understand what you are saying. The shift left and sign extending right worked good. I changed the xgyro variable to a long instead of word and it worked great to dump the two msb's and keep the sign. When I debug the decimal value of the result I get the right number including it's sign after that command. I didn't need to do anything to change from two's complement so I just deleted that code. When I take the signed xgyro and try to convert it to floating point, what I debug to the serial terminal becomes garbage though after the ffloat(xgyro) command, then the fmul(xgryo, conversion_factor) makes it worse. I think I not reading the floating point variable out to the serial terminal right. I was using the simple-debug object and the dec command to do it. I'm sure the value is correct, I just am not understanding the difference in the signed integer format and signed floating point format, and how to get the two different values to display properly.

    Thanks again for the help.
  • electricsmithelectricsmith Posts: 20
    edited 2010-07-12 11:17
    By the way, I assumed that I needed to send as a string to the debug port instead of using the Dec command (which that may be my only problem with that issue), so I used the float to string prior to using the debug.str command. It gives me just the pointer to string coming back from the float to string command and not the string.

    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
  • max72max72 Posts: 1,155
    edited 2010-07-12 11:21
    Check your float object. You should fine a "to string" funtions. Use it to send a string to the terminal.
    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
Sign In or Register to comment.