Arduino MPU6050 AD0 Tricks with offset setting gives corrupted data

I am currently experimenting with two MPU6050 which the AD0 is connected via PIN 7 and PIN 8 respectively, and if this is working, I plan to add another 2 more MPU6050 to it.

I am using i2cdevlib's MPU6050 library and what I did in a flow is:

Initialize one MPU6050 object

  • Set MPU6050 Object as 0x68 (LOW AD0)
  • Set all to HIGH, but one to LOW (to select the MPU6050)
  • Calculate offset and calibrate, store everything in array. (offsets and etc)
  • Repeat steps 3 to 4 unless all are calibrated.
  • Start to loop between two MPU, setting everything to HIGH and the one to be used as low.
  • Write the LOW's (current selected) MPU with offset that is stored in array, then getMotion6 (Raw data).
  • Write selected MPU to high, repeat from step 6 to step 7.

Everything is working, however when I am having a loop to collect data, it gives me corrupted data, the problem I find is in this function.

void loop{
    for (int i = 7; i <= 8; i++) {
      pinMode(i, OUTPUT);

      digitalWrite( i, LOW);
      //      Serial.print("\nWriting pin: ");
      //      Serial.print(i);
      //      Serial.println(" to LOW");
      delay(2);
      int index = i - 7;
      Serial.print("Offsets:\t");
      Serial.print(ax_offset[index]);
      Serial.print("\t");
      Serial.print(ay_offset[index]);
      Serial.print("\t");
      Serial.print(az_offset[index]);
      Serial.print("\t");
      Serial.print(gx_offset[index]);
      Serial.print("\t");
      Serial.print(gy_offset[index]);
      Serial.print("\t");
      Serial.println(gz_offset[index]);

      accelgyro.setXAccelOffset(ax_offset[index]);
      accelgyro.setYAccelOffset(ay_offset[index]);
      accelgyro.setZAccelOffset(az_offset[index]);
      accelgyro.setXGyroOffset(gx_offset[index]);
      accelgyro.setYGyroOffset(gy_offset[index]);
      accelgyro.setZGyroOffset(gz_offset[index]);

      Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t");
      Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t");
      Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t");
      Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t");
      Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t");
      Serial.print(accelgyro.getZGyroOffset()); Serial.println("\t");

      //      delay(1000);
      //      accelgyro.getMotion6(&ax[index], &ay[index], &az[index], &gx[index], &gy[index], &gz[index]);
      int ax, ay, az, gx, gy, gz;
      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

      Serial.print("PIN ");
      Serial.print(i);
      Serial.print("'s data is:");
      Serial.print("aX:" ); Serial.print(ax); Serial.print("\t");
      Serial.print("aY:" ); Serial.print(ay); Serial.print("\t");
      Serial.print("aZ:" ); Serial.print(az); Serial.print("\t");

      Serial.print("gX:" ); Serial.print(gx); Serial.print("\t");
      Serial.print("gY:" ); Serial.print(gy); Serial.print("\t");
      Serial.print("gZ:" ); Serial.println(gz);

      pinMode(i, INPUT_PULLUP);
    }
}

The first few loops will return accurate data (as in, all the sensors are close 0 [no motion])

I am suspecting because there is a huge difference between both sensors and the getMotion6 is comparing with the old sensor, can that be the case?

Attached is the output of my sensors reading, untouched.

13:39:39.292 -> Writing pin: 8 to HIGH
13:39:39.292 -> Offsets:	-4602	-640	2493	220	-29	9
13:39:39.292 -> -4602	-640	2493	220	-29	9	
13:39:39.292 -> PIN 7's data is:aX:-56	aY:4	aZ:16284	gX:7	gY:86	gZ:26
13:39:39.292 -> Offsets:	-8149	780	2644	46	11	55
13:39:39.292 -> -8149	780	2644	46	11	55	
13:39:39.292 -> PIN 8's data is:aX:68	aY:-4	aZ:16408	gX:-64	gY:27	gZ:2
13:39:44.293 -> Offsets:	-4602	-640	2493	220	-29	9
13:39:44.293 -> -4602	-640	2493	220	-29	9	
13:39:44.326 -> PIN 7's data is:aX:26	aY:44	aZ:15108	gX:53	gY:-255	gZ:-240
13:39:44.326 -> Offsets:	-8149	780	2644	46	11	55
13:39:44.326 -> -8149	780	2644	46	11	55	
13:39:44.326 -> PIN 8's data is:aX:-32352	aY:13320	aZ:1160	gX:-768	gY:3	gZ:24

