If you look at my reply #19, when I said "It can't be negative" I meant after the program I attached, the result is now positive, so is ABS needed now?
C
Assuming x_raw and y_raw are 16 bit variables read directly from the compass then we need to split them into their component parts.
sx=1 if x_raw was negative else 0 and ux is the positive value of x_raw. Ditto y values.
Code:
dim sx,sy,comp as byte
dim ux,uy,degrees as word
if x_raw>32767 then
ux=65535-x_raw
ux=ux+1
sx=1
else
ux=x_raw
sx=0
endif
if y_raw>32767 then
uy=65535-y_raw
uy=uy+1
sy=1
else
uy=y_raw
sy=0
endif
Now we have these parts we can use them to calculate an angle.
This produces a word variable between 0 and 359.
Code:
if ux>uy then
degrees=uy*45/ux
oct=1
else
degrees=ux*45/uy
oct=0
endif
comp=0
if degrees>22
if degrees<44
comp=comp+1
endif
if degrees<41
comp=comp+1
endif
if degrees<37
comp=comp+1
endif
if degrees<32
comp=comp+1
endif
else
if degrees>2
comp=comp+1
endif
if degrees>6
comp=comp+1
endif
if degrees>10
comp=comp+1
endif
if degrees>15
comp=comp+1
endif
endif
degrees=degrees+comp
if oct>0
degrees=90-degrees
endif
if sy>0
if sx>0
degrees=180+degrees
else
degrees=180-degrees
endif
else
if sx>0
degrees=360-degrees
endif
endif
After the above degrees will contain the answer.
Mike.
Edit, the above code is not self explanatory. It is written this way to avoid any floating point numbers and trigonometry functions.
Assuming x_raw and y_raw are 16 bit variables read directly from the compass then we need to split them into their component parts.
sx=1 if x_raw was negative else 0 and ux is the positive value of x_raw. Ditto y values.
Now we have these parts we can use them to calculate an angle.
This produces a word variable between 0 and 359.
After the above degrees will contain the answer.
Mike.
Edit, the above code is not self explanatory. It is written this way to avoid any floating point numbers and trigonometry functions.
Hi C,
The orange section isn't needed.
The numbers should be 32767.
The errors are (as Eric pointed out) because the DIMs need to be split onto separate lines.
I'm assuming you have 3 values raw x, y & z. Use the two that give you the plane you want the direction in.
Hi, M and E,
Here's the code that works, and gives interesting results when PCB is compared to a compass, see attachments.
I'm pretty sure that X and Y are used for direction and Z is used possibly for tilt?
Thanks,
C.
Don't have time to check it now but looks like I messed up the quadrant part of the code. Will check tomorrow - Saturday night here, time to party.
I have a GY-271 board and, if it's flat, X and Y give the compass bearing.
Mike.
Edit, just noticed ux & uy are bytes - they should be words.
You have calculated two times the 2's complement of y_raw
so y_raw is always positive and the sign sy is always 0.
Could you show all x_raw and y_raw values before 2's complement and angles.
2's complement calculations are missing +1 at the end.
Don't have time to check it now but looks like I messed up the quadrant part of the code. Will check tomorrow - Saturday night here, time to party.
I have a GY-271 board and, if it's flat, X and Y give the compass bearing.
Mike.
Edit, just noticed ux & uy are bytes - they should be words.
Nice code !! .... I'm working on something very similar in Assembly
in your initial stage ux, and uy can be determined by XORing the MSB with a "1"
in your second stage, instead of using 45 to multiply the lowest number and dividing by the highest number, I am multiplying by 128 which is a simple shift left in Assembly language. Division is done by subtraction until there is an underflow. The result is used against a lookup table which effectively does what you have accomplished in a series of IF statements. The lookup table allows for at least 1/2 a Deg resolution.
In the initial code I posted I multiply by 32 and adjust so a full circle is 256 degrees. The ux, sx bit is due to the limitations of oshonsoft - it can't handle negative integers!!
Due to your comment I've just realised that an overflow may be taking place (even more so if times 128). My compass module never returns a value greater than 1000 so overflow isn't a problem, the OPs compass may be different and cause errors due to overflow. Cam, do you have actual values from your compass?
In the initial code I posted I multiply by 32 and adjust so a full circle is 256 degrees. The ux, sx bit is due to the limitations of oshonsoft - it can't handle negative integers!!
Due to your comment I've just realised that an overflow may be taking place (even more so if times 128). My compass module never returns a value greater than 1000 so overflow isn't a problem, the OPs compass may be different and cause errors due to overflow. Cam, do you have actual values from your compass?
Nice code !! .... I'm working on something very similar in Assembly
in your initial stage ux, and uy can be determined by XORing the MSB with a "1"
in your second stage, instead of using 45 to multiply the lowest number and dividing by the highest number, I am multiplying by 128 which is a simple shift left in Assembly language. Division is done by subtraction until there is an underflow. The result is used against a lookup table which effectively does what you have accomplished in a series of IF statements. The lookup table allows for at least 1/2 a Deg resolution.
Hi J and P,
I can set, to READ 2x X_raw and 2x Y_raw, Which angles should I READ? e,g, 360 x 6 readings is a lot, so not too many please. Best not to choose exactly as the code changes if possible.
EDIT: Note Oshonsoft needs a THEN for each IF.
Is this all ok ''OCT''
Dim sx As Byte
Dim sy As Byte
Dim comp As Byte
Dim ux As Word
Dim uy As Word
Dim degrees As Word
Dim strdegrees As String
Dim oct As Byte '?????????????????????????????