How to read/write to a specific register of an I2C device

Hello all,

I am new to the forum, thanks for having me! Been wanting to get into microcontrollers for a while and I finally have the time to dedicate to it.

So typically me, I choose the deep end to jump into... I am busy working with and Invnesense MPU-6050 in the form of the GY-521 breakout board. I have gotten past the stage of extracting raw values from the sensor, but I am now trying to dig deeper. I want to set the configuration registers, which I can do, but it is proving difficult to verify them. Can someone please tell me where I am going wrong?

I am using a Teensy 3.0 MCU with the following connections:

VCC -> 3.3V
GND -> AGND
SCL -> Pin 19, A5 (SCL)
SDA -> Pin 18, A4 (SDA)

No other connections are made to or from the Teensy 3.0 with respect to the GY-521.

Registers are defined at the beginning of the code as follows:

#define MPU6050 0x68
#define GYRO_CONFIG 0x1B

I write the parameter for the configuration as follows:

  // Gyro Configuration
  Wire.beginTransmission(MPU6050);
    Wire.write(GYRO_CONFIG);  // GYRO_CONFIG register
    Wire.write(0);  // 0 = +/-250dps, 1 = +/-500dps, 2 = +/-1000dps, 3 = +/-2000dps
    Wire.endTransmission();

And then I try to verify it by reading it as follows:

  Wire.beginTransmission(MPU6050);
    Wire.requestFrom(MPU6050,1);
    Wire.write(GYRO_CONFIG);
    GCVal = Wire.read();
    Serial.print("Gyro. Config. Register Value = "); Serial.println(GCVal);
    Wire.endTransmission();

This is the result that it yields:

Gyro. Config. Register Value = 1
Initialization Done! :) Writing data...
1) AcX_raw = -12 | AcY_raw = -80 | AcZ_raw = 17064 | Tmp_raw = 28.81 | GyX_raw = -145 | GyY_raw = 126 | GyZ_raw = -61
2) AcX_raw = -72 | AcY_raw = -20 | AcZ_raw = 16940 | Tmp_raw = 28.86 | GyX_raw = -152 | GyY_raw = 128 | GyZ_raw = -73
3) AcX_raw = -180 | AcY_raw = -76 | AcZ_raw = 17084 | Tmp_raw = 28.91 | GyX_raw = -152 | GyY_raw = 134 | GyZ_raw = -62
4) AcX_raw = -84 | AcY_raw = 8 | AcZ_raw = 16980 | Tmp_raw = 28.91 | GyX_raw = -135 | GyY_raw = 126 | GyZ_raw = -58
5) AcX_raw = -128 | AcY_raw = -52 | AcZ_raw = 17040 | Tmp_raw = 29.00 | GyX_raw = -134 | GyY_raw = 130 | GyZ_raw = -66
6) AcX_raw = -60 | AcY_raw = 4 | AcZ_raw = 17216 | Tmp_raw = 28.91 | GyX_raw = -161 | GyY_raw = 128 | GyZ_raw = -34
7) AcX_raw = -68 | AcY_raw = -92 | AcZ_raw = 17076 | Tmp_raw = 29.00 | GyX_raw = -125 | GyY_raw = 124 | GyZ_raw = -61
8) AcX_raw = -100 | AcY_raw = 12 | AcZ_raw = 17116 | Tmp_raw = 29.05 | GyX_raw = -150 | GyY_raw = 127 | GyZ_raw = -52
9) AcX_raw = -160 | AcY_raw = -88 | AcZ_raw = 17108 | Tmp_raw = 29.00 | GyX_raw = -128 | GyY_raw = 128 | GyZ_raw = -57
10) AcX_raw = -76 | AcY_raw = -112 | AcZ_raw = 17024 | Tmp_raw = 29.00 | GyX_raw = -145 | GyY_raw = 134 | GyZ_raw = -67
MEMSData.csv written successfully

As you can see, I wrote 0 to the register, but it tells me that the value is 1. It does this regardless of whether I set it to 0, 1, 2 or 3. It is a read/write register.

This leads me to think that I am not writing the correct form of the value into the register or my code for extracting the register value is wrong. Could someone please help?

For your convenience below is attached the specifics of the MPU-6050 Register Map.

Please ask any questions and thanks for your help in advance!

Dylan

I'm not familiar with that device, but typically you would read a register by doing this:

void readConfig ()
{
  Wire.beginTransmission(MPU6050);
  Wire.write(GYRO_CONFIG);
  Wire.endTransmission();
  Wire.requestFrom(MPU6050,1);
  GCVal = Wire.read();

  Serial.print("Gyro. Config. Register Value = "); Serial.println(GCVal);
}

Martin-X, you are a man on a horse! :grin: :grin: :grin:

Worked like a charm! Thank you very much for your help!

So we are making progress...

My next question is how one writes multiple bits to a register. As one can see from the picture in the original post, the GYRO_CONFIG register also has self test enabling bits for the three axes. I can set the the fullscale of the gyro with the following code:

 // Gyro Configuration
  Wire.beginTransmission(MPU6050);
    Wire.write(GYRO_CONFIG);  // GYRO_CONFIG register
    Wire.write(0);  // 0 = +/-250dps, 1 = +/-500dps, 2 = +/-1000dps, 3 = +/-2000dps
    Wire.endTransmission();

However, this code only writes the 3rd and 4th bit. Can someone please explain to me how I configure the 5th, 6th and 7th bit?

Would I do something like this?

// Gyro Configuration
  Wire.beginTransmission(MPU6050);
    Wire.write(GYRO_CONFIG);  // GYRO_CONFIG register
    Wire.write(0xE3);  // Setting register to 11100011 in hex
    Wire.endTransmission();

Where I set the fullscale to 3 and enables the selftest bits.

I have a feeling that the answer lies in this AVR Tutorial, but I am getting a bit lost.

Thanks again,

Dylan

Dylan144GT:
Would I do something like this?

Yes, something like that.

Thanks again Martin-X!