Gy-521 mpu-6050 i2c

Hi everyone.

I am struggeling to let a Digispark Pro (ATtiny167) communicate with the GY-521 / MPU-6050 board
GY-521-MPU-6050
I must say, that I've never ever used I2C before. So I cannot know, where to start searching for the problem and which boards work well together and how I can tell right away which don't.

What am I doing?
I try to summarize the essential code, that in the end should produce some numbers.

#include <Wire.h>

pinMode(0, INPUT); // SDA
pinMode(2, INPUT); // SCL

Wire.begin();

// Setup MPU-6050
Wire.beginTransmission(0x68); // default address, when AD0 is not pulled high.
Wire.write(0x6B); // Register to disable sleep.
Wire.write(0b00000000);
Wire.endTransmission(); // returns 0
Wire.beginTransmission(0x68);
Wire.write(0x1B); // Register for gyro setup
Wire.write(0x00000000);
Wire.endTransmission(); // returns 0
Wire.beginTransmission(0x68);
Wire.write(0x1C); // Register for accel setup
Wire.write(0b00000000);
Wire.endTransmission(); // returns 0

Wire.beginTransmission(0x68);
Wire.write(0x3B); // Starting register of 6 bytes accelerometer values (3x high/low).
Wire.endTransmission(); // returns 0
Wire.requestFrom(0x68, 6); // returns 0
// each of the following 6 read() calls returns 0 here, where I would expect some reasonable byte values.
XH = Wire.read();
XL = Wire.read();
// ...

If all of the endTransmission() calls return 0, I think, the I2C is working fine, isn't it?
I only have a very simple DIY oscilloscope, which may not be able to handle 400kHz, but at least I can see, that SCL and SDA are pulled high by the board, which according to the I2C specs is correct. Further I catch some signals on wire, that look like communication is going on, without analyzing in detail - I would assume I don't need to debug a popular protocol like I2C. (Side note: When I was using a Digispark first, I got the return code 3 for the 3 setup calls, while I could observe SCL and SDA being pulled low. Maybe my Digispark is broken, that's why I switched to the Pro.) That's why I would assume, with the Pro the I2C works here.

About the wiring:
Pro 5V -> GY VCC, providing 4.8V
Pro PIN 0 -> GY SDA
Pro PIN 2 -> GY SCL
and of course a shared GND.
Power supply is via USB only for now.

Why am I getting 0 out of all registers? Btw. - the only way for me to see, what's going on is to use DigiKeyboard's println().

Any experiences? Any advice? Opinions?

I can only insert 1 picture in a post...

So here is what I captured on wire:

You must have pullup resistors on SDA and SCL. Typically they are 4.7K. Also, the sensor is 3.3V, and for safest operation, the pullups must be connected to 3.3V when used with a 5V Arduino. Otherwise logic level shifters are required.

Some guidelines for Arduino and I2C, provided by a forum member:

Thanks for the quick reply. I wonder, if I really have a problem regarded to voltage, since both lines are 3,3V high all the time. The GY-521 pulls them up. The Digispark does not force them high at 5V and I believe the spark on the other hand evaluates a voltage higher than 2,xV as "high" already, correct?

Of course not. Devices on the I2C bus actively pull the lines low for data transmission, which is why pullup resistors are required. However, if there are pullups to 5V, that is a problem for a 3.3V sensor.

Plenty of useful information in the link I posted.

Yea, I am currently reading...

What I don't understand: When I already have a 3.3V level on the bus, why do I still need pull up resistors?

Presumably there are pullups on the sensor itself. Looking closely at the sensor board photo, they are probably the resistors marked 472.

There is no universal standard for what value of pullup is to be used and where they should be connected. Many sensor and MCU board manufacturers leave the choice up to the user, so you have to check.

From what I measured and wrote in the initial post is that SCL and SDA are being pulled high by the board. When configured as input on the DS Pro, they would be 0V otherwise.

Plus - the I2C lib gives me a result code of 0, which means, that the transmission worked. When I give a false address e.g., then the result code is 1. If I had a lack of pull up resistors, I think, the result code would never be 0, right?

I2C does not work at all if the pullups are missing.

Use the Arduino I2C Address Scanner program to check I2C communications, and verify correct device addresses.

Alright, then I can mark this checked, because that's what the I2C Scanner is doing. Trying all addresses until it gets a 0 from endTransmission(). And that's what I get when connecting to 0x68. So that's not my problem so far.

Pins are being pulled high at 3.3V and the DS Pro sees this voltage as high. endTransmission() returns 0.
From this point I still do not understand, why reading the registers returns 0.

Here is the simplest code I know of that can be used to read the basic data from MPU-6050.

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}

void loop() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14); // request a total of 14 registers
  int16_t t = Wire.read();
  AcX = (t << 8) | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  t = Wire.read();
  AcY = (t << 8) | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  t = Wire.read();
  AcZ = (t << 8) | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  t = Wire.read();
  Tmp = (t << 8) | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  t = Wire.read();
  GyX = (t << 8) | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  t = Wire.read();
  GyY = (t << 8) | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  t = Wire.read();
  GyZ = (t << 8) | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  t = Wire.read();
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp / 340.00 + 36.53); //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

Well, I know this code. What would help me is some1 who can tell me, where exactly could be my particular problem, since I already posted my code and described my hardware / wiring pretty detailed. You may find, that my code does pretty much what you just posted.

Does it work for your setup?

If not, there is either a sensor or MCU problem, which might have to do with your unusual choice of the Digispark board or the Arduino core you are using. Few people on this forum will be familiar with either module.

You may find, that my code does pretty much what you just posted.

I find that the code is not the same. You forgot to issue a restart before requesting multiple data bytes. If that feature even works with the Digispark core.

I can't see, where this restart takes place in your code example.

Wire.endTransmission(false);

Always a good idea to consult the reference page: endTransmission() - Arduino Reference

1 Like

Oh, right. The "stop" parameter. That was a good hint, thank you. Unluckily and unexpectedly it doesn't change the result. I keep getting 0 :frowning:
So, during configuration of the GY-521, I use endTransmission(), which defaults to true. And before any requestFrom() I use endTransmission(false);

btw. tried it with a regular Arduino Uno now. Same result. I ordered another module. I can't quite imagine such a defect on a mass production board, that the I2C bus is responding, but the sensors aren't providing any data :thinking: We'll see.

So, now that I got a replacement MPU-board I know, that the first one really had a defect. I2C was working, but the sensor must have been reporting zeros, which is why I only got zeros.

Sad, that my first experience with I2C was like this, which left me completely clueless, if my code was wrong, my hardware incapable or whatever.

GY-521 / MPU-6050 works with Arduino Uno, Digispark Pro and even Digispark with the Wire or TinyWireM library.

The MPU-6050 was discontinued years ago.

Today you can only buy Chinese imitations, and have no guarantee that the modules even work as advertised. They are very cheap for a reason. It is fine to experiment with modules that start with GY- but buy several of them, so that there is a good chance that one or more actually work.

If you want genuine, quality products, with product support, buy them from reputable suppliers.

1 Like

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