Sometimes, it takes few rounds before the data goes corrupted but sometimes immediately on the second round, what did I do wrong in the code?

Try it with the most simple code there is: Arduino Playground - MPU-6050.

Which Arduino board do you have ?

If you are using a Arduino Uno, then a HIGH to AD0 will push 5V into the MPU-6050 and damage the 3.3V sensor.
I see that you switch between OUTPUT + LOW and INPUT_PULLUP. I don't know if the small current by the pullup resistor is safe, probably not. There is also a small glitch in your code that sets the OUTPUT as HIGH.

Background information:
The microcontroller of the Arduino Uno is part of the AVR family. They have a few things combined and have a few tricks with the input and output registers for a pin.
One of those things is that when you set INPUT_PULLUP, the output register is pre-set to HIGH. As soon as you make that pin a OUTPUT, then the output will be HIGH !

You have this:

pinMode(i, OUTPUT);  // output will be HIGH after a INPUT_PULLUP
digitalWrite( i, LOW);  // output is set LOW
delay(2);   // a small delay is good
...
pinMode(i, INPUT_PULLUP);  // set to INPUT and turn on pullup resistor

I suggest to pre-set the output, to prevent tha it will get HIGH

digitalWrite( i, LOW);  // pre-set the output to LOW, pullup is turned off
pinMode(i, OUTPUT);  // output will be OUTPUT and LOW
delay(2);   // a small delay is good
...
pinMode(i, INPUT_PULLUP);  //

Your MPU-6050 might already be damaged and the pullup might still be too much current into the AD0 pin.

Can you buy a 3.3V Arduino board ?

Hey as of what I read and understand around the forum, the AD0 Pin on the MPU_6050 can take a 5V [which is a HIGH], only the microcontroller unit [MPU_6050] itself takes a 3.3v. But this may be wrong somehow. Because I've tried to connect one of the MCU AD0 Pin to 5v and it successfully detects and the simplest code works.

I am using Arduino Uno and is connecting the MCU via VCC Pin with 3.3v, but the AD0 is set to be connected via Pin 7 and Pin 8 [Two MPU6050 in this case]

Did I damage the MPU6050 in this case? Because I've tried using the simplest code it seems to be working.

I've tried to experiment a bit, and it appears to me that my tricks will work if I am not setting offset to other values but 0.

Works as in, MPU6050's getMotion returns only a small movement if stay untouched on surface.

samleews:
Hey as of what I read and understand around the forum, the AD0 Pin on the MPU_6050 can take a 5V [which is a HIGH]

Can you tell where you read that ? It is wrong.

samleews:
Did I damage the MPU6050 in this case?

Well, sometimes a chip does not get damaged so easily. The MPU-6050 is probably still okay, maybe, perhaps not :confused: The measured values could be inaccurate.
The MPU-6050 is an older chip. The newer sensor chips (from Bosch for example) do really get damaged with 5V.

Can you show your full sketch and explain the problem once more ?
When you have many sensors, then you should have many objects. Each is located at 0x68, but only one can be active at a time.
I'm not very fond of the I2CDev lib. I don't know if it can deal with multiple sensors. Can you try to find examples for that ?

I agree with Koepel, do not apply 5V to AD0.

By far the best approach is to use 3.3V Arduinos with 3.3V sensors. You can buy a 3.3V Pro Mini clone on eBay for about $2.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.