How to link 6 gy-521s in a uno?

Hi, i am newbie.
I can link one gy-521(mpu6050) to arduino uno and run the Teapot demo.

I have a idea needs 6 mpu6050s.
Someone suggest me using mega2560 or stm32 instead.

Is this achievable using a uno?

Hi, every one.
I made some advance.

Follow official trick,
I wired 2 GY-521s to UNO like:

2GY521s - UNO
INT - 2
TX/RX - A4/A5
VCC/GND - VCC/GND

1st GY521 AD0 - 9
2nd GY521 AD0 - 10

when I write code like:

digitalWrite(9, LOW);
digitalWrite(10, HIGH);
//data processing

or

digitalWrite(9, HIGH);
digitalWrite(10, LOW);
//data processing

the 2 GY-521s works well separately.

But when I change the code like:

digitalWrite(9, LOW);
digitalWrite(10, HIGH);
//data processing

digitalWrite(9, HIGH);
digitalWrite(10, LOW);
//data processing

The system wait INT for a long time (more than 5s),
After waiting, 2 GY-521s works for a while (also about 5s),
Then waiting for INT.

Why this happens?

I found 2 MPU6050s compete on INT0 and this result in FIFOoverflow
Is there any method transfering data without interrupt?

From what I can see, the 6050 has only 1 address bit, and it can have a I2C address of either 0x68 or 0x69 so that would limit you to having only 2 of them.

I have realized a solution with 2 6050s like:

2GY521s - UNO
TX/RX - A4/A5
VCC/GND - VCC/GND

1st GY521 AD0 - 9
2nd GY521 AD0 - 10

–NO INT linked–

The code

#include <Kalman.h>
#include <Wire.h>
#include <Math.h>

float fRad2Deg = 57.295779513f;
const int MPU = 0x68;
const int nValCnt = 7;

const int nCalibTimes = 50;
int calibData[nValCnt];

unsigned long nLastTime = 0;
float fLastRoll = 0.0f;
float fLastPitch = 0.0f;
Kalman kalmanRoll;
Kalman kalmanPitch;

int numOfMPU = 1;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Wire.begin();

pinMode( 9, OUTPUT);
pinMode(10, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:

if (numOfMPU == 1)
{
numOfMPU = 2;
digitalWrite( 9, LOW);
digitalWrite(10, HIGH);
}
else
{
numOfMPU = 1;
digitalWrite( 9, HIGH);
digitalWrite(10, LOW);
}

WriteMPUReg(0x6B, 0);
Calibration();
nLastTime = micros();

int readouts[nValCnt];
ReadAccGyr(readouts);

float realVals[7];
Rectify(readouts, realVals);

float fNorm = sqrt(realVals[0] * realVals[0] + realVals[1] * realVals[1] + realVals[2] * realVals[2]);
float fRoll = GetRoll(realVals, fNorm);
if (realVals[1] > 0) {
fRoll = -fRoll;
}
float fPitch = GetPitch(realVals, fNorm);
if (realVals[0] < 0) {
fPitch = -fPitch;
}

unsigned long nCurTime = micros();
float dt = (double)(nCurTime - nLastTime) / 1000000.0;

float fNewRoll = kalmanRoll.getAngle(fRoll, realVals[4], dt);
float fNewPitch = kalmanPitch.getAngle(fPitch, realVals[5], dt);

float fRollRate = (fNewRoll - fLastRoll) / dt;
float fPitchRate = (fNewPitch - fLastPitch) / dt;

fLastRoll = fNewRoll;
fLastPitch = fNewPitch;

nLastTime = nCurTime;

//Serial.print(“Roll:”);
//Serial.print(fNewRoll);
//Serial.print(’(’);
Serial.println(fRollRate);
//Serial.print("),\t\tPitch:");
//Serial.print(fNewPitch);
//Serial.print(’(’);
//Serial.print(fPitchRate);
//Serial.print(")\n");
delay(10);
}

void WriteMPUReg(int nReg, unsigned char nVal) {
Wire.beginTransmission(MPU);
Wire.write(nReg);
Wire.write(nVal);
Wire.endTransmission(true);
}

unsigned char ReadMPUReg(int nReg) {
Wire.beginTransmission(MPU);
Wire.write(nReg);
Wire.requestFrom(MPU, 1, true);
Wire.endTransmission(true);
return Wire.read();
}

void ReadAccGyr(int *pVals) {
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.requestFrom(MPU, nValCnt * 2, true);
Wire.endTransmission(true);
for (long i = 0; i < nValCnt; ++i) {
pVals = Wire.read() << 8 | Wire.read();

  • }*
    }
    void Calibration()
    {
  • float valSums[7] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0};*
  • for (int i = 0; i < nCalibTimes; ++i) {*
  • int mpuVals[nValCnt];*
  • ReadAccGyr(mpuVals);*
  • for (int j = 0; j < nValCnt; ++j) {*
  • valSums[j] += mpuVals[j];*
  • }*
  • }*
  • for (int i = 0; i < nValCnt; ++i) {*
    calibData = int(valSums / nCalibTimes);
    * }*
    * calibData[2] += 16384;*
    }
    float GetRoll(float *pRealVals, float fNorm) {
    _ float fNormXZ = sqrt(pRealVals[0] * pRealVals[0] + pRealVals[2] * pRealVals[2]);
    * float fCos = fNormXZ / fNorm;
    return acos(fCos) * fRad2Deg;
    }
    float GetPitch(float *pRealVals, float fNorm) {
    float fNormYZ = sqrt(pRealVals[1] * pRealVals[1] + pRealVals[2] * pRealVals[2]);
    float fCos = fNormYZ / fNorm;
    return acos(fCos) * fRad2Deg;
    }
    void Rectify(int *pReadout, float *pRealVals) {
    for (int i = 0; i < 3; ++i) {_
    pRealVals = (float)(pReadout _- calibData) / 16384.0f;
    }
    pRealVals[3] = pReadout[3] / 340.0f + 36.53;
    for (int i = 4; i < 7; ++i) {_

    pRealVals = (float)(pReadout _- calibData) / 131.0f;
    }
    }*

    However, 50 calibrations result in a good shape but the speed is low.
    And the
    I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
    does not use calibrations,
    how it get good data?_

Yes, the 6050 may have only one address bit. Drive each device with a unique data line from the Arduino to the address line.
Hold the line High for all of them, which is address 0x69 I think. Drive one low and talk to address 0x68 - the one device with its address line low will be the one you are accessing.

That's right, I have just used this trick.

i have tested 3 sensors,
it works well.