MPU6050 Will Not Wake Up!

Hi All,

I am using the MPU6050 (GY-521) IMU chip to output it's raw analog values. I am using the basic example sketch on http://playground.arduino.cc/Main/MPU-6050 to read the raw values. Now the sensor starts in sleep mode by default and should be taken out of sleep mode by this line of code: "MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0);"

We are using the Arduino DUE board and our pinouts look like this: VCC => 5V GND =>GND SCL => A5 SDA => A4 INT => D13 (pin 0x68 on the DUE)

We have tried connecting SCL and SDA to the SCL and SDA pins of the DUE board (D21 & D20) and got the same results (not that I think that matters, it's just something we tried).

The code we are running is on the aforementioned link page, we have not changed it, to be specific: ( http://playground.arduino.cc/Main/MPU-6050?action=sourceblock&num=1 )

Our output looks like this:

MPU-6050
Read accel, temp and gyro, error = 1
accel x,y,z: 6170, 16384, 1197
temperature: 36.529 degrees Celsius
gyro x,y,z : 1, 0, 1, 

MPU-6050
Read accel, temp and gyro, error = 1
accel x,y,z: 6680, 64, -21244
temperature: 42.529 degrees Celsius
gyro x,y,z : 256, 0, 256, 

MPU-6050
Read accel, temp and gyro, error = 1
accel x,y,z: 6170, 16384, 1197
temperature: 36.529 degrees Celsius
gyro x,y,z : 1, 0, 1, 

MPU-6050
Read accel, temp and gyro, error = 1
accel x,y,z: 6680, 64, -21244
temperature: 42.529 degrees Celsius
gyro x,y,z : 256, 0, 256,

It continuously outputs the same two bunches of data no matter which direction we move the sensor. We have also tried to let it warm up for 10-20 min with no change in any of the outputs.

Any help to interpret why our sensor will not work would be greatly appreciated. We have been trying to troubleshoot this problem for a few weeks now with no real help from previous posts about the sleep mode on the MPU6050.

Run this sketch, open serial monitor and see if your IMU is detected by arduino. You should see its I2C address.

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

The output you appear to see, is just random bits, because you are not actually communicating with the device at all.

The Uno and similar devices use a4/a5 for the I2C connections. I don't think the Due does, you need to check that instead of tryng random things, I think the due has similar pin connections to the Mega. Don't take my word for it. look it up.

You need to run the I2c_scanner sketch to verify that the I2C is actually communicating with the device. If you don't get a response, check the wirng, check the voltage, review the pull-up resistor issues.

The Due is a 3.3V device, you need to consider that . Different sensor modules will deal with that issue in different ways.

You need to get the I2C to work, BEFORE you worry about putting the device into or out of sleep mode.

If you want another chek that the I2C is working and the device is responding, try to read the device register with the "who am i" value, and check you get the correct value. This will confirm that the device's i2c is working and also the hardware to access it's data registers is working. and also verifies that your I2C implementation on your arduino is working.

Thank you for both of your thoughtful replies, you were both correct that my Arduino is not connecting with my device. I have the correct pins hooked up now per the pinouts of DUE ( http://www.robgray.com/temp/Due-pinout-WEB.png ): 5V => VCC GND => GND D20(SDA) => SDA D21(SCL) => SCL D13(0x68) => INT

Yet I still cannot get the Arduino to find the device, the I2C scanner can't find it.

The device works fine when I use the DMP output of the chip (hooked up in the same fashion but using different code: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 ), but I cannot get the raw analog values that I need because of this problem.

I am going to try sifting through Rowberg's code for the DMP to see what libraries he is using, I am starting to think using only Wire.h for the DUE board is my problem. Any thoughts you might have will be greatly appreciated.

EDIT: I was right, the Arduino DUE will not recognize the sensor unless I include the other libraries 'MPU6050.h' and 'I2Cdev.h' from Rowberg's library. I can now correctly get the raw values and calibrate the sensor. Thank you for your help in making me realize this simple solution.

P.S. - The Arduino DUE board has only given me nothing but problems on the three projects for which I have used it, in the future I would recommend staying away from it if you are not very experienced with Arduino or micro-controllers in general.

it seems very strange that the I2C would work for one sketch and not for the others. Are you using the same physical wiring for both sketches ?

The i2c_scanner should detect any device connected to your arduino, even if you haven't included any libraries or code for the device in your sketch.

The values are not really "analog values", and you will confuse yourself and others if you call them that.

You can access this device to get the data, without including those libraries and all the stuff in them. You only need a working implementation of I2C, and you need to know which register to set to turn it on, and which six registers to read the data from.

I was right, the Arduino DUE will not recognize the sensor unless I include the other libraries 'MPU6050.h' and 'I2Cdev.h' from Rowberg's library.

It may appear that way, but actually this statement is wrong.

Yes I used the exact wiring as I mentioned above, I believe it's definitely a problem that is unique to the DUE board because of its 32-bit core, giving it different timers and interrupts than Arduino's other 16-bit core models. And yes the neither the I2C scanner or the basic MPU6050 raw value sketch would work on the DUE unless I have the same libraries called as I mentioned in my edit of the last post.

Hi, I am also using the Arduino Due for a project with the same MPU-6050. I have the exact same error to my serial output as "mcsorleyt". I have tried to include the other libraries 'MPU6050.h' and 'I2Cdev.h' as said above, however, I am still getting the junk output. I have added libraries to arduino projects in the past, i.e. you create a folder inside the libraries directory named after the .h file that is to go inside. Any help or recommendations about exactly which libraries to add and where would be useful. Thanks for your time.

I have found how to connect the Arduino Due to the MPU-6050. After many hours of trouble shooting, I found a solution and I am determined to make this as easy as possible for others. To make this very clear for those who come after me, follow this simple procedure to get raw data. I also semi convert raw data to useable data, see code below.

1.) First, connect the pins while the board isn’t powered. I haven’t read anyone mentioning this step yet. I found that if the ADO pin is not set to GND before the mpu-6050 is powered, it will fail to be recognized by the arduino Due and you will only recieve zeros for the raw data. By Setting the ADO pin to GND, the address will be 0x68. So, to be clear, the pins should be as follows,

  • VCC =>+5V.
  • GND=>GND.
  • SCL=>D21.
  • SDA=>D20.
  • ADO=>GND.
  • INT=>D2 or D13, I’m not sure here, but I’ve managed to use D2.

2.) Once you have the pins wired, you can power the mpu-6050.

3.)Here is my copy of the MPU6050_raw.ino

// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class
// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
//      2013-05-08 - added multiple output formats
//                 - added seamless Fastwire support
//      2011-10-07 - initial release

/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/

// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include <I2Cdev.h>
#include <MPU6050.h>
#include "MATH.h"
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high

int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t temperature;


// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO


#define LED_PIN 13
bool blinkState = false;

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
    // it's really up to you depending on your project)
    Serial.begin(57600);//38400);

    // initialize device
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();
    //accelgyro.setSleepEnabled(false);
    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
    
    // use the code below to change accel/gyro offset values
    /*
    Serial.println("Updating internal sensor offsets...");
    // -76	-2359	1688	0	0	0
    Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
    Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
    Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
    Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
    Serial.print("\n");
    accelgyro.setXGyroOffset(220);
    accelgyro.setYGyroOffset(76);
    accelgyro.setZGyroOffset(-85);
    Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76
    Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359
    Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688
    Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0
    Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0
    Serial.print("\n");
    */

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

void loop() {
    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    temperature = accelgyro.getTemperature();
    // these methods (and a few others) are also available
    //accelgyro.getAcceleration(&ax, &ay, &az);
    //accelgyro.getRotation(&gx, &gy, &gz);

    #ifdef OUTPUT_READABLE_ACCELGYRO
        // display tab-separated accel/gyro x/y/z values
        Serial.print("a/g:\t");
        //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");
          convert_angle(ax);
          convert_angle(ay);
          convert_angle(az);
         Serial.println((temperature+ 12412.0) / 340.0);
         delay(100);
    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
        Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
        Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif

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



void convert_angle(int16_t tmp_arg)
{
  float t = (float) tmp_arg;
//TO-DO
  //The 17000 values is an approx and produces NAN, it should be replace to calc
// the correct rot angle, maybe gx-y-x should be used here instead of ax-y-z...
  t=acosf(t/17000)*57.29;
  Serial.print(t);Serial.print("\t");
}

4.) I’ve added a few functions to convert to realistic values. I haven’t finished the angle conversion but it’s trivial at this point. Notice that this program includes the libraries ‘MPU6050.h’ and ‘I2Cdev.h’. To include these libraries, download them from GitHub - jrowberg/i2cdevlib: I2C device library collection for AVR/Arduino or other C++-based MCUs.

I will be very clear, once this is downloaded, copy the folders called I2Cdev and MPU6050, these folders will be located specifically under the Arduino section of the directory for the download,i.e. i2cdevlib-master/Arduino/file_is_here. Just copy these 2 folders to the Arduino directory, such as Documents/Arduino/Libraries. Restart Arduino IDE and these libraries will be included. Now, you can open the existing file called MPU6050_raw.ino, it will be located under the example section which is found in the MPU6050 folder. Or you could create a new file and paste the code above in and compile to the arduino. Either way, at this point, you should be good.

I wish when people found solutions, they would share them instead of posting, “Oh yeah that was my problem”, or the classic “fixed it”. Come on people, full solutions help everybody.