C语言 带ESP 32的MPU 9250-无法读取磁力计

soat7uwm  于 2023-04-11  发布在  其他
关注(0)|答案(1)|浏览(313)

我试图从MPU9250读取数据。加速度计和陀螺仪读数正常。但我无法从磁力计成功读取任何数据。查看数据表,一切看起来都是为了有关设置。
ST1磁力计寄存器也未读取。每次调用磁力计的I2Cread函数时,调试打印Serial.print("Wire available: "); Serial.println(Wire.available());打印0(据我所知,这意味着没有任何可用的字节可供读取)。任何建议或帮助都非常感谢。提前感谢。
下面是我的代码:

#include <Wire.h>
#include <Arduino.h>

#define MPU9250_ADDRESS 0x68
#define MAG_ADDRESS 0x0C

#define GYRO_FULL_SCALE_250_DPS 0x00
#define GYRO_FULL_SCALE_500_DPS 0x08
#define GYRO_FULL_SCALE_1000_DPS 0x10
#define GYRO_FULL_SCALE_2000_DPS 0x18

#define ACC_FULL_SCALE_2_G 0x00
#define ACC_FULL_SCALE_4_G 0x08
#define ACC_FULL_SCALE_8_G 0x10
#define ACC_FULL_SCALE_16_G 0x18

void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
{
  Wire.beginTransmission(Address);
  Wire.write(Register);
  Wire.endTransmission();

  Wire.requestFrom(Address, Nbytes);
  uint8_t index = 0;
  Serial.print("Wire available: ");
  Serial.println(Wire.available());

  while (Wire.available())
  {
    Serial.println("Data array data:");
    Data[index++] = Wire.read();
    Serial.print(index-1);
    Serial.print("\t");
    Serial.println(Data[index-1]);
  }
}

void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
{
  Wire.beginTransmission(Address);
  Wire.write(Register);
  Wire.write(Data);
  Wire.endTransmission();
}

void setup()
{
  Wire.begin();
  Serial.begin(115200);

  I2CwriteByte(MPU9250_ADDRESS, 28, ACC_FULL_SCALE_16_G);

  I2CwriteByte(MPU9250_ADDRESS, 27, GYRO_FULL_SCALE_2000_DPS);

  // enable mag sensor bypass
  I2CwriteByte(MPU9250_ADDRESS, 0x37, 0x22);

  I2CwriteByte(MAG_ADDRESS, 0x0A, 0x01);
  delay(20);
  //I2CwriteByte(MAG_ADDRESS, 0x0A, 0x00);
}

void loop()
{
  uint8_t Buf[14];
  I2Cread(MPU9250_ADDRESS, 0x3B, 14, Buf);

  int16_t ax = -(Buf[0] << 8 | Buf[1]);
  int16_t ay = -(Buf[2] << 8 | Buf[3]);
  int16_t az = Buf[4] << 8 | Buf[5];

  int16_t gx = -(Buf[8] << 8 | Buf[9]);
  int16_t gy = -(Buf[10] << 8 | Buf[11]);
  int16_t gz = Buf[12] << 8 | Buf[13];

  uint8_t ST1;
  //I2CwriteByte(MAG_ADDRESS, 0x0A, 0x01);
  delay(20);
  do
  {
    I2Cread(MAG_ADDRESS, 0x02, 1, &ST1); // not read, 0 bytes available in read
    Serial.print("ST1: "); 
    Serial.println(ST1);
  } 
  while (!(ST1 & 0x01));

  uint8_t Mag[7];
  I2Cread(MAG_ADDRESS, 0x03, 7, Mag);
  //I2CwriteByte(MAG_ADDRESS, 0x0A, 0x00);
  Serial.println("Mag array data:");
  for (size_t i = 0; i < 7; i++)
  {
    Serial.print(i);
    Serial.print("\t");
    Serial.println(Mag[i]);
  }
  

  int16_t mx = -(Mag[3] << 8 | Mag[2]);
  int16_t my = -(Mag[1] << 8 | Mag[0]);
  int16_t mz = -(Mag[5] << 8 | Mag[4]);

  Serial.print(ax, DEC);
  Serial.print("\t");
  Serial.print(ay, DEC);
  Serial.print("\t");
  Serial.print(az, DEC);
  Serial.print("\t");

  Serial.print(gx, DEC);
  Serial.print("\t");
  Serial.print(gy, DEC);
  Serial.print("\t");
  Serial.print(gz, DEC);
  Serial.print("\t");

  Serial.print(mx + 200, DEC);
  Serial.print("\t");
  Serial.print(my - 70, DEC);
  Serial.print("\t");
  Serial.print(mz - 700, DEC);
  Serial.print("\t");

  Serial.println("");

  delay(500);
}
dojqjjoe

dojqjjoe1#

如果您查看MPU9250 datasheet第21页的框图,可以看到罗盘ADC通过辅助i2c总线连接,并通过旁路多路复用器进行配置。为了读取罗盘数据,您需要配置registers(寄存器37,可能还有其他寄存器)以使能旁路模式,以便可以在连接到主机的主i2c总线上访问数据。
如果你不知道如何使它工作,看看一个开发良好的MPU9050库,看看他们是如何做到这一点,或干脆使用一个现成的开发库。

相关问题