SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By lifeofdave
#144899
Hi All.

If you have purchased the sparkfun "LSM303 Breakout Board - Tilt Compensated Compass" and, like I did, expect it to give you a compass heading out of the box simply by using the example code provided by sparkfun then this post might help you out...

Summary:
If you are finding the sparkfun provided example code gives you a very faulty compass heading then you need to use the pololu code linked below to calibrate the device.

https://github.com/pololu/LSM303

More info:

After receiving this device I tried various things to get a good compass heading; indoor testing, outdoor testing, 3.3v, 5v, arduino mega, arduino mini pro, moving it away from my wacom tablet, etc. The only thing that made a noticeable difference was keeping the compass at least a meter or two from my wacom tablet. Sitll, however, the compass heading was off.

I found that the North and South were close to 0º and 180º but that East and West were around -55º and +55º ,respectively, off where they should be. These results suggested a calibration issue rather than a sensor fault so I did some further research.

After reading the post linked below I followed Mee_n_Mac's 'sanity' checks, which involve pointing the x axis towards magnetic north,then E,S and W and recording the magnetometer X,Y and Z value for each.

viewtopic.php?f=14&t=28591&p=128200&hil ... ty#p128200

The results:
Code: Select all
                            X           Y           Z
X pointing North:           30          5        -490
X pointing East:           -220        240       -470
X pointing South:          -480        30        -430
X pointing West:           -250       -240       -450
From the above results you can see the Y axis is behaving well. When Y is pointing north it reads 240 and when pointing south it reads -240. However the X axis is not behaving as it should, reading 30 when pointing north and -480 pointing south. This offset explained why I was getting perfect heading on one axis but not the other.

Next I used the pololu calibration code to find the min and max values for each axis of the magnetometer. The values for this particular sensor were:
X: min = -733, max = +379
Y: min = -530, max = 518
Z: min = -533, max = 468

Once these values were entered into the pololu heading example sketch the LSM303DLH started giving accurate heading info.

To further understand the magnetometer readings I made rough rotations of the device around each axis and recorded the X,Y and Z values. I then made recorded the values whilst making a series of random rotations. Using grapher, included with os x, I plotted these results:

Image

The application notes pdf has a lot of info as to what this graph means (page 27 onwards), but as I undertand it the fact the points resemble a sphere rather than an ellipsoid suggests there is very little soft-iron interference.

On a final note if you are looking for buy the LSM303DLH then also look into the more recent LSM303DLM which has a greater accuracy.

The compass is now working properly so I'm happy! :)
By jremington
#144908
For much better calibration procedures, and the theory behind them, see http://sailboatinstruments.blogspot.com ... ation.html and links therein. See also the articles http://myahrs.wordpress.com/?order=asc and http://www.ckdevices.com/datasheets/MTD ... ration.pdf

The procedures work for accelerometers, providing the accelerometer is still while each data point is collected. This is tedious, however!
By Ipaulsen
#145113
Hi, I am very new to this, I have the LSM303DLH, with the Arduino Uno, I am using the LSM303 pololu library, trying to get heading readings from serial monitor 9600, with this set up I am not getting any values. Please help!

Setup
SCL to A5
SDA to A4
GND to GND
Vin to 3.3V
Code
Code: Select all
#include <Wire.h>
#include <LSM303DLH.h>

LSM303DLH compass;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  compass.enableDefault();
  
  // 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() {
  compass.read();
  int heading = compass.heading((LSM303DLH::vector){0,-1,0});
  Serial.println(heading);
  delay(100);
}