Obtaining Roll and Pitch from a Tilt Compensated Compass

I have built a Tilt Compensated Compass using the LSM303 chip and the Adafruit LSM303 and Unified Sensor libraries and the sample script that displays the heading on the serial monitor.


#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);

void setup(void)
Serial.println(“Magnetometer Test”); Serial.println("");

/* Initialise the sensor /
There was a problem detecting the LSM303 … check your connections */
Serial.println(“Ooops, no LSM303 detected … Check your wiring!”);

void loop(void)
/* Get a new sensor event */
sensors_event_t event;

float Pi = 3.14159;

// Calculate the angle of the vector y,x
float heading = (atan2(event.magnetic.y,event.magnetic.x) * 180) / Pi;

// Normalize to 0-360
if (heading < 0)
heading = 360 + heading;
Serial.print("Compass Heading: ");

I would like to be able to obtain the pitch (along the X axis) and Roll (along the y axis) and display it in degrees. Moreover I would like it to display it so that when the sensor is perfectly level, the display will indicate 0 degrees. I would also like it to display a change in orientation to display + for upward tilt and - for downward tilt and limit it to 90 degrees in either direction (when you get to +90 degrees and then go slightly past +90 degrees it would say -89 degrees.)

This has probably been done before, but after a couple of hours of searching I have come up empty handed.

You get roll and pitch from the accelerometer.

Google "roll pitch accelerometer" for lots of hits: Here are a couple: https://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf https://www.dfrobot.com/wiki/index.php/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing