Sie sind auf Seite 1von 3

Magnometer calibration

November 16, 2014 Alex 2 Comments


All of our smartphones have an integrated compass. It can be very useful when you are looking for in which
direction you should start heading while walking. However, you have probably noticed that sometimes, the
direction showed by our phones can be quite...wrong! It happens when the compass has not been calibrated
correctly. But if you try to turn the compass around in every direction, you'll probably notice that the direction
arrow finally takes the right direction. Why? Because the smartphone is doing a "live" calibration as you move
the compass.
What you should keep from this introduction is that compass calibration is fundamental ! Don't intend on
using a magnetic sensor in your project unless you have it calibrated. Otherwise, the data you'll be using will

probably be inaccurate, if not completely random


Back to basics
What does a magnetometer do?
"Well, it obviously gives you your heading!"
"NOPE! (Chuck Testa)"
The magnetometer gives you a three dimensional vector of the magnetic field it senses. This magnetic field is a
combination of both the earth's field and of the magnetic field created by all the surrounding objects. And this
second magnetic field is far from being negligible, especially in our hobbyist projects where there's electronics
(and motors) all around.
Theoretically, the measured magnetic field should :

 be centered around 0
 always have the same strength

If we could represent it in 3D, it should basically look like a perfect sphere centered in 0.
In reality :

 it is not centered around 0, because of the presence of other magnetic fields around the sensors(such as
other magnets, electric wires) : it is hard iron distortion.
 it does not have a constant strength, because of the presence of other ferromagnetic materials around
the sensors, which skew the magnetic field. This is soft iron distortion.

What we get is essentially a potato-shaped magnetic field (because of soft iron distortion), that is not even
centered (because of hard iron distortion).
Calibration techniques
Hard Iron distortion
Hard iron errors introduce an offset in the magnetometer data
To get this offset is pretty simple : we keep track of the maximum and minimum values the magnetometer
outputs on each axis while moving it in space. From what we know the maximum and minimum should be
centered around 0, so we get the offset by :

We can then subtract the measured offset from each raw measurement in order to get hard iron free data.
Soft Iron distortion
Here, the work consist in transforming a potato in an orange. Or, transforming an ellipsoid into a sphere, if you
prefer. It's actually easier than it sounds. There are obviously mathematical formulas that involve matrices but
let's keep it simple here.
Let's say earth magnetic field's value is F. It is the norm of the vector given by the magnetometer. While we've
seen it should be the same on the three axes, experience shows it's not. So let's assume we have measured the
maximum magnetic field Fx for the x axis,Fy for the y axis, Fz for the z axis.
We then calculate the average field value F by :

Let's assume that F = 1. If F_x = 0.8, it means that F_x is only 80% of the average field value. Hence the
potato. Now if we simply multiply all the incoming x values by F/F_x, the potato effect, will be gone, as we
expand the range of the x values so that it is no longer 80% of what it should be, but 100%.

Final equation
If we no combine the two equations and use vectors, we get:

Scale transforms the potato into an orange(soft iron distortion) and the Offsets vector brings it back in the
center(hard iron).
Calibration process
The calibration consist in getting the min/max values of x/y/z fields, and then calculations the offsets and scale
factors. The more you move the magnetometer in all directions, the more efficient your calibration will be.
Using calibration data
?
01 // We get the raw values here in mx,my,mz
02
//(this is pseudo code)
03
04 mag.getHeading();
05
06 // Now we apply the calibration data
07
08 mx = (int)((scale_x)*(mx-x_offset));
09 my = (int)((scale_y)*(my-y_offset));
10 mz = (int)((scale_y)*(mz-z_offset));
11

Das könnte Ihnen auch gefallen