Advanced hard and soft iron magnetometer calibration for dummies

If you bought the cheap magnetomter module like HMC5883L you can not use it without calibration. Measurement of magnetic field will be subjected to distortion. There are two categories of these distortions: the hard iron distortions and the soft iron distortions. The hard iron errors refer to the presence of magnetic fields around the sensor (magnets, power supply wires) and are related to measurement offset errors, while the soft iron errors refer to the presence of ferromagnetic materials around the sensor, which skew the density of the Earth's magnetic field locally and are related to scaling offset errors. You can read more information about these distortions here.

In other words, to get the correct magnetometer data you should get the calibrated magnetometer data. One of the ways to resolve this problem: you should apply the bias to the vector of the non calibrated magnetometer data (X, Y, Z coordinates) and then multiply the transformation matrix by this resulting vector:

Picture 1

In this case the magnetometer calibration is the process of getting the transformation matrix and the bias. To get these data you can use the MagMaster program.

You can download MagMaster here.

Example of using the MagMaster



  • MagMaster (placed in MagMaster folder)
  • MagViewer (placed in MagMaster folder)


  • Arduino Sketch (placed in MagMaster folder)

Picture 2

Picture 3

Picture 4

Connect the magnetometer module to the arduino board via I2C bus (picture 4). Upload the arduino sketch to the arduino board (see "Arduino_Code" folder in the "MagMaster" folder). This arduino sketch requires the HMC5883L library, copy the folder "HMC5883L" (placed in "Arduino_Code" folder)  to the folder "C:\Program Files\Arduino\libraries".

Then run the MagViewer.exe, select the serial port of the arduino board (the boud rate of the seraial port should be 9600 bps) and click "Run MagViewer". Now you can see the coordinates of the magnetometer data vector in 3D space on a real time (picture 5, video 1, 2). These data are not calibrated yet.

Picture 5

Video 1

Video 2

If you see the points of the magnetometer vector coordinates in 3D space the arduino board and the PC connection works right.

Now close the MagViewer window and run the MagMaster.exe (picture 6). Select the serial port of the arduino board. The green strings X, Y, Z will indicates the coordinates of the magnetometer vector.

Picture 6

Place the magnetometer module as shown on the picture 8.1 and click "Point 0" button of the "Axis X+" groupbox. For the placement of the module you can use the wooden bar or the paper box (picture 7). If you can not connect your magnetometer device to PC then you can use any other way to get to know the magnetometer data. You can enter these data in the program manually.

Picture 7

Place the magnetometer as shown on the picture 8.2 and click "Point 180" button of the "Axis X+" groupbox and so on. You should do in the following way:

  • Picture 8.1: "Point 0", "Axis X+"
  • Picture 8.2: "Point 180", "Axis X+"
  • Picture 8.3: "Point 0", "Axis X-"
  • Picture 8.4: "Point 180", "Axis X-"
  • Picture 8.5: "Point 0", "Axis Y+"
  • Picture 8.6: "Point 180", "Axis Y+"
  • Picture 8.7: "Point 0", "Axis Y-"
  • Picture 8.8: "Point 180", "Axis Y-"
  • Picture 8.9: "Point 0", "Axis Z+"
  • Picture 8.10: "Point 180", "Axis Z+"
  • Picture 8.11: "Point 0", "Axis Z-"
  • Picture 8.12: "Point 180", "Axis Z-"

Picture 8

You should fill the table. After that click "Calculate Transformation Matrix and Bias" and get the required matrix and bias (picture 9).

Picture 9

The transformation matrix and the bias are got. Now you can calculate the calibrated magnetometer data in your device on a real time with using the matrix and the bias as shown on picture 1. The example of the arduino sketch of using this calculation you can find in the "Arduino_Test_Results" folder.

You can apply the sphere radius stabilization algorithm to your program (use for it the Arduino_Radius_Stabilization folder placed in MagMaster folder).

The calibrated magnetometer vector coordinates in 3D space with the radius stabilization shown on the picture 10 and video 3, 4.

Picture 10

Video 3

Video 4

Using of the arduino is only example, you can easy adopt the arduino code for any other system and use the MagMaster program with it.

Views: 123214

Comment by Samuel on July 11, 2014 at 5:51am


thanks for this great article. I have a question about the compass calibration, hope you can help me out. I have a device that rotates based on the heading i read from the compass. I already do the hard iron and that gets me pretty close to the result i want to get. But its just slightly off, so i guess i need the soft iron as well.

