Setup guide, but how do I get steady compass readings form a 9DOF

I have a 9DOF based with a ITG3200/ITG320?5 ADXL345 HMC5883L chips. The item is available at

Important is to connect the sensor to 3.3V instead of the 5V. My board has a VCC but I havent tried to connect it to 5V because I have no documentation of the sensor. It looks like it have a 3.3V regulator but it is not tested (yet)
Attach sensor to Ground.
The connection to I2C is simple. If the board dont show movement of the sensor, its possible to change the SCL/SDA. I do not have resistors to SCL/SDA. There is guides where pullup resistors is used. For me it worked without. (=KISS)

My first atemt to get the sensor working is to implement theFreeIMU.

  1. Download the FreeIMU library

The Library needs to be changed. The FreeIMU board have other chips. To change the FreeIMU the library have to be changed to an “older” FreeIMU board with
ITG3200/ITG320?5 ADXL345 HMC5883L chips.

// Uncomment the appropriated version of FreeIMU you are using
//#define FREEIMU_v01
//#define FREEIMU_v02
#define FREEIMU_v03       // <=========================================================================================          
//#define FREEIMU_v035
//#define FREEIMU_v035_MS
//#define FREEIMU_v035_BMP
//#define FREEIMU_v04

// 3rd party boards. Please consider donating or buying a FreeIMU board to support this library development.
//#define SEN_10121 //IMU Digital Combo Board - 6 Degrees of Freedom ITG3200/ADXL345 SEN-10121
//#define SEN_10736 //9 Degrees of Freedom - Razor IMU SEN-10736
//#define SEN_10724 //9 Degrees of Freedom - Sensor Stick SEN-10724
#define SEN_10183 //9 Degrees of Freedom - Sensor Stick  SEN-10183 <======================================
//#define ARDUIMU_v3 //  DIYDrones ArduIMU+ V3 or
//#define GEN_MPU6050 // Generic MPU6050 breakout board. Compatible with GY-521, SEN-11028 and other MPU6050 wich have the MPU6050 AD0 pin connected to GND.

// *** No configuration needed below this line ***
  1. Start the FreeIMU example: FreeIMU_quaternion
    In the serial monitor it gives alot of HEX figures that contains floats. This output is NOT for human eyes. Its for a visualization GUI made in processing.

  2. Download processing:
    The processing platform looks like Arduino IDE.

  3. Now we need the visualization GUI for processing. The processing if found in the download of FreeIMU under the processing directory.
    Copy the processing directory to a easyer place like c:\processing.

  4. Check the COM port used for the Arduino IDE. In my case it was COM28. Open the processing sketch FreeIMU_cube.pde.
    Search for the code where processing is assigning the Serial port to lissening to. Chang it to our Arduino IDE Com port.

import processing.serial.*;
import processing.opengl.*;

Serial myPort;  // Create object from Serial class

final String serialPort = "COM28"; // replace this with your serial port. On windows you will need something like "COM28". <==============================

float [] q = new float [4];
float [] hq = null;
  1. Run the Arduino IDE sketch example for FreeIMU_quaternion WITHOUT starting the Serial monitor.

  2. Run the Processing sketch to see how the board is moving.

  3. Change the Processing to the sketch FreeIMU_yaw_pitch_roll.pde to get another view.

This is a guide to be sure that the board is working and that all libraries are in place.

Now to my problem:

The visualization GUI shows that the accelometers and the gyros have a drift over time. How do I get a steady direction from the yaw and combine it to the compass.

When I test the compass i get a heading that is very unstable. (testexamle for HMC5883L). The testexample is not tiltcompensated but even if its not moved it gives ±10 degress readings.

The purpose is to guide a robot with PID in a straight line. PID can adjust bad readings, but to start with good readings before the PID makes it alot easyer.

Any suggestion to get a steady reading from the compass with compensation from accelometers and Gyros?

In brief - to eliminate drift from the gyro you need a reference that's drift-free in the long-term - this is combined with the gyro in such a way that the gyro provides the high frequency information and the drift-free reference provides the low-frequency information (here high frequency means perhaps 0.1Hz and above!)

An alternatively way of looking at it is to adjust the gyro reading from the reference after passing the reference through a low-pass-filter - thus for tilt you use the low-pass-filtered accelerometer readings (thus removing any short-term vibration or movement, but retaining the acceleration due to gravity).

For yaw the compass provides the reference (or alternatively with 3-axis compass and 3-axis accelerometer you can combine the two to give a reference frame, then combine with the gyro).

The compass itself will be noisy - unless you low-pass filter its output on a timescale of several seconds it will appear to be very twitchy (because these are tiny hall devices they have a lot of noise - expensive magnetometers use other physical principles to get better results than a MEMS compass)

MEMS accelerometers too are fairly noisy.

So I'd suggest looking up phrases "Kalman filter", "drift compensation", "9DoF" and suchlike for more information - there are various libraries around, perhaps someone else has a good review of them?

the DCM already compensate for the error. Take a look at the freeImu's code, you'll see it use a PI controller. Just play with this value untile you find the right ones.