Arduino 2560 ADK with a 9DOF sensor board (MPU 6050)

In order to monitor the movement of my robot I looked for an IMU sensor board. At the end I bought a 9 DOF transducer offered by It is similar to the “original” Flydurino  board (Freeimu 0.4.3) but does not provide an altimeter. Its interfaces are limited too and do not cover an interrupt channel or a SPI interface. But it is much cheaper 🙂

Jeff Rowberg wrote a powerful library to address I2C devices that integrates the MPU 6050 allready. But I missed an example code that shows how to use all sensors (especially the HMC5883l) on this board in a common application. It is connected to via sub I2C on the IMU. For this purpose I extended the code proposed by @muzhig on  i2cdevlib. Additional useful informations can be found on Arduino MPU 6050.

2013-09-05 09.41.43

Arduino 2560 ADK connected to a IMU sensor board via I2C


Comments, improvements or hints are welcome!

// ---------------------------------------------------------------------------
// Receive all measurements from an 9 DOF sensor board. 
// Sebastian Zug
// Otto-von-Guericke University, Magdeburg, Germany
// 09/2013
// ---------------------------------------------------------------------------
// Structure:
//                                           Sub I2C
//                                        ______^ ______
//                                       |              |
// ----------
//  Arduino  |               ----------------          -------------
//  2560     |- 3.3 V ------ | MPU 6050     |          |  HMC5883  |
//           |- GND ---------| Acceleration,|---SDA ---|  Compass  |
//           |- SDA ---------| Gyro, Temp   |---SCL ---|           |
//           |- SCL ---------|              |          |           |
//           |               ----------------          -------------
//                       |___________________ _______________________|
//                                           V
//                                   Integrated IMU sensor 
// Pull-up resistors are integrated in the sensor board.
// IMPORTANT: When I connect the sensor board to a 5V power supply, it was 
//            not possible to realize a I2C connection in this case. I made
//            some experiments with additional pull-upps on the I2C but 
//            without any results.
// ---------------------------------------------------------------------------
// It exists a very good library for I2C communication based on Arduino "Wire"
// provided by Jeff Rowberg. It integrates specific controllers as MPU 6050 
// and HMC 5883. Take a view on
// The example was implement with i2cdevlib Version and extends the existing 
// MPU_6050_raw // example. It uses the code proposed by @muzhig on i2cdevlib 
// ---------------------------------------------------------------------------

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include "HMC5883L.h"

// The default I2C address is defined 
// MPU 6050 - 0x68 - MPU6050_DEFAULT_ADDRESS
// HMC5883L - 0x1E - HMC5883L_DEFAULT_ADDRESS    
MPU6050 mpu6050;
HMC5883L hmc5883l;

int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t mx, my, mz;
double temp;

#define LED_PIN 13
bool blinkState = false;

// this method is just used to collect different setSlave operations
void setSlaveControl(uint8_t slaveID){
    mpu6050.setSlaveEnabled(slaveID, true);
    mpu6050.setSlaveWordByteSwap(slaveID, false);
    mpu6050.setSlaveWriteMode(slaveID, false);
    mpu6050.setSlaveWordGroupOffset(slaveID, false);
    mpu6050.setSlaveDataLength(slaveID, 2);

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    // initialize serial communication

    Serial.println("Initializing I2C devices...");

    if (mpu6050.testConnection()){
      Serial.println("MPU6050 connection successful");
    else {
      Serial.println("MPU6050 connection failed");

    // configuration of the compass module
    // activate the I2C bypass to directly access the Sub I2C 

    if (hmc5883l.testConnection()) {
        Serial.println("HMC5883l connection successful");

        // unfourtunally 
        // hmc5883l.setMode(HMC5883L_MODE_CONTINUOUS); 
        // does not work correctly. I used the following command to 
        // "manually" switch on continouse measurements

        // the HMC5883l is configured now, we switch back to the MPU 6050

        // X axis word
        mpu6050.setSlaveAddress(0, HMC5883L_DEFAULT_ADDRESS | 0x80); 
        mpu6050.setSlaveRegister(0, HMC5883L_RA_DATAX_H);

        // Y axis word
        mpu6050.setSlaveAddress(1, HMC5883L_DEFAULT_ADDRESS | 0x80);
        mpu6050.setSlaveRegister(1, HMC5883L_RA_DATAY_H);

        // Z axis word
        mpu6050.setSlaveAddress(2, HMC5883L_DEFAULT_ADDRESS | 0x80);
        mpu6050.setSlaveRegister(2, HMC5883L_RA_DATAZ_H);

    } else {
        Serial.println("HMC5883l connection failed");

    // activate temperature MPU 6050 sensor

    // configure Arduino LED for
    pinMode(LED_PIN, OUTPUT);

void loop() {

    // read raw heading measurements from device

   // To calculate heading in degrees. 0 degree indicates North
    float heading = atan2(my, mx);
    if(heading < 0)
      heading += 2 * M_PI;

   // read raw accel/gyro measurements from device
   mpu6050.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

   // see MPU 6050 datasheet page 31 of 47
   temp=((double) mpu6050.getTemperature()) /340.0 + 36.53;

   Serial.print(ax); Serial.print("\t");
   Serial.print(ay); Serial.print("\t");
   Serial.print(az); Serial.print("|\t");
   Serial.print(gx); Serial.print("\t");
   Serial.print(gy); Serial.print("\t");
   Serial.print(gz); Serial.print("|\t");
   Serial.print(heading * 180/M_PI); Serial.print("|\t");

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);

Readers Comments (9)

  1. 19062 688856Several thanks for the wonderful post C I

  2. Hi! Thanks for the post! But I have a little big problem.
    I don’t have any experience about arduino and sensors…so, I don’t know if the
    problem is about missed libraries.
    The error is as follows:
    “class HMC5883L has no member named ‘testConnection’
    “class HMC5883L has no member named ‘initialize’
    HMC5883L_DEFAULT_ADDRESS was not declared in this scope
    HMC5883L_RA_MODE was not declared in this scope
    HMC5883L_MODE_CONTINUOUS was not declared in this scope
    HMC5883L_RA_DATAX_H was not declared in this scope
    HMC5883L_RA_DATAY_H was not declared in this scope
    HMC5883L_RA_DATAZ_H was not declared in this scope.
    What could I do? Thank you very much in advance!

  3. hi thanks for your example, but why the heading cant read 0?
    i use my real compass and i give direction on my sensor to the north, and the heading just about 130-180, cant read 0?

    why, im quite newbie, please answer my question, *sorry for bad english

    • Hi desraino,

      please post a short code example and describe your ideas more in detail.

      See you


  4. could i get your email address?
    theres many things i have to ask.
    and i dont know how to attached the screen shot from my problem.
    thanks for reply sebastian.

  5. 3jeh87TnuuD3

  6. Could anyone please provide a working HMC5883L.h?

    I can’t get it to work.

  7. Everyone loves what you guys are usuallpy up too.
    This type of clever work and reporting! Keep up the teerrific
    works guys I’ve included you guys to my blogroll.


Leave a comment

Your email address will not be published.