Main Site Documentation

Calibration of Compass Module


Has anyone else used the compass modules from Seeed?

We are seeing serious non-linearities in the output of the devices. Even in raw vector mode, the X and Y components don’t seem to make sense.

In order to reduce the effect of hard-iron offsets we’ve tried multiple, physical locations away from all ferrous materials. The only ferrous materials in our entire assembly are the crystal cover, the GPS module cover and the USB connector on the Cerb40. All of these are more than 25mm from the Honeywell sensor.

To deal with soft-iron factors we’ve settled on a look up table.

So the question! Has anyone else developed a calibration routine or strategy that we can use to linearise the output?
This is for a fixed installation and the calibration should ideally be of the table look-up variety (it can’t be done in service easily). I have no aversion to applying mathematical transformations either - plenty of CPU time available.

Thanks for the ideas!


OK, did some testing and thinking and managed to calibrate the compass module accurately enough for my application.

The magnetic field sensing suffers from hard iron and soft iron errors, as well as standard production tolerance issues. There’s some really good data at

I’ve found a function that works for my electrical and mechanical layout to correct for the sensor deviations.

I’ve also changed the driver to use the System.Math.Atan2() function to generate the raw magnetic angles. Seeed had used a custom fn, maybe the new fn wasn’t available before NETMF4.2.

There’s a graph attached showing the before and afters.

It’s now accurate to within about 2° or so. There’s plenty of measurement error in the raw data :slight_smile:


It would be great if you can share something on codeshare for community to benefit from now or in future :slight_smile:


Sure will Gus, as always.

Would be great if there was someway to push changes to be reviewed for inclusion in the main source. Those darn Seeed drivers are sorely neglected…

BTW, I’m getting the feeling that there’s a better pattern to writing the drivers that would allow the same driver to be used in both pure NETMF and Gadgeteer contexts.


Additional Notes:
The compass module is 90 degrees out of ‘natural’ alignment.

The X-axis is actually forward (positive North) NOT the Y-axis.


I also have a question about magnetic declination on these modules.

Please note the following link from this document:

I just started a project that uses this module, and since my project also have a GPS, I would like to compensate for the magnetic angle correction. Does the existing seed drive cate for inserting GPS coordinates into the module as described above? It is probably unlikely as the one the Seed module uses HMC5883, and its datasheets does not appear to mention this anywhere. It would be usefull if that same lookup table was available somewhere and we could put it into a flash module.

I suppose I could also let the application self calibrate using the GPS when travelling at a speed in a car. And probably store the calibration value in an EEPROM.


@ KiwiSaner there is no way in the current driver to add magnetic declination. Also, you should note that the driver does not align the output with the axes correctly.

I should be posting something to Codeplex this week for NETMF4.2 that fixes both these issues, and allows for arbitrary ‘application rotation’ (mounting orientation).

Re: Calibration at speed - that would work for one direction, but the output of the compass is not linear - see hard iron and soft iron offsets.


Yeah… I suppose it probably impossible get it perfectly correct. But at least compensating for magnetic declination based on geographic location should improve it a little at least.

By the way… I realized today that there is a much more elegant way to do it if you have GPS data available. The RMC sentence of a compass includes the magnetic declination offset for the specific location. So its just a matter of adding or subtracting it from the compass reading. But it will also mean I cannot use the Gadgeteer GPS implementation.


That’s a really good idea to get the declination from the GPS.

My quick scan of the u-blox manual does not, however, fill me with confidence that the feature is implemented on the chipset (as used on the Seeed GPS module).

I’ll need to run a test to see the raw NMEA data stream.


i had checked the ublox-manual and only find only

in the descripton of the $GPRMC message.
i can’t find any message (NMEA and UBLOX) with an magnetic value… :frowning:


Apologies, my bad, you are correct.

However, I’m not confident the UBlox module supports this field, it is definitely part of the string sent via the serial port, but need to check if it’s actually ever filled in.


I will try it later tonight and report back if it works or not. I’m not really using the Seeed module though. I just wired up my own GPS which is also based on a Ublox NEO6. Probably the same engine as the Seeed module.


VB-Daniel : Sadly… you are right. The NEO6 does not send magnetic variation. Seems like I’m back to my other plan of calibrating against a speed with the GPS.


Bummer, that would have been really neat


Have a read of this…


@ Justin - Thanks. That is indeed a very interesting article and a interesting website in general. Do you know if that article refers to open source code? It sounds to me they solved the problem quite well by implementing a lookup table in flash memory.

Just for interest sake I played quite a lot with my Compass module tonight and I’m quite impressed with its accuracy when I offset the magnetic variation for my area. I tested it by using Google earth to calculate the exact bearing of some distant markers that I see in the distance from my house. Then I used the compass to verify that I get same bearing to these markers. And without exception it was spot on almost every time.

(My compass unit does come from Seeed… I just used a similar module which I already had, but it uses the same Honeywell chip, so it essentially the same thing).


@ KiwiSaner - its used in ardupilot so open source.
out of curiosity where abouts are you?


@ Justin - Hi Justin. It definitely sounds like something to investigate more. These guys have done all the groundwork and proofed it works.

An oh… I live in Auckland, New Zealand. Originally South African… hence the username. :slight_smile:


@ KiwiSaner - im from the north shore…


I had read a litte bit about magnetic variation and now i’m not sure if it’s realy important
the magnetic variation is a problem depending on ‘where you are’ and variate every year. In europe in the moment it’s 1-2° east. the accuracy of the sensor is 1-2° as well. So both superimpose each other. accurac of 2° is meaning about 200m error per 1000m distance traveled. so it’s only a problem if you have to go realy long route without a target to aim for. (maybe sailing…). maby it’s easier to correct the course some times using a GPS (only every 1km maybe to save power…)
Important is the magnetic variation if you install the sensor in a car or something that affect the magnetics. btw this is consant and must be corrected…