Reputation: 527
I'm using an embedded device with a simple 3-axis Magnetometer on it. I have it currently displaying the X Y Z values in micro Teslas but how do I convert these into a compass heading? I have tried looking it up on Google but everything I find seems extremely complicated/poorly explained.
If possible I'd like to know how to do it both tilt-compensated and also without compensating for tilt.
The values I'm currently getting on a flat surface for X, Y, Z are 70,0.8 and 34.1 respectively in case that somehow helps.
P.S In case it helps here is a snippet of the code I'm using for the magnetometer:
mSensor.enable();
while(true){
wait(1);
mSensor.getAxis(mData);
lcd.cls();
lcd.locate(0,3);
lcd.printf("X=%4.1f micro-Tesla\n\rY=%4.1f micro-Tesla\n\rZ=%4.1f micro-Tesla", mData.x, mData.y, mData.z);
Upvotes: 10
Views: 30656
Reputation:
You first need calibration (either using the device calibration method, or, by rotating it in a complete circle to ascertain the full field strengths).
You can then use the X, Y, and Z readings to compute the location of "north" relative to whichever way you're pointing (keeping in mind that "north" changes as much as 30 degrees depending where on earth you are (called declination - see http://www.magnetic-declination.com/), and that it's not horizontal to the ground either (confusingly, called "inclination" - see https://physics.stackexchange.com/questions/283761/if-you-hold-a-compass-needle-vertical-does-it-point-down-or-up-differently-on-wh/283782 )
If you picture the X, Y, and Z readings as meaning "where on an imaginary circle is the direction of magnetism - where those 3 circles are on 3 different planes, you can compute the logical position of a vector pointing towards magnetic north in 3 dimensions.
The bad news - there's no simple way to do what you want accurately, and definitely not one that's going to work without trig math on all 3 readings (you can't just use X and/or Y alone).
The good news - you probably don't really need to know an actual "heading" - most applications just need some local relative direction as compared with something you already know.
Beware that strong magnets (such as ones in all modern motors) seriously mess with readings from a long way away (10 or more foot even) - grab an app from your phone store that shows your phone magnetometer readings, and wave a magnet around to see this easily!
Upvotes: 3
Reputation: 12047
Without compensation for tilt it's not too complicated:
angle = atan2(Y, X);
That's actually the same as converting a vector in cartesian coordinates [X, Y] to a vector in polar coordinates [length, angle], without needing the length.
For the tilt-compensated version, you need to project the 3D-vector [X, Y, Z] onto a plane [X2, Y2] first and then use the same formula as before. But to do that you would need an accelerometer to know the amount of tilt.
Upvotes: 15