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: 124025

Comment by Tim C on July 15, 2014 at 12:46pm

Arduino micro, with you code. I can see output from serial terminal just fine but it doesn't work with the MagViewer.

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


Yes, this method is not ideal. This is not good idea for the field calibration. For calibrating by this method you need 12 different positions (even not 8). I do not know how whithout these positions to find soft iron transformation matrix.

If you need not the Z coordinate, it will be 2D magnetometer. I think it is possible to calibrate magnetometer by  only ratation around the axis ortogonal to the earth plane in this case. But I don't know how to do it :). I think about it, but i have not ideas yet.

Can you tell me: your device will have pitch and roll? or only yaw?

Comment by Yury Matselenak on July 15, 2014 at 1:39pm

Tim C,

I will try to run the MagViewer on the computer without installed Unity and report here.

Comment by Tim C on July 15, 2014 at 7:05pm


I ran your program on another desktop to calibrate a magnetometer. The MagMaster works fine but MagViewer stuck after the Unity splash screen and froze as opposed to displaying xyz coordinate system.

The specs for two computers I have tried:

win7 Ultimate, 12G ram, i7  (only displays xyz coordinates, laptop)

win7 Enterprise, 4G ram, i5 (freezes after Unity splash screen,desktop)

Arduino mini. Baudrate 9600, output format "mx,my,mz" for each line.

MagMaster works on both computers. Does MagViewer use RTS or CTS lines? If so, can you publish a version without using it? My current setup won't allow me to use pins in UART other than RX, TX.


Comment by Samuel on July 15, 2014 at 10:33pm

Ok let me explain my project:

Its an antenna tracker that uses a 360° continuous rotation servo for pan. As i cannot control the angle of that servo i want to use a compass. The servo will move until the compass says target reached. I use a PID controller for that, but thats not so important for this.

So what i do now when i calibrate is get xMax and xMin, yMax and yMin do the (xmax-xmin)/2 and (ymax-ymin)/2 and use this as offset to substract from the current read x and y values.

The initialisation process is the same as multiwii, you can look it up here:

This works ok so far but when i target 0/90/180/270 degree i have a slight offset of around 5 degree. Didnt measure yet if 0° is truly north. will do that this evening.

Comment by Yury Matselenak on July 18, 2014 at 7:02am


May be the better way for your task is using of the optical encoder instead of the magnetometer?

Comment by Samuel on July 18, 2014 at 7:11am

Compass works great if its calibratet. See MyFlyDream Antenna Tracker. As i said before we achieve pretty good results already, but it could be done better, thats why i want to try soft iron. But if it doesnt work with your method i'll find another one ;)

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

Tim C,

MagViewer does not use RTS or CTS lines. I use the Arduino Mega 2560 board with own usart-usb converter. Can you place here the screenshot of your arduino termanal?

Comment by Michael on July 30, 2014 at 8:13pm

Hi Yury,

I followed your instructions and ran the calibration with the following results. I'm very new so I'm not sure if anything looks wrong in my results. Can you confirm my results? Please let me know if I need to re-do this test.

Kindest regards,


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


Try to read my comments for Harry above. Harry posted his first comment on June 28, 2014 at 5:24pm. I thinks your problem it is the same.


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

Join DIY Drones

Season Two of the Trust Time Trial (T3) Contest 
A list of all T3 contests is here. The current round, the Vertical Horizontal one, is here

© 2020   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service