在最近折腾 MPU6050 的时候,尝试使用 Arduino 读取数值,使用Esp32-S3-R8N8
一开始先使用了 Adafruit_MPU6050 库,由于我的Esp32 s3支持自定义I2C,因此与示例有些许不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* Get tilt angles on X and Y, and rotation angle on Z
* Angles are given in degrees
*
* License: MIT
*/

#include "Wire.h"
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>

Adafruit_MPU6050 mpu;
sensors_event_t a, g, temp;
float gyroX, gyroY, gyroZ;
float gyroXerror = 0.07;
float gyroYerror = 0.03;
float gyroZerror = 0.01;
unsigned long lastTime = 0;
unsigned long gyroDelay = 10;

void initMPU()
{
if (!mpu.begin())
{
Serial.println("Failed to find MPU6050 chip");
while (1)
{
delay(10);
}
}
Serial.println("MPU6050 Found!");
}

void getGyroReadings()
{
mpu.getEvent(&a, &g, &temp);

float gyroX_temp = g.gyro.x;
if (abs(gyroX_temp) > gyroXerror)
{
gyroX += gyroX_temp / 50.00;
}

float gyroY_temp = g.gyro.y;
if (abs(gyroY_temp) > gyroYerror)
{
gyroY += gyroY_temp / 70.00;
}

float gyroZ_temp = g.gyro.z;
if (abs(gyroZ_temp) > gyroZerror)
{
gyroZ += gyroZ_temp / 90.00;
}

Serial.print("X: ");
Serial.print(String(gyroX));
Serial.print("\tY: ");
Serial.print(String(gyroY));
Serial.print("\tZ: ");
Serial.print(String(gyroZ));
Serial.print("\n");
}

void setup()
{
Serial.begin(115200);
// 我使用自定义的I2C引脚,SDA9,SCL10
Wire.begin(9, 10);
initMPU();
}

void loop()
{
if ((millis() - lastTime) > gyroDelay)
{
getGyroReadings();
lastTime = millis();
}
}

但是在烧录后运行提示
Failed to find MPU6050 chip

我检查了连线,有这折腾了各种代码,最后看到了 stackoverflow 上有这样一个问题。
Failed to find MPU6050 with ESP32

I found the root of the problem.

solution: Adafruit_MPU6050.h

#define MPU6050_DEVICE_ID 0x68 ///< The correct MPU6050_WHO_AM_I value

this “0x68” must be changed to 0x98

ONLY in this line

NOT here :

#define MPU6050_I2CADDR_DEFAULT
0x68 ///< MPU6050 default i2c address w/ AD0 high

it must stay the same 0x68

In some case the device id may not be 0x98

我尝试修改了,但是依然无法正确的链接,但是这似乎给了我一些Idea。
在Adafruit_MPU6050中,它在链接时会检查MPU6050的ID,如果ID不正确,则无法链接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
bool Adafruit_MPU6050::begin(uint8_t i2c_address, TwoWire *wire,
int32_t sensor_id) {
if (i2c_dev) {
delete i2c_dev; // remove old interface
}

i2c_dev = new Adafruit_I2CDevice(i2c_address, wire);

// For boards with I2C bus power control, may need to delay to allow
// MPU6050 to come up after initial power.
bool mpu_found = false;
for (uint8_t tries = 0; tries < 5; tries++) {
mpu_found = i2c_dev->begin();
if (mpu_found)
break;
delay(10);
}
if (!mpu_found)
return false;
// 读取MPU6050_WHO_AM_I
Adafruit_BusIO_Register chip_id =
Adafruit_BusIO_Register(i2c_dev, MPU6050_WHO_AM_I, 1);
// 检查MPU6050_WHO_AM_I是否等于MPU6050_DEVICE_ID
// make sure we're talking to the right chip
if (chip_id.read() != MPU6050_DEVICE_ID) {
return false;
}

return _init(sensor_id);
}

因此,如果MPU6050的ID不正确,则无法链接。
那么我链接不上是不是因为MPU6050的ID不正确呢?
我参考Arduino论坛上的一个帖子,使用Wire库读取MPU6050的ID。
MPU 6050(A) module problems - WHO_AM_I reports 0x98, not 0x68 as it should. Fake MPU 6050

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void MPU6050_Read(int address,
uint8_t *data) { // Read from MPU6050. Needs register address, data array
int size = sizeof(*data); //
Wire.beginTransmission(MPU6050_I2C_ADDRESS); // Begin talking to MPU6050
Wire.write(address); // Set register address
Wire.endTransmission(false); // Hold the I2C-bus
Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true); // Request bytes, release I2C-bus after data read
int i = 0; //
while (Wire.available()) { //
data[i++] = Wire.read(); // Add data to array
}
}


void WhoAmI() {
uint8_t waiByte; // Data will go here
MPU6050_Read(MPU6050_WHO_AM_I, &waiByte); // Get data
Serial.print(F("Device WhoAmI reports as: 0x")); //
Serial.println(waiByte, HEX); // Report WhoAmI data
}

使用这个函数读取MPU6050的ID,我得到了这样的输出

1
Device WhoAmI reports as: 0x70

0x70? WTF这简直抽象,这似乎是MPU6500的ID。
但是Anyway, 修改了MPU6050_DEVICE_ID后,它总算是工作了

在查了一堆文档之后发现,似乎0x70是MPU6500的ID,而6500已经停产
MPU6500文档
Github上一些用户反馈

最终,给各位避雷下商家
【优信电子】MPU-6050模块三轴加速度+三轴陀螺仪 6DOF模块 GY-521


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
本站总访问量