LSM303DLM 3D Compass Heading on Arduino


I have recently uploaded the Heading example and tested the heading. Instead of the heading being the X axis, it is the reverse of the Y axis. EG, if I have the Y axis pointing south, it gives me 0. I have the z axis pointing to the ground.
I have tested by changing the Roll and Pitch and also did the calibrate first and adjusted values, however, still looks like reverse of Y. I am in the southern hemisphere if that has any bearing (if you’ll pardon the pun).

Anyone have any ideas?


Aside from the obvious joke about being in the wrong hemisphere, are you sure that you have the LSM303DLM chip, not the LSM303DHLC and are using the appropriate software? Although the chips are otherwise very similar, the locations of the y and z magnetometer registers are swapped. I have both and the only way to tell them apart is to look at the pictures of the boards and compare the (meaningless to me) chip markings.

The packaging says #Pololu #1273

What I did find, which was not what I expected, was when I did a serial read on all axises that the maximum magnetic values were when the axis was pointed through the Earth to magnetic north and not in the horizontal plane. Is that what I should be expecting to read?

OK, the compass is as you state. Are you using the example code intended for the LSM303DLM, and not the code for the LSM303DLHC?

The earth’s magnetic field vector points into or out of the ground everywhere, except close to the equator where it is nearly horizontal. Think of the field due to a “small” bar magnet at the earth’s center.

Cheers, Jim

The code is this

#include <Wire.h>
#include <LSM303.h>

LSM303 compass;

void setup() {
  // Calibration values. Use the Calibrate example program to get the values for
  // your compass.
  compass.m_min.x = -520; compass.m_min.y = -570; compass.m_min.z = -770;
  compass.m_max.x = +540; compass.m_max.y = +500; compass.m_max.z = 180;

void loop() {;
  int heading = compass.heading((LSM303::vector){0,-1,0});

I downloaded it from

What is interesting is I just looked at the comments in the source file and it says

// Returns the number of degrees from the -Y axis that it
// is pointing.
int LSM303::heading(void)
  return heading((vector){0,-1,0});

Hi, angelo_f.

Like the comment says, the version of the heading() function that takes no arguments does return the direction the negative Y axis of the board is pointing. The idea is that you would use the board oriented the way it’s shown in our pictures, with the -Y axis pointing away from you:

If you want to use some other axis as a reference, you can simply call heading() with a vector argument. For example, to use the X axis, just use heading((vector){1,0,0})

- Kevin

OK, great. That all makes sense. I thought I was losing my mind yesterday but it all makes sense now.

Thanks for all the follow up.