LSM303DLM Magnetometer Skewed Readings

I am currently working with a custom board that has the LSM303DLM module on it. I am successfully reading correct data via the I2C interface and calculating a heading based on the process of this source:
I am working in C (not C++) on a dsPIC so I had to make a few minor changes but nothing functional.

The heading I am getting seems to be very weighted towards the south pole. At magnetic north I get a heading of 0, and south a heading of 180. But at what should be about 135 degrees I get a reading of 90 degrees and at about 225 degrees I get a reading of 270.

In other words the rotation of readings is very slow around the north pole and fast around the south pole. Most of the calibrations I have found have just been a scaling of the data which does not fix this problem. And I have tried to follow the process of this source: … e_id=0J434
But I had trouble following the math without example data, and my setup is not ideal for getting reliable data at known orientations.

What I am looking for is a step by step set of equations to correct my readings (not just scale them). Also, most of the solutions I have seen reference MATLAB to get and plot the data but I do not have access to this either.

If it helps, here are the maximum and minimum values of each of the readings for my device (not scaled):
x min: -540
x max: 320
y min: -710
y max: 163
z min: -426
z max: 419

Thanks for your help.

The magnetometer is nearly useless without proper calibration and from the data that you provide, yours appears to be performing quite a bit worse that the two uncalibrated examples that I’ve used.

See the link below for a discussion of state of the art procedures, including free downloadable, self-contained programs for calibrating the magnetometer. Before using either program, you will have to collect machine-readable magnetometer measurements for as many different orientations as possible (hundreds if not thousands). The programs work for accelerometers as well, providing the device is perfectly still during each measurement. … ation.html

Thanks a lot, this was a huge help. I have one question about the application though. It asks for the norm to to the local Earth’s magnetic field and gives a link where you can find that data.
Here: … alcIGRFWMM

But that page does not call the data the “norm to the local Earth’s magnetic field”. Which piece of data is this? I am using the total field_value/1000 but I am not sure if this is correct.

The “norm of the local earth’s magnetic field” is just a scaling constant. You can use 1.0, unless you want the measured value to conform to some particular unit of measurement.