Connection failed in MPU6050 sensor

Hello everyone! I bought a GY-87 module sesnor, this module has BMP180, MPU6050 and QMC5883L sesnors. Link amazon: https://www.amazon.es/gp/product/B07HMLRD8Q/ref=ox_sc_saved_title_1?smid=A3U3NV7MT8POQS&psc=1.

I am using Arduino NANO for this project. The connection NANO - GY is:

NANO GY-87

GND GND
A5 SCL
A4 SDA
3.3V 3.3V

Fisrt I used the BMP180 sensor, and it works correct. The serial monitor prints “BMP180 init success”.

But when I tried to calibrate the MPU6050, the monitor serial prints “Connection failed in MPU6050”.
I upload an example to MPU, that only use the Wire library.

#include <Wire.h>
const int MPU_ADDR = 0x68;
int16_t accelerometer_x, accelerometer_y, accelerometer_z;
int16_t gyro_x, gyro_y, gyro_z;
int16_t temperature;
char tmp_str [7];
char* convert_int16_to_str(int16_t i) {
  sprintf(tmp_str, "%6d", i);
  return tmp_str;
}

void setup() {
  Serial.begin (9600);
  Wire.begin ();
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x68);
  Wire.write(0);
  Wire.endTransmission(true);

}

void loop() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_ADDR, 7*2, true);

  accelerometer_x = Wire.read()<<8 | Wire.read();
  accelerometer_y = Wire.read()<<8 | Wire.read();
  accelerometer_z = Wire.read()<<8 | Wire.read();
  temperature = Wire.read()<<8 | Wire.read();
  gyro_x = Wire.read()<<8 | Wire.read();
  gyro_y = Wire.read()<<8 | Wire.read();
  gyro_z = Wire.read()<<8 | Wire.read();

  Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
  Serial.print(" | aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
  Serial.print(" | aZ = "); Serial.print(convert_int16_to_str(accelerometer_z));

  Serial.print(" | tmp = "); Serial.print(temperature/340.00+36.53);
  Serial.print(" | gX = "); Serial.print(convert_int16_to_str(gyro_x));
  Serial.print(" | gY = "); Serial.print(convert_int16_to_str(gyro_y));
  Serial.print(" | gZ = "); Serial.print(convert_int16_to_str(gyro_z));
  Serial.println();

  delay (700);
 
}

I use I2C_scanner to find 0x68 ADDRESS. Arduino Playground - I2cScanner.

The serial monitor prints:

aX: -6840 | aY: -2064| aZ: 840| tmp: 44.32| gX: -630| gY: 574| gZ: -158

Then I tried to calibrate the sensor, but it doesn’t works. I use this libraries: arduino_MPU6050_lib_pack.rar - Google Drive.

The code:

// I2Cdev and MPU6050 must be installed as libraries
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"


//Change this 3 variables if you want to fine tune the skecth to your needs.
int buffersize=1000;     //Amount of readings used to average, make it higher to get more precision but sketch will be slower  (default:1000)
int acel_deadzone=8;     //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge  (default:8)
int giro_deadzone=1;     //Giro error allowed, make it lower to get more precision, but sketch may not converge  (default:1)

// 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(0x68); // <-- use for AD0 high

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

int mean_ax,mean_ay,mean_az,mean_gx,mean_gy,mean_gz,state=0;
int ax_offset,ay_offset,az_offset,gx_offset,gy_offset,gz_offset;

void setup() {
  // join I2C bus (I2Cdev library doesn't do this automatically)
  Wire.begin();
  // COMMENT NEXT LINE IF YOU ARE USING ARDUINO DUE
  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz). Leonardo measured 250kHz.

  // initialize serial communication
  Serial.begin(115200);

  // initialize device
  accelgyro.initialize();

  // wait for ready
  while (Serial.available() && Serial.read()); // empty buffer
  while (!Serial.available()){
    Serial.println(F("Send any character to start sketch.\n"));
    delay(1500);
  }                
  while (Serial.available() && Serial.read()); // empty buffer again

  // start message
  Serial.println("\nMPU6050 Calibration Sketch");
  delay(2000);
  Serial.println("\nYour MPU6050 should be placed in horizontal position, with package letters facing up. \nDon't touch it until you see a finish message.\n");
  delay(3000);
  // verify connection
  Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  delay(1000);
  // reset offsets
  accelgyro.setXAccelOffset(0);
  accelgyro.setYAccelOffset(0);
  accelgyro.setZAccelOffset(0);
  accelgyro.setXGyroOffset(0);
  accelgyro.setYGyroOffset(0);
  accelgyro.setZGyroOffset(0);
}


void loop() {
  if (state==0){
    Serial.println("\nReading sensors for first time...");
    meansensors();
    state++;
    delay(1000);
  }

  if (state==1) {
    Serial.println("\nCalculating offsets...");
    calibration();
    state++;
    delay(1000);
  }

  if (state==2) {
    meansensors();
    Serial.println("\nFINISHED!");
    Serial.print("\nSensor readings with offsets:\t");
    Serial.print(mean_ax); 
    Serial.print("\t");
    Serial.print(mean_ay); 
    Serial.print("\t");
    Serial.print(mean_az); 
    Serial.print("\t");
    Serial.print(mean_gx); 
    Serial.print("\t");
    Serial.print(mean_gy); 
    Serial.print("\t");
    Serial.println(mean_gz);
    Serial.print("Your offsets:\t");
    Serial.print(ax_offset); 
    Serial.print("\t");
    Serial.print(ay_offset); 
    Serial.print("\t");
    Serial.print(az_offset); 
    Serial.print("\t");
    Serial.print(gx_offset); 
    Serial.print("\t");
    Serial.print(gy_offset); 
    Serial.print("\t");
    Serial.println(gz_offset); 
    Serial.println("\nData is printed as: acelX acelY acelZ giroX giroY giroZ");
    Serial.println("Check that your sensor readings are close to 0 0 16384 0 0 0");
    Serial.println("If calibration was succesful write down your offsets so you can set them in your projects using something similar to mpu.setXAccelOffset(youroffset)");
    while (1);
  }
}


void meansensors(){
  long i=0,buff_ax=0,buff_ay=0,buff_az=0,buff_gx=0,buff_gy=0,buff_gz=0;

  while (i<(buffersize+101)){
    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    
    if (i>100 && i<=(buffersize+100)){ //First 100 measures are discarded
      buff_ax=buff_ax+ax;
      buff_ay=buff_ay+ay;
      buff_az=buff_az+az;
      buff_gx=buff_gx+gx;
      buff_gy=buff_gy+gy;
      buff_gz=buff_gz+gz;
    }
    if (i==(buffersize+100)){
      mean_ax=buff_ax/buffersize;
      mean_ay=buff_ay/buffersize;
      mean_az=buff_az/buffersize;
      mean_gx=buff_gx/buffersize;
      mean_gy=buff_gy/buffersize;
      mean_gz=buff_gz/buffersize;
    }
    i++;
    delay(2); //Needed so we don't get repeated measures
  }
}

void calibration(){
  ax_offset=-mean_ax/8;
  ay_offset=-mean_ay/8;
  az_offset=(16384-mean_az)/8;

  gx_offset=-mean_gx/4;
  gy_offset=-mean_gy/4;
  gz_offset=-mean_gz/4;
  while (1){
    int ready=0;
    accelgyro.setXAccelOffset(ax_offset);
    accelgyro.setYAccelOffset(ay_offset);
    accelgyro.setZAccelOffset(az_offset);

    accelgyro.setXGyroOffset(gx_offset);
    accelgyro.setYGyroOffset(gy_offset);
    accelgyro.setZGyroOffset(gz_offset);

    meansensors();
    Serial.println("...");

    if (abs(mean_ax)<=acel_deadzone) ready++;
    else ax_offset=ax_offset-mean_ax/acel_deadzone;

    if (abs(mean_ay)<=acel_deadzone) ready++;
    else ay_offset=ay_offset-mean_ay/acel_deadzone;

    if (abs(16384-mean_az)<=acel_deadzone) ready++;
    else az_offset=az_offset+(16384-mean_az)/acel_deadzone;

    if (abs(mean_gx)<=giro_deadzone) ready++;
    else gx_offset=gx_offset-mean_gx/(giro_deadzone+1);

    if (abs(mean_gy)<=giro_deadzone) ready++;
    else gy_offset=gy_offset-mean_gy/(giro_deadzone+1);

    if (abs(mean_gz)<=giro_deadzone) ready++;
    else gz_offset=gz_offset-mean_gz/(giro_deadzone+1);

    if (ready==6) break;
  }
}

Here, firstly prints MPU6050 connection failed, and the final message with the Offsets doesn’t appear.
The GY is in horizontal position and facing up. I have been waitig for 4 minutes and nothing appears…

If someone can help me, please!

Comment out the TWBR line and try again. Most probably you have to long wires for a 400kHz bus speed.

Hello!
What I have to comment out in TWBR?

Hi,
Have you got 4k7 pullup resistors on the SDA and SCL lines?

Tom.... :slight_smile:

Hi Tom,

No page says that I have to put resistors to use MPU6050, I have to do it?

I connected to 3.3V

Hi,
Most controllers have them already fitted to the I2C lines, but it will not hurt to add external ones.
I2C needs pullup resistors and some problems with I2C devices seems to be because of the lack of pullups.
Yes you can put them from SDA to 3V3 and SCL and 3V3.

Tom.... :slight_smile:

Thansk for helping!

But I upload codes without resistors and the sensor prints numbers… and when I move it the numbers changes. The problem is when I want to calibrate the sensor, it doesn’t calibrate.

If the sensor was broken, it always prints 0, no?

Can I use the pullup of the Arduino NANO? How can I write in the code that I’m using the Pullup of the Arduino to SCL and SDA?

Hi,

Can I use the pullup of the Arduino NANO? How can I write in the code that I'm using the Pullup of the Arduino to SCL and SDA?

You don't do anything to your code, you physically add them to your circuit, the code has nothing to do with I2C pullups.
i2cres.jpg

Tom... :slight_smile:

i2cres.jpg

Okey, so if I put this resistors (connected from SCL and SDA to VCC (3.3V)), the code from Arduino doesn't prints "MPU6050 connection failed" and the sensor can be calibrated?

Because I told you before that the sensor works (not correctly due to the calibration), it's very strange...

Thanks!

...the code won't print...

Sorry!! It's first conditional :slight_smile:

What I have to comment out in TWBR?

I wrote "the TWBR line", so I meant the following line:

  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz). Leonardo measured 250kHz.

Hi,

I eliminated this line, and itkeep printing connection failed....

If the sensor was broken, it always prints 0, no?

No, it would always return only 1 bits, so the results you get may be the result of a broken sensor. But it seems you have a sensor listening on the MPU6050 address but not behaving exactly as such a sensor. It it possible that you got a Chinese fake chip?

Hi,

The sensor is in the GY-87 module sensor. I bought it in amazon:

I think it is not a fake chip... Why do you say that?

Why do you think the chip is NOT fake? They are everywhere these days, especially with sellers like Amazon, eBay and Alibaba. And there are always failing modules.

Hi,
Have you tried connecting 5V to Vccin instead of 3V3 to the 3V3 pin on the 6050 and using 4k7 resistors from SDA to 5V and SCL to 5V?

If not then please try it, using the 5V rather than 3V3 supply from the Nano.

Tom... :slight_smile: