Give me a sign
rjo__
Posts: 2,114
in Propeller 1
I've been playing with this so long... it has become a blur.
I have a nifty BNO055 absolute position sensor with sensor fusion. It reports linear acceleration as signed 16bit integers.
When I display these values over serial, the signs are lost. Actual negative values are reported as the two's complement form... and appear as positive values. And if I do arithmetic on these values, the result appears as though the two's complement form of the negative values is actually a positive integer being operated upon.
What to do?
I have a nifty BNO055 absolute position sensor with sensor fusion. It reports linear acceleration as signed 16bit integers.
When I display these values over serial, the signs are lost. Actual negative values are reported as the two's complement form... and appear as positive values. And if I do arithmetic on these values, the result appears as though the two's complement form of the negative values is actually a positive integer being operated upon.
What to do?

Comments
NegMask = $0080
if ReadValue AND NegMask = $0080
then OR ReadValue, $FF00
should work. You know what I'm saying :P
Yep, that's it. The ~~ at the front of a variable extends the sign from bit 15 (a single ~ extends from bit 7).
I had trouble figuring out which version to show you... but your question got me looking and Iit turns out that I was declaring a long but bit shifting it as though it were a word... duh.
I also discovered that if I declare a variable as a word and then assign a -1 to it, what comes back is the two's complement form... but for as a long it comes back as -1... who would have figured?
I don't have it completely sorted yet, but this appears to be my first mistake.
Thanks,
Rich
Your example is actually showing extension to a 16-bit value from a signed 8-bit number. In Spin you need to use longs for correct results with signed operations. Here's a way to do what you're suggesting if the special operator is not your cup of tea.
if (sensorvalue & $8000) sensorvalue |= $FFFF_0000Another what to so this in Spin -- if the sign is not in in bit 15 or bit 7 -- is like this:
The ~> (SAR, shift arithmetic right) works like a right shift but fills bit 31 with the previous contents of bit31 (instead of 0 as a standard shift does).
PRI Get_Acceleration_Data accxi:=i2c.readByte(BNO055,LIA_DATA_x_MSB) accxi:=accxi<<8 mydata:= i2c.readByte(BNO055,LIA_DATA_x_LSB) accxi:=accxi+mydata mydata:=accxi tester:=1 mydata:=mydata<<17 mydata:=mydata>>17 if mydata<accxi accxi:=1+ not(accxi) tester:=-1 accx :=tester*accxiThe shift by 17 assumes that the data is only 15 bits. If you really have 16 bits of data you could shift by 16, or you could use the "~~" sign extension operator.
Thanks guys
I'll tell you what though, even with my miserable programming... this little package is looking just fine:)
I'm going to look at this again in the AM
Thanks