Go Down

Topic: HMC5843 lib update (Read 5720 times) previous topic - next topic


Ok after getting this little HMC stamp, and after adding a cap otherwise it didn't work properly, i modified/extended the HMC lib to get it easy going.
The output values of the HMC need to be scaled, as the documentation describes, the new calibrate function does just that. The output values are scaled after calibration but still just a vector so for yaw pitch and stuff you need some calculations.

Lib: http://www.filejumbo.com/Download/A0733DDFF58B4FCE


Is your library just written for arduino mega boards since you include twi.h in HMC.h file? I am new to programming so I might be wrong! If yes how do I adopt the code to an arduino uno board or are no modifications needed?

Thanks in advance!

I've been able to use the above library correctly also on my Arduino Duemilanove.. so an Arduino Mega is not needed.

Unfortunately tough I'm experiencing some problems.. the reading seems quite random.. Don't know how to check them..

How do I put the sensor for correct calibration?

Looking at the calibration routine in the library it seems that there isn't needed to put the device in a particular position.. it seems it does the calibrations without need to move it.

I plotted the X and Y while rotating the device in 360 deg.. this is the output: http://forum.sparkfun.com/download/file.php?id=693&t=1

Not bad, I would say..


I just bought that little monster.
Is your plot taken before or after calibration?


Nov 23, 2010, 11:52 pm Last Edit: Nov 23, 2010, 11:54 pm by fax8 Reason: 1
Hi newbee! The readings which created that plot have been created using the above library. If you look at the code in the library you'll see that calibration is done during setup() ..

So, yeah, those values are from a calibrated sensor with the library above. On sparkfun forum there is a related discussion were more complex approaches to calibration are discussed.

I still don't know if what they do to calibrate is actually needed as as you can see, using the library above, the readings looks quite accurate (in my case).

I just asked for clarification on the same forum page, let's see if I get some help: http://forum.sparkfun.com/viewtopic.php?p=114124#p114124

What are you planning to do with the sensor? It would be cool to share efforts in using these chips..

I'm into HCI experimentation, tangible interfaces.. see my website for some early developments http://www.varesano.net/


Ciao Fabio,

the readings don't look all that good I think: They should make up a circle, not an ellipse around the origin.
If you have one diameter larger than the other, it is an idication that the system should be calibrated. As the ellipse doesn't look tilted, a calibration should not be difficult.

Read more about calibration in a publ. by ST Microelectronics:
Application note
Using LSM303DLH for a tilt compensated electronic compass

I am trying to build an electronic compass. So far I have programmed a three axis accelerometer to output roll and pitch and this morning I got the HMC5843 to run, with the wire library.

I am not sure, how good the computated heading will be if the compass is moved, and therefore one might need to calculate motion from the accel for compensation ( I found a reference on that) or integrate a gyro.



Sure, I know that they should made a circle not an ellipse.. but I'm wondering how much error this miscalibration will lead to.. I guess that it would be around 4/5 degrees of error.. so I wonder if it's really worth implementing a sophisticated calibration routine.. for my needs I mean ???

The document you pointed me to looks quite good written and I will surely have a look at it. This is the direct link if anyone else is interested: http://www.st.com/stonline/products/literature/an/17353.pdf

You should also read http://forum.sparkfun.com/viewtopic.php?f=14&t=18510 .. there are quite a good number of references there.

Also, worth noting are everything here: http://code.google.com/p/imumargalgorithm30042010sohm/downloads/list

You find a paper on the topic and some implementations you might find useful.

I just created a 3d version of the 2d graph above. It's all described at http://www.varesano.net/blog/fabio/first-steps-hmc5843-arduino-verify-accuracy-its-results and you'll also find all the sources I used to create those graphs.

You should find them useful if you need something like that.


Hello Fabio,

I thought about calibrating the magnetometer, and I think it is easy:
From your plot you already have all data necessary, but you can easily read the necessary calibration data (which are essentially the minima and maxima of the X and Y readings of the single axis sensors)  during a calibration routine and save them to program memory, as follows (no guarantee for correctness):
you measure X and Y readings during a slow circle you perform with the compass, and save Xmin, Xmax, Ymin, Ymax. Then you calculate the offset from the centre to be:

Xoff = (|Xmax|+|Xmin|) / 2  
Yoff = (|Ymax|+|Ymin|) / 2  
Xgaincorrfactor = (|Xmax|+|Ymax|) / 2 * Xmax
Ygaincorrfactor = (|Xmax|+|Ymax|) / 2 * Ymax

which gives you the total correction for X:

Xcorrected = Xraw * Xgaincorrfactor - Xoff

analog for Y correction.

You could do that during setup of the compass.
It would be interesting to know if the correction depends on the compass system or if it changes if you do the calibration in different environments like outdoor, too.

Let me know how it works!

Andreas (newbee)


Nov 26, 2010, 10:49 am Last Edit: Nov 26, 2010, 10:49 am by segler Reason: 1
Sorry I forgot to explain :

Xoffset and Y offset center the ellipse to the centre of the ccordinate system, and Xgaincorrfactor and Ygaincorrfactor correct the ellipsoid shape to become a circle.


I'll think about your method.

In the paper you linked (AN3192) there's a different method (see appendix C) which involves using least square method to determine the best offset and gains possible.

There's also a Mathlab implementatio of a similar approach by Seb Madgwick here: http://forum.sparkfun.com/viewtopic.php?p=108085#p108085

I just updated VIKI's library to use Arduino's Wire library to use the I2C bus. You find my code on my blog post An HMC5843 magnetometer library for Arduino based on Wire.

I still did not investigated on the calibrating issue. Doing that soon.


Hi everyone,

it took me some time to figure out how to exactly calibrate this chip. From what I understand one needs to calibrate it to the minima and maxima in the three axes. This implies to hold it in every axis parallel to the earth's magnetic field vector which in inclined in our area about 60° from the horizontal. If one sticks to the horizontal and vertical plane one gets reults that are smaller and thus a wrong sensitivity, or, rather, a sensitivity that is OK only for the exact calibration planes.
If one would like to use the chip in a mobile application this approach in my view does not yield the correct sensitivity.
David Schultz published a code that allows the calculation of sensitivities and offsets from 6 values. In the code he suggests to take these values at positions that are exactly horizontal and vertical (at the minima and maxima of the accelerometer readings).

My view is to collect the readings of many random positions in space and filter them for the minimal and maximal value in each axis and record only these values.  This way one can will end up with the true minima and maxima of the ellipsoid to describe, and the calibration factors thus obtained are not bad.

Any remaining error is likely due to having missed the precise position of minima and maxima during calibration.

I tried to document these findings here:  http://home.arcor.de/dreckes



Sorry newbee, just to be clear, in your previous equation:

 Xgaincorrfactor = (|Xmax|+|Ymax|) / 2 * Xmax

used to compute x gain factor, do you mean:

 (1) Xgaincorrfactor = (|Xmax|+|Ymax|) / (2 * Xmax)


 (2) Xgaincorrfactor = ((|Xmax|+|Ymax|) / 2) * Xmax

Pleas, could you clarify to me this point?

Sorry for this silly question.

Go Up