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:

3689598033?profile=originalPicture 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)

3689598066?profile=originalPicture 2

3689598042?profile=originalPicture 3

3689598079?profile=originalPicture 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.

3689597980?profile=originalPicture 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.

3689598100?profile=originalPicture 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.

3689598052?profile=originalPicture 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-"

3689598213?profile=originalPicture 8

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

3689598116?profile=originalPicture 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.

3689598230?profile=originalPicture 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.

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones


  • All,

    I'm planning to make another run at the  J.Merayo et al. "Scalar calibration of vector magnemoters" technique, but all references to the original paper point to paywalls of one sort or another.  Anyone have a copy they can send me?



  • All,

    See my blog post for an update on the 'outlier pruning' feature on my calibration GUI.  You'll still need the MATLAB file referenced in the post, but at least you'll be able to generate a good dataset for the run ;-).




  • Yuri,

    I downloaded and opened your MagMaster source, but I found only the 'MagMaster' files, not the 'MagViewer' ones.  It is the viewer that won't open the higher comm ports :-(



  • Well, I may have spoken too soon about porting the MATLAB routine to C#.  I'm getting lost in the translation from MATLAB code to MathNet matrix functions.  For instance, I am reasonably sure that the MATLAB line

    D=triu(qr(D));%avoids to compute the svd of a large matrix

    corresponds to the MathNet.Numerics code

    //D=triu(qr(D));%avoids to compute the svd of a large matrix
    QR<double> DQR = D.QR();
    Matrix Q = (Matrix)DQR.Q;
    Matrix R = (Matrix)DQR.R;

    Matrix D2 = (Matrix)R.UpperTriangle(); //this is the same as Octave's triu(qr(D))

    But the results from the same input test data set are not identical (close, but not exactly the same).  Also, the MATLAB code implements the Cholesky function as a user function, while MathNet implements a Cholesky class - same with the MATLAB code's Usolve() & Utsolve() functions.

    So, I'm stuck.  If there is anyone out there who can help with the MATLAB - to - MathNet.Numerics translation, please contact me ;-).

    In the meantime I discovered that the MATLAB code doesn't do a very good job of handling 'outlier' data, so I'm modifying my GUI to allow the user to visually select and remove outlier points from the dataset before using it for calibration.  At the very least, I'll wind up with a nice GUI front end to the MATLAB code :/


  • Harry,

    Yes, I have made a fair bit of progress.  I found a MATLAB that does a spherical estimate based on a random (but hopefully representative) set of magnetometer points.  Here's the text at the top of the routine:

    % performs magnetometer calibration from a set of data
    % using Merayo technique with a non iterative algoritm
    % J.Merayo et al. "Scalar calibration of vector magnemoters"
    % Meas. Sci. Technol. 11 (2000) 120-132.
    % X : a Nx3 (or 3xN) data matrix
    % each row (columns) contains x, y, z measurements
    % N must be such that the data set describes
    % as completely as possible the 3D space
    % In any case N > 10
    % The calibration tries to find the best 3D ellipsoid that fits the data set
    % and returns the parameters of this ellipsoid
    % U : shape ellipsoid parameter, (3x3) upper triangular matrix
    % c : ellipsoid center, (3x1) vector
    % Ellipsoid equation : (v-c)'*(U'*U)(v-c) = 1
    % with v a rough triaxes magnetometer measurement
    % calibrated measurement w = U*(v-c)
    % author : Alain Barraud, Suzanne Lesecq 2008

    I've got the graphics going, using my DevDept Eyeshot 3D viewer library, and I'm using Math.Net's Numerics library for the matrix math.  Should have it going within the next week or so, and I'll upload it here (however that is done) for you guys to shoot at ;-).


  • Frank,  Have you made any progress on your program? 

    I'm also trying something myself.  I took the 3Dscatter processing sketch and made an android "app" that reads an HMC5883 over the USB.  It gives the same visual as Yuri's MagViewer.  If I can wrap my head around his matrix math code, I want to add a button to calculate the transformation and bias.

    BTW, Yuri, I finally got my board calibrated using your MagMaster.  No point in borrowing if I couldn't get it right.


  • Hi Yuri.

    Is it possible to calibrate a 1-axis sensor in all three axis (x,y,z)?



  • Frank, here is the source code of my program:


    MagMaster source code. Contribute to YuriMat/MagMasterSource development by creating an account on GitHub.
  • Anyone have the math expressions for calculating the calibration matrix elements (M11 - M33) shown in the MagMaster program?  I'm building my own program for this, but don't know how these elements are calculated. Any help would be appreciated



  • Yes, I thought the 'high-number' comm port numbers might be the issue, but I couldn't find the source code, so no way to fix it.  Instead I am constructing my own 3D viewer in C# .net, using an old (but still working) version of the EyeShot 3D library.  I'll be happy to share it here, assuming I ever get it to a 'finished' state ;-)



This reply was deleted.