Could not find a valid MPU6050 sensor, check wiring!

Hello,

I have arduino nano + MPU6050 (GY-521) - works fine with other libraries for this sensor. But I would like to find why I get this error with this library.

Initialize MPU6050
Could not find a valid MPU6050 sensor, check wiring!

I followed this tutorial.
I tried to swap SCL and SDA wires - not helped, connected back how described in tutorial.
I searched information related to wires/pins in MPU6050.h and MPU6050.cpp - nothing found.
The initialisation of mpu object fails. How can I get more details in console to identify the root of the problem?

Nano, or Nano Every?

Nano

Hi,
At a pinch, have you got 4k7 pullups on the SDA and SCL lines?

Tom... :slight_smile:

I don't have any resistors on SDA, SCL lines, as this is not required in the tutorial.
I opened MPU6050.cpp and I see for the communication is used the same Wire.h that works in basic hello world test example (but another library).

#include <Wire.h>
#include <math.h>

#include <MPU6050.h>

bool MPU6050::begin(mpu6050_dps_t scale, mpu6050_range_t range, int mpua)
{
    // Set Address
    mpuAddress = mpua;

    Wire.begin();

If wire.h is OK and arduino nano can talk to mpu6050, then the problem is only in this library mentioned above. I tried to look in MPU6050.h the registers addresses and compared them to the rigister addresses from mpu6050 datasheet and they are correct.
MPU address is correct - 0x68 because I don't use AD0 pin.

I MPU6050.cpp, begin function contains 3 parameters, mpu6050_dps_t scale, mpu6050_range_t range, int mpua, but in the arduino sketch, I see only 2 parameters in begin: mpu6050_dps_t scale, mpu6050_range_t range.
Should I add the address in the sketch begin too?

cpp

bool MPU6050::begin(mpu6050_dps_t scale, mpu6050_range_t range, int mpua)

sketch

while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))

Not helped declaring the address in begin. It's predeclared in mpu6050.h
The problem in somewhere else...

run an I2C scan to see if anything is detected

Here the results:

Arduino MultiSpeed I2C Scanner - 0.1.11

1 devices found in 4375 milliseconds.

TIME DEC HEX 50 100 150 200 250 300 350 400 [KHz]

30525 104 0x68 V V V V V V V V

0x68 is a correct address for a MPU6050 (The device has two valid addresses, 0x68 or 0x69, depending on the status of the AD0 pin) so that's good news - it seems to be visible

(on a Nano SDA -> A4; SCL -> A5 should be the correct wiring)

you would not be the first one with crappy build quality on such devices...

Hi,
Have you at least tried the 4K7 pullup resistors?

Tom... :slight_smile:

J-M-L:
0x68 is a correct address for a MPU6050 (The device has two valid addresses, 0x68 or 0x69, depending on the status of the AD0 pin) so that's good news - it seems to be visible

(on a Nano SDA -> A4; SCL -> A5 should be the correct wiring)

you would not be the first one with crappy build quality on such devices...

I confirm, SDA -> A4; SCL -> A5

This is not a case for crappy build because the sensor is detected by I2Cscanner and other libraryes work fine with this sensor. It's not a hardware problem, I think, but a software problem. I need bigger debug level in console to see more details, because this code reports only "check wiring". I checked - wiring is OK.

This is not a case for crappy build because the sensor is detected by I2Cscanner

could be seen but may be not respond to targeted commands.

other libraryes work fine with this sensor

what do you mean ? Do you have a library working fine with your device? why don't you use it?

TomGeorge:
Hi,
Have you at least tried the 4K7 pullup resistors?

Tom... :slight_smile:

Yes, I tried. Not helped.

what do you mean ? Do you have a library working fine with your device? why don't you use it?

Because this library can be used for a very good motion detector. Read my first post.
Other libraries works, but I need to add a lot of C++ code to adjust for a good motion detector. I'm new in C++ and it's difficult for me to start from zero.
While debugging this code I'm learning.

I found the problem by myself. Now I don't get anymore "check wiring" in the console.

Initialize MPU6050

 * Sleep Mode:            Enabled
 * Clock Source:          Internal 8MHz oscillator
 * Accelerometer:         +/- 2 g
 * Accelerometer offsets: 2304 / 2800 / 1021

 Xraw = 0.00 Yraw = 0.00 Zraw = 0.00
 Xnorm = 0.00 Ynorm = 0.00 Znorm = 0.00
 Xraw = 0.00 Yraw = 0.00 Zraw = 0.00
 Xnorm = 0.00 Ynorm = 0.00 Znorm = 0.00

I just modified the function "Check MPU6050 Who Am I Register" to return always true, and the code runs. Now I'm checking why it can't read who am I register.

I'm trying to figure out how to read bits from registers and compare to datasheet. For example WHO_AM_I register.

Register adress is defined:
#define MPU6050_REG_WHO_AM_I (0x75) // Who Am I

The default value of this register is 0x68

here I modified to return true, but in reality it returns false:

if (fastRegister8(MPU6050_REG_WHO_AM_I) != 0x68)

Something is wrong in reading function?
So I decided to see what's inside WHO_AM_I register with this simply code:

uint8_t whoami_bits;
	
	Wire.beginTransmission(0b1101000); // the mpu address in binary or 0x68 in hex
	Wire.write(0x75);                             // select register 0x75 REG_WHO_AM_I
	Wire.endTransmission();
	Wire.requestFrom(0b1101000,6);      // request for 6 bits from selected register
	while (Wire.available() < 6);
	whoami_bits = Wire.read();
	Serial.println("Who_AM_I register contents :");
	Serial.println(whoami_bits);               // displaying contents

In the console I get:

Initialize MPU6050
Who_AM_I register contents :
152

What is 152 ?? Decimal 152 is 0x98 in hex. Wrong value. Or I'm interpreting something wrong here.
Can someone give an idea? I am reading correctly the values?

Wire.requestFrom(0b1101000,6);      // request for 6 bits from selected register

The second argument to requestFrom() is the number of BYTES being requested, not bits.

OK. 6 bytes not bits. You can ignore my typo in the comment. This does not affect the result. I've requested even 1 byte and I get the same result 152 (0x98), but the right result should be 104 or 0x68

To read that register you need to do

uint8_t value;
Wire.beginTransmission(0x68);
Wire.write(0x75);
Wire.endTransmission();

Wire.beginTransmission(0x68);
Wire.requestFrom(0x68, 1);
value = Wire.read();
Wire.endTransmission();

// now print it
Serial.print(value, BIN);

Then the spec states WHO_AM_I[6:1] that means you need to only take bits 1 to 6 of that register read to form the address and describes it this way

This register is used to verify the identity of the device. The contents of WHO_AM_I are the upper 6 bits of the MPU-60X0’s 7-bit I2C address. The least significant bit of the MPU-60X0’s I2C address is determined by the value of the AD0 pin. The value of the AD0 pin is not reflected in this register .

The I2C bus specification specifies that in standard-mode I2C, the slave address is 7-bits long followed by the read/write bit.

The default value of the register should be 0x68