LSM303D making a Compass to give zero to north


I am trying to make my LSM303D a Compass. I’m not using specifically made PCB that my company ordered. I have found some tips online, but it uses two axis and it changes when I pitched the PCB. this is the code is use now.

    ACC_X_LSB = 0x28; // x 
    ACC_X_MSB = 0x29;
    ACC_Y_LSB = 0x2A; // y
    ACC_Y_MSB = 0x2B;
    ACC_Z_LSB = 0x2C; // z
    ACC_Z_MSB = 0x2D;    

    MAG_X_LSB = 0x08; // x
    MAG_X_MSB = 0x09;
    MAG_Y_LSB = 0x0A; // y
    MAG_Y_MSB = 0x0B;
    MAG_Z_LSB = 0x0C; // z
    MAG_Z_MSB = 0x0D;
int GetValue(int MSB, int LSB)
    int combined = 256 * MSB + LSB;
    return combined;

void lsm303d_update_values() {

    x_mag = GetValue(lsm303d_read_register(MAG_X_MSB), lsm303d_read_register(MAG_X_LSB));
    y_mag = GetValue(lsm303d_read_register(MAG_Y_MSB), lsm303d_read_register(MAG_Y_LSB));
    z_mag = GetValue(lsm303d_read_register(MAG_Z_MSB), lsm303d_read_register(MAG_Z_LSB));
    pose_float_2axis = (atan2((float)y_mag,(float)x_mag)*180)/3.14159;


It sounds like you are using our LSM303D carrier and trying to make a tilt-compensated compass. We have an Arduino library for that board, which has example code for getting tilt-compensated heading. (A link to the GitHub page for that library can be found under the Resources tab of that sensor’s product page.)

You might find that library especially useful if you are reading your LSM303D from an Arduino. If you are not, you could probably use it as a guideline for writing your own code.


To make a useful compass, you will need to individually calibrate the magnetometer, and of course, correct for the magnetic declination in your area. The best procedure is summarized and applied in this post: Correcting the Balboa magnetometer

1 Like