# Twos compliment in Oshonsoft and Compass calibration

#### camerart

##### Active Member
Oshonsoft interpreters all integers as positive.
For example 16 bit word as 0-65535.
When you know, that the integer is 2's complement, you must take care of the sign in the program.
You can do it easily by converting the signed integer to a floating point variable ( see msg #12 ), as was done in the BMP280 calculation or carry the sign in a separate variable.
Hi J,
I follow.
My point is that, when receiving 2's complement, I would only be able to alter it after it has been gleaned by Oshonsoft, so would it have been corrupted in any way before applying (msg#12)?
C.

#### jjw

##### Member
Hi J,
I follow.
My point is that, when receiving 2's complement, I would only be able to alter it after it has been gleaned by Oshonsoft, so would it have been corrupted in any way before applying (msg#12)?
C.
I don't quite understand what you mean.
If the data is corrupted, how can you know it?
Or do you want to make some filtering / averaging?

#### camerart

##### Active Member
I don't quite understand what you mean.

If the data is corrupted, how can you know it?
Or do you want to make some filtering / averaging?
Hi J,
I think the penny has dropped.
C.

Last edited:

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Hi J,
Because it states in the D/S that integers are 2's complement, then they are negative. Once they are READ by Oshonsoft, and bearing in mind that Oshonsoft doesn't support negatives, then what state are they for the program to work on?
C.
You are reading too much into this 2's complement thing.... The output of the chip is a word... The number will be 0 to 65535 IF!! the number is bigger than 32767 then its negative!! Is as simple as that!! Your output is apparently
4095 to -4096 where 0 is flat!! If the value is bigger than 32767 then subtract it from 65536 and you will get the correct number!!

#### camerart

##### Active Member
You are reading too much into this 2's complement thing.... The output of the chip is a word... The number will be 0 to 65535 IF!! the number is bigger than 32767 then its negative!! Is as simple as that!! Your output is apparently
4095 to -4096 where 0 is flat!! If the value is bigger than 32767 then subtract it from 65536 and you will get the correct number!!
Hi I,
Again! the penny has dropped, thank you all for your patience.
I'll let you know, how I get on.
C.

DELETED

Last edited:

#### Pommie

##### Well-Known Member
Think of what happens when you decrement or subtract 1 from a number. It will eventually go to zero and on the next decrement it will be 0xffff or minus 1 - the same as in decimal. It's just a convenient way to represent negative numbers.

Mike.

#### camerart

##### Active Member
Think of what happens when you decrement or subtract 1 from a number. It will eventually go to zero and on the next decrement it will be 0xffff or minus 1 - the same as in decimal. It's just a convenient way to represent negative numbers.

Mike.
Hi M,
I had to experiment for some time to figure out that, although I thought I was dealing with BITs BYTEs and WORDs, I needed to use LONG to accommodate the suggested subtract from 65536. No wonder Oshonsoft rejected it Using BINARY allowed me to visualise better.
C.

#### jjw

##### Member
Hi M,
I had to experiment for some time to figure out that, although I thought I was dealing with BITs BYTEs and WORDs, I needed to use LONG to accommodate the suggested subtract from 65536. No wonder Oshonsoft rejected it Using BINARY allowed me to visualise better.
C.
Subtract from 65536 was suggested, when the data was first converted to floating point.
With 16 bit words you can subtract from 65535 and then add one.
I think floating point is needed, when calculating angles from x,y
( arctan ( x/y ) )

#### camerart

##### Active Member
Hi J,
True, I'm sure I'll need it, but just couldn't visualise it as a number, until, I changed it to BINARY.
C.

DELETED

Last edited:

#### camerart

##### Active Member
Hi,

Because I appear to be getting errors in the results, I have set the program to show X and Y in separate BYTES and each WORD on the output screen.

The LB appears ok and shows 0 to 255
The HB only shows 0 or 254 or 255.

I understand the high BIT of the HB is the + - indicator, but I can't see which of the other BITs combine with the LB to give 12BITS.

Is there an error?

C.

#### jjw

##### Member
What is the gain setting?
It might be too low.
According the d/s the values can be from 0xF800 to 0x7FF

#### camerart

##### Active Member
What is the gain setting?
It might be too low.
According the d/s the values can be from 0xF800 to 0x7FF
Hi J,
It was the default 0x20
I turned it up to max %11100000 and now the HB is always 0 or 255.

From your reply, I can now see that it is the lower 3xBITs in the HB that makes up the 12BIT together with the LB. (Remembering that the HB high bit is the +- indicator)

EDIT:
I tried all of the gain settings, and at the lowest setting, if the module is moved in all directions, and tilts, then X and Y give 0, 1, 2, 253, 254, 255
Y occasionally gives 252.

This looks promising, so I'll try it in the program, which has the XY calculation. If it works, I'll then try to include the Z correction.
C.

Last edited:

#### camerart

##### Active Member
Hi,
Finding a compass module has been a bit of a puzzle. It needs to be SPI configured, which isn't always straight forward.
I found a likely one, used in iphones AK8963C. This appears to be working, here is a TXT of READings, showing the registers: Xx2 Yx2 Zx2. First I rotated as a compass, then a 'barrel roll' then head over heals.

Can someone verify, that the BYTE which is mainly 0 or 1 or 254 or 255, is the SIGN BYTE, before I proceed please?
C.

#### Attachments

• 2.6 KB Views: 3
• 2.6 KB Views: 4
• 23.8 KB Views: 2

#### rjenkinsgb

##### Active Member
I'd say it's a 16 bit twos complement number & the mostly 0 / 255 byte is the top half of the value.
It look like the range is about +/- 360 so the high byte does not have a large range.

so eg. for a line with varied values:
DATA 253 254 101 255 151 0

In hex that is:
FD FE
65 FF
97 0

Swap bytes and you get:
FEFD = -259
FF65 = -155
0097 = 151

#### camerart

##### Active Member
I'd say it's a 16 bit twos complement number & the mostly 0 / 255 byte is the top half of the value.
It look like the range is about +/- 360 so the high byte does not have a large range.

so eg. for a line with varied values:
DATA 253 254 101 255 151 0

In hex that is:
FD FE
65 FF
97 0

Swap bytes and you get:
FEFD = -259
FF65 = -155
0097 = 151
Hi R,
Yes, it's definitely twos compliment, and I guessed the BYTEs were the wrong way round, but I don't have confidence in maths, so I'm glad you verified it.
I'll swap the two BYTEs round and carry on, thanks.
C.

#### Pommie

##### Well-Known Member
That's just normal big endien.

Mike.

#### camerart

##### Active Member
Hi,
M, Ok.

J, How did you get those results in #36? I have an APP on my phone, for viewing and converting DEC, HEX, BIN, which has simple calculations. I'd like to play with twos compliment for a bit, so I get more familiar.
C.

#### rjenkinsgb

##### Active Member
I just used the calculator supplied with Windows..
Set it in Programmer mode (in View), then "word" as the data size option.

Entering the value while hex is selected, then switch to decimal.

For a generic calculator, enter the hex (in hex mode), convert to decimal then if the number is larger than 32767, subtract 65536.
That should give the same results.

[Or another way - if negative (high bit set) bit-invert it; "NOT" operation in some things, then add 1. That gives the positive version of the negative number. The same sequence converts positive to negative.]