Hard Iron Calibration of a Magnetometer Using a CSV Data File


I recently worked with a client to explore hard-iron calibration of a magnetometer’s output.  I found some really helpful information from Freescale in their application notes AN4246, AN4247, and AN4248.  These all relate to tilt compensation of an eCompass.  These application notes are directed toward a cell phone application.

I found the equations detailed in AN4246: Calibrating an eCompass in the Presence of Hard- and Soft-Iron Interference to be useful.   You can Google the other application notes for additional information.

One thing that wasn’t useful, was that I couldn’t find an example online of converting a *.csv file of magnetometer measurements to appropriate hard-iron bias calculations. So I wrote an application myself.

Hard-iron interference is described in AN4246 as…

”The application note AN4247, section 6, defines the hard-iron offset as resulting from permanently magnetized ferromagnetic components on the PCB. Since the magnetometer and PCB rotate together, the hard-iron offset is a simple vector VPCB, which adds to the magnetometer reading. AN4247, section 6, also notes that any zero field offset in the magnetometer factory calibration will appear as a fixed additive vector VSensor.”

Essentially, the hard-iron interference is treated as an offset, or subtraction from each data axis.  In other words if you collect your magnetometer data and chart it as pairs of axes you will see it offset from the origin by an amount equal to the hard-iron interference.  I’ve charted a data set below.  In this chart the red dot locates is the origin, and the orange circle is the geomagnetic field.  If you were to chart all three axes you would see a sphere whose center is offset from the origin.  Ideally you want each axis pair to be located within the orange circle and centered on the origin.


If soft-iron impacts come into play the sphere is also squashed or tilted. Below is an image from AN4246.  The red data shows magnetometer plotted in 3 dimensions.  The data is impacted by both hard- and soft-iron interference.   The blue sphere is the same data compensated for these interference types.  It re-centers and sphere-izes the data.



Because hard-iron interference is different for different applications (the PCBs are comprised of different components) magnetometer manufacturers usually don’t calibrate their sensors after manufacturing.  A magnetometer’s location on the planet can also impact the hard-iron interference because magnetic declination changes depending on where you are on the planet.  If you use the compass application on your cell phone you will have to compensate for these effects.  In my iPhone I’m required to roll the phone around for this calibration to occur.

So back to my software.  I needed a way to verify that I was correctly calculating the bias values.  AN4246 gives an example data set of 6 magnetometer measurements.  It also walks you through the calculations and provides the resulting bias values.  This is great, because if I assume Freescale is correct in their derivation and calculations (which I do) I can use their values.  This allowed me to copy their application note values into an Excel spreadsheet, save the sheet as a *.csv file, and then open the file with my software.  I could then verify the results of my software’s calculations against their values.

My software accepts a *.csv file where column one is the X axis magnetometer values, column 2 is Y axis, and column 3 is the Z axis.


There are two ways you could populate the *.csv file values.  For my client I was already collecting data and exporting it as as a *.csv data set.  However there is another way you could collect the data, and it is described (although vaguely) in AN4246.  If you match the magnetometer data with accelerometer data points you can get by with calibrating for hard-iron interference with just 6 data points.  Many applications where hard-iron interference needs to be calculated incorporate accelerometers and gyroscopes, so you may find this useful.

If you rotate your PCB and take note of the min and max accelerometer values along each axis (6 measurements total) you’ve just traced out the end-points of a sphere defined by the accelerometer’s gravitational measurements.  This sphere is decoupled from the magnetometer as it is not impacted by magnetic interference.  Collecting the X, Y, and Z magnetometer values at each accelerometer min/max gives you the extent of the magnetic sphere without the hard-iron bias subtracted.

Entering those values into a spreadsheet (in the format I previously described), saving the file as a *.csv file, and opening that file with my software, can allow you to calculate these offsets.

In my application I tried did that, as well as collecting all of the magnetometer data as the PCB was rotated around all angles.  The resulting bias calculations are similar enough for calibration.  Below I show a much larger data set with the hard-iron interference calculated and subtracted from the raw data.  You can see that the magnetometer data is now centered on the origin and, for the most part, within the geomagnetic field calculated.


My software was written in VB using Visual Studio 2013.  I also had to add Mathnet.Numerics to the project for access to the matrix math (linear algebra) functions.  In the zipped file are 3 data sets, 2 of which are experimental sets that I generated with an ST Microelectronics LSM9DS1.  The third is the Freescale AN4246 data used to verify the results.  I also included a Setup file which should allow you to install the program using the *.msi file located in the file structure below.

At the end of the day incorporating hard-iron calibration into your measurements is pretty simple.  Just subtract the bias values from the associated axis.  For example, X_magnetometer_calibrated = X_magnetometer_raw – X_bias.


Here is link to the zipped software files…



  1. Hi there,

    I couldn’t quite bear the monstrousity of app note that NXP released, so I firstly didn’t manage to go through all of it. After I’ve seen your code, I realized to what simplicity the compensation algorithm goes down. Thanks for that!

    • I’m glad you found it helpful.


      • Hi again,

        firstly I was about to do the work myself, cause the math is actually not too complicated. But I found your GUI inlcluding the offset vision etc. so useful, I will just use that for thehard-iron calibration of my sensors. Really good job, keep on going.

Speak Your Mind