I want to calibrate it on the field as well to get the real compass values from outside without any disturbances i have in my house, so i want to start the calibration by pressing a button for example.

For this i need to know how to calculate the matrix from withtin the arduino. Can you tell me how to calculate M11 ... M33?

Same for Bias...i read, that bias is calculates by (Xmax - Xmin)/2 but i dont really come to these values based on the MagMaster screenshots you showed...



Comment by William Premerlani on July 11, 2014 at 7:19am


Very nice tutorial, I really enjoyed it.

Another factor that must be considered is mutual alignment of gyros, accelerometers, and magnetometers. Even if each of them is working perfectly by itself, that is not enough. In addition, they must be approximately aligned with each other. If not, then their misalignment must be accounted for.

If they are all mounted on the same board, then they are aligned with each other well enough.

However, if the magnetometer is mounted separately, it might have enough misalignment with respect to gyros and accelerometer that cannot be ignored, because of the large vertical component of the earth magnetic field. A misalignment of as little as 5 degrees can cause problems.

It is possible to detect and compensate for this effect in flight. More more information see this discussion.

Best regards,

Bill Premerlani

Comment by Yury Matselenak on July 11, 2014 at 11:27am

I am not sure that it is possible to calibrate the magnetometer on the field with the method described in this article, because for the calibration using this method you should place the magnetometer orthogonally to the earth plane (in this article for this I used the wooden or the paper box).
But if you can place your device orthogonally to the earth plane and rotate it how it is shown on the picture 8 then the calibration with this method is possible.
I think you can write this algorithm for the arduino board. For writing my algorithm I used this article (this is the theory). This is russian language post, but I  think you can translate it to english by google translate. About the practical part, here I shared the MagMaster source code, function of the transformation matrix and bias finding called calculate_transformation_matrix(). This is Visual Studio 2010 C# project (sorry for not very optimised code).

Comment by Yury Matselenak on July 11, 2014 at 11:29am

William Premerlani,
thanks, your article is very interesting. I thinked about the mutual alignment of the magnetometer, accelerometer  and gyro. Your method is good. I have the thoughts abot magnetometer, accelerometer and gyro aligment too. But I think that the good solution it the field calibration of the magnetometer and accelerometer and gyro together  mounted on the device (airplane, drone, robot). Accelerometer and gyro can be calibrated like the magnetometer.

Comment by Samuel on July 11, 2014 at 11:29am

Thanks mate. Will try and report back here.

Comment by JLJu on July 11, 2014 at 1:37pm

Of course Accelerometer and Gyro need to be calibrated and compensated;also for mounting position.
A thought about results presentation. It's a lot easier to compare performances if along with the method procedures is also provided a procedure to calculate measurement uncertainty. In your case I refer to the uncertainty term added by your calibration procedure.

For instance in my Pitot log I report the airspeed value with the related uncertainty. Let's say 25.1(0.2)m/s. In the case of the Pitot an uncertainty approximative(overestimated) formula can be provided; that formula can account for the most common sources of uncertainty.

With that kind of result presentation is easy to select instruments or procedures.

Comment by Samuel on July 14, 2014 at 5:11am

Hi Yuri,

just had a look at your code. You really seem to need those 8 different positions for calculating the matrix in your example.In my project i can not bring the device to those 8 stages. Is it possible to calculate that matrix in another way? You asked if i can level my device...In fact its put on a tripod so it should be leveled. But i can only rotate it around x and y axis as its fixed to the tripod.

So for an automatic calibration i could get max/min x and y values only, but its possible to have steps like 0/90/180 and 270 degree by hand.

I dont need the z-axis as i dont do any tilt compensation. Do you have an idea what i could do to still get a soft iron calib?



Comment by Tim C on July 15, 2014 at 11:24am


I am able to read sensor data from MagMaster. However, MagViewer only displays xyz coordinate system but nothing happens. What Unity plugins do I need to install?


Comment by Yury Matselenak on July 15, 2014 at 12:34pm

Tim C,

You do not need any Unity plugins. I do not know why MagViewer doesn't work in your case. May be you have selected wrong com port or boud rate...

Comment by Yury Matselenak on July 15, 2014 at 12:37pm

Tim C,

Do you use the arduino board or other one?


You need to be a member of DIY Drones to add comments!

Join DIY Drones

© 2020   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service