Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MPU6050 I2C communication is not possible #53

Closed
agcaahmet opened this issue Nov 15, 2016 · 28 comments
Closed

MPU6050 I2C communication is not possible #53

agcaahmet opened this issue Nov 15, 2016 · 28 comments

Comments

@agcaahmet
Copy link

Although I2C Scanner sketch is able to found the device, it is not possible to communicate with MPU6050 using jrowberg/i2cdevlib library. On the other hand, using esp8266 board works with the same sketch and library.

@nkolban
Copy link

nkolban commented Nov 16, 2016

By any chance do you have a logic analyzer that you can attach to the SDA and CLK to see what is being sent?

@me-no-dev
Copy link
Member

I have looked many times at libs like this and never came up with a reason to why I2Cdev lib calls Wire.beginTransmission before reading data from I2C slave. That is a really wrong approach ;) begin and end transmission are used only for writing to slaves and not reading. I remember doing some hacking to the I2C lib for ESP8266 in order to get that resolved, but it's bad code non the less.
Will look into screwing with the lib again to make it compatible, but in general I find this to be the wrong thing to do ;)

@me-no-dev
Copy link
Member

hmm... I looked at the code and there is nothing to prevent even this from working. It will send a probe after reading and that is all that will happen

@agcaahmet
Copy link
Author

@nkolban Unfortunately, I dont have a logic analyzer :(
@me-no-dev I will try your trick in your first message (comment out begin and end transmission statements for reading) but I could not understand what you mean exactly in your second message

@agcaahmet
Copy link
Author

By the way, the same problem exists with the following "Short example sketch" in Arduino website which is free of I2C library.

// 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,true); // request a total of 14 registers
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
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);
}

The result of this sketch on serial line is:
AcX = 0 | AcY = 0 | AcZ = 0 | Tmp = 36.53 | GyX = 0 | GyY = 0 | GyZ = 0

@me-no-dev
Copy link
Member

I'll give it a go

me-no-dev added a commit that referenced this issue Nov 16, 2016
@me-no-dev
Copy link
Member

hey can you pull the latest master and give this another go?

AcX = -1836 | AcY = 152 | AcZ = 15844 | Tmp = 30.32 | GyX = -375 | GyY = -111 | GyZ = -148
AcX = -1844 | AcY = 220 | AcZ = 15884 | Tmp = 30.32 | GyX = -376 | GyY = -98 | GyZ = -134
AcX = -1724 | AcY = 128 | AcZ = 15752 | Tmp = 30.27 | GyX = -393 | GyY = -127 | GyZ = -145
AcX = -1768 | AcY = 272 | AcZ = 15932 | Tmp = 30.27 | GyX = -388 | GyY = -95 | GyZ = -152
AcX = -1724 | AcY = 192 | AcZ = 15884 | Tmp = 30.22 | GyX = -427 | GyY = -113 | GyZ = -136

@agcaahmet
Copy link
Author

Thank you for your great effort, now the "Short Example Sketch" works. However, I could not still make it work with the I2CDev library. I am trying possible modifications on I2CDev.cpp file but haven't found any solution :(

@me-no-dev
Copy link
Member

If I2CDev tests the return endTarnsaction, it will receive error, because MPU does not send ACK. Maybe that is causing it to fail?

@agcaahmet
Copy link
Author

Arduino-MPU6050-Example sketch (base code).txt

The attached base code (directly taken from website http://playground.arduino.cc/Main/MPU-6050) is also not working. The serial monitor result is:
MPU-6050
Read accel, temp and gyro, error = 2
accel x,y,z: 0, 0, 0
temperature: 36.506 degrees Celsius
gyro x,y,z : 0, 0, 0,

I tried to comment out endTransmission return statement but it didnt help. Below is the serial monitor result:
MPU-6050
Read accel, temp and gyro, error = -11
accel x,y,z: 0, 0, 0
temperature: 36.506 degrees Celsius
gyro x,y,z : 0, 0, 0,

I will try to monitor the SDA and SCL lines and post here the results if I can :)

@me-no-dev
Copy link
Member

make sure that the module has pull-ups or add ones yourself. Pins are floating

@agcaahmet
Copy link
Author

Unfortunately, pull-up resistors didn't make any difference. I think the module has already pull-ups.

@me-no-dev
Copy link
Member

Ok, I have 6050 somewhere around. I'll try to find it and give it a go.

me-no-dev added a commit that referenced this issue Dec 9, 2016
wait for data to be latched and increase timeout in attempt to fix clock stretch issues
Connected issues:
http://esp32.com/viewtopic.php?f=19&t=632&p=2832#p2801
#81
#53
#11
@me-no-dev
Copy link
Member

try the latest commit please :)

@agcaahmet
Copy link
Author

Now, I2C communication cause a hang for esp32. The mcu does nothing just after the first wire communication :(

@me-no-dev
Copy link
Member

please try now :)

@agcaahmet
Copy link
Author

Arduino "Short Example Sketch" Works with the following result:

AcX = 1876 | AcY = 10356 | AcZ = -14036 | Tmp = 26.69 | GyX = 136 | GyY = -13 | GyZ = -270
AcX = 1732 | AcY = 10340 | AcZ = -14048 | Tmp = 26.65 | GyX = 105 | GyY = -27 | GyZ = -272
AcX = 1828 | AcY = 10336 | AcZ = -13844 | Tmp = 26.55 | GyX = 129 | GyY = -74 | GyZ = -194
...

However "Example Sketch (Base Code)" still not working with following result:

InvenSense MPU-6050
June 2012
WHO_AM_I : 0, error = 3
PWR_MGMT_1 : 0, error = 3

MPU-6050
Read accel, temp and gyro, error = 3
accel x,y,z: 0, 0, 0
temperature: 36.506 degrees Celsius
gyro x,y,z : 0, 0, 0,

MPU-6050
Read accel, temp and gyro, error = 3
accel x,y,z: 0, 0, 0
temperature: 36.506 degrees Celsius
gyro x,y,z : 0, 0, 0,
...

@me-no-dev
Copy link
Member

Please try the latest commit.

@agcaahmet
Copy link
Author

Unfortunately, similar results:
"Short Example Sketch" works but "Example sketch (base code)" and "MPU6050_raw" (from jrowberg) do not work.
For info: I am using gy-86 module

@me-no-dev
Copy link
Member

MPU6050_raw ? no clue what that is, but I'll wildly guess that it's reading single bytes to get WHO_AM_I for example and it locks the bus

@me-no-dev
Copy link
Member

#90 (comment)

@me-no-dev
Copy link
Member

ok, please try the latest commit

@agcaahmet
Copy link
Author

Oh thank you for your great effort, I2C now works on MPU6050, I tried also I2CDev repo library and it also works :)

@techboycr
Copy link

@agcaahmet I am facing a similar issue but in this case I2Cdev will not even compile.

How did you get it to compile with the library?!

@agcaahmet
Copy link
Author

There exist some duplicate definitions, you need to comment out one of each duplicate definition.
And you need to define "BUFFER_LENGTH" in your code (for example in I2Cdev.h file) as follows:
#define BUFFER_LENGTH 32

@carbonadam
Copy link

i2cdevlib does not work. Arduino: 1.8.5 (Windows 10), Board: "DOIT ESP32 DEVKIT V1, 80MHz, 921600, None"

In file included from C:\Program Files (x86)\Arduino\libraries\I2Cdev\I2Cdev.h:80:0,

             from C:\Program Files (x86)\Arduino\libraries\I2Cdev\I2Cdev.cpp:46:

C:\Program Files (x86)\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readBytes(uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)':

C:\Program Files (x86)\Arduino\libraries\I2Cdev\I2Cdev.cpp:276:62: error: 'BUFFER_LENGTH' was not declared in this scope

         for (uint8_t k = 0; k < length; k += min(length, BUFFER_LENGTH)) {

                                                          ^

C:\Users\woodtiger\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:181:24: note: in definition of macro 'min'

#define min(a,b) ((a)<(b)?(a):(b))

                    ^

C:\Program Files (x86)\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readWords(uint8_t, uint8_t, uint8_t, uint16_t*, uint16_t)':

C:\Program Files (x86)\Arduino\libraries\I2Cdev\I2Cdev.cpp:414:70: error: 'BUFFER_LENGTH' was not declared in this scope

         for (uint8_t k = 0; k < length * 2; k += min(length * 2, BUFFER_LENGTH)) {

                                                                  ^

C:\Users\woodtiger\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:181:24: note: in definition of macro 'min'

#define min(a,b) ((a)<(b)?(a):(b))

                    ^

exit status 1
Error compiling for board DOIT ESP32 DEVKIT V1.

@carbonadam
Copy link

Any idea why it wont compile? I am not really sure on the status of the i2c and also those multiple definitions and where to find them

@Pi-pythoner
Copy link

//Hey guys,I just work it out,because arduino i2c AND ESP32 arduino i2c not same
//You just need add Wire.begin(SDA, SCL);

#include<Wire.h>
#define SDA 4
#define SCL 15

const int MPU_addr=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
Wire.begin(SDA, SCL);
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,true); // request a total of 14 registers
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
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);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants