本次将演示九轴传感器模块-MPU9250获取加速度、陀螺仪、地磁数据。
本次使用I2C接口,因此直接把模块的I2C与零知板的I2C引脚对应相连接即可,供电选择3.3v,其他默认。
/* MPU9250 DEMO
POWERED BY lingzhilab.com
*/
#include "quaternionFilters.h"
#include "MPU9250.h"
#define AHRS true
#define SerialDebug true
int intPin = 12;
int myLed = LED_BUILTIN;
MPU9250 myIMU;
void setup()
{
Wire.begin();
Serial.begin(9600);
pinMode(intPin, INPUT);
digitalWrite(intPin, LOW);
pinMode(myLed, OUTPUT);
digitalWrite(myLed, HIGH);
byte c = myIMU.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX);
Serial.print(" I should be "); Serial.println(0x71, HEX);
if (c == 0x71)
{
Serial.println("MPU9250 is online...");
myIMU.MPU9250SelfTest(myIMU.SelfTest);
Serial.print("x-axis self test: acceleration trim within : ");
Serial.print(myIMU.SelfTest[0],1); Serial.println("% of factory value");
Serial.print("y-axis self test: acceleration trim within : ");
Serial.print(myIMU.SelfTest[1],1); Serial.println("% of factory value");
Serial.print("z-axis self test: acceleration trim within : ");
Serial.print(myIMU.SelfTest[2],1); Serial.println("% of factory value");
Serial.print("x-axis self test: gyration trim within : ");
Serial.print(myIMU.SelfTest[3],1); Serial.println("% of factory value");
Serial.print("y-axis self test: gyration trim within : ");
Serial.print(myIMU.SelfTest[4],1); Serial.println("% of factory value");
Serial.print("z-axis self test: gyration trim within : ");
Serial.print(myIMU.SelfTest[5],1); Serial.println("% of factory value");
myIMU.calibrateMPU9250(myIMU.gyroBias, myIMU.accelBias);
myIMU.initMPU9250();
Serial.println("MPU9250 initialized for active data mode....");
byte d = myIMU.readByte(AK8963_ADDRESS, WHO_AM_I_AK8963);
Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX);
Serial.print(" I should be "); Serial.println(0x48, HEX);
myIMU.initAK8963(myIMU.magCalibration);
Serial.println("AK8963 initialized for active data mode....");
if (SerialDebug)
{
// Serial.println("Calibration values: ");
Serial.print("X-Axis sensitivity adjustment value ");
Serial.println(myIMU.magCalibration[0], 2);
Serial.print("Y-Axis sensitivity adjustment value ");
Serial.println(myIMU.magCalibration[1], 2);
Serial.print("Z-Axis sensitivity adjustment value ");
Serial.println(myIMU.magCalibration[2], 2);
}
} // if (c == 0x71)
else
{
Serial.print("Could not connect to MPU9250: 0x");
Serial.println(c, HEX);
while(1) ;
}
}
void loop()
{
if (myIMU.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01)
{
myIMU.readAccelData(myIMU.accelCount);
myIMU.getAres();
myIMU.ax = (float)myIMU.accelCount[0]*myIMU.aRes; // - accelBias[0];
myIMU.ay = (float)myIMU.accelCount[1]*myIMU.aRes; // - accelBias[1];
myIMU.az = (float)myIMU.accelCount[2]*myIMU.aRes; // - accelBias[2];
myIMU.readGyroData(myIMU.gyroCount);
myIMU.getGres();
myIMU.gx = (float)myIMU.gyroCount[0]*myIMU.gRes;
myIMU.gy = (float)myIMU.gyroCount[1]*myIMU.gRes;
myIMU.gz = (float)myIMU.gyroCount[2]*myIMU.gRes;
myIMU.readMagData(myIMU.magCount);
myIMU.getMres();
myIMU.magbias[0] = +470.;
myIMU.magbias[1] = +120.;
myIMU.magbias[2] = +125.;
myIMU.mx = (float)myIMU.magCount[0]*myIMU.mRes*myIMU.magCalibration[0] -
myIMU.magbias[0];
myIMU.my = (float)myIMU.magCount[1]*myIMU.mRes*myIMU.magCalibration[1] -
myIMU.magbias[1];
myIMU.mz = (float)myIMU.magCount[2]*myIMU.mRes*myIMU.magCalibration[2] -
myIMU.magbias[2];
} // if (readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01)
myIMU.updateTime();
// MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f, my, mx, mz);
MahonyQuaternionUpdate(myIMU.ax, myIMU.ay, myIMU.az, myIMU.gx*DEG_TO_RAD,
myIMU.gy*DEG_TO_RAD, myIMU.gz*DEG_TO_RAD, myIMU.my,
myIMU.mx, myIMU.mz, myIMU.deltat);
if (!AHRS)
{
myIMU.delt_t = millis() - myIMU.count;
if (myIMU.delt_t > 500)
{
if(SerialDebug)
{
Serial.print("X-acceleration: "); Serial.print(1000*myIMU.ax);
Serial.print(" mg ");
Serial.print("Y-acceleration: "); Serial.print(1000*myIMU.ay);
Serial.print(" mg ");
Serial.print("Z-acceleration: "); Serial.print(1000*myIMU.az);
Serial.println(" mg ");
Serial.print("X-gyro rate: "); Serial.print(myIMU.gx, 3);
Serial.print(" degrees/sec ");
Serial.print("Y-gyro rate: "); Serial.print(myIMU.gy, 3);
Serial.print(" degrees/sec ");
Serial.print("Z-gyro rate: "); Serial.print(myIMU.gz, 3);
Serial.println(" degrees/sec");
Serial.print("X-mag field: "); Serial.print(myIMU.mx);
Serial.print(" mG ");
Serial.print("Y-mag field: "); Serial.print(myIMU.my);
Serial.print(" mG ");
Serial.print("Z-mag field: "); Serial.print(myIMU.mz);
Serial.println(" mG");
myIMU.tempCount = myIMU.readTempData();
myIMU.temperature = ((float) myIMU.tempCount) / 333.87 + 21.0;
Serial.print("Temperature is "); Serial.print(myIMU.temperature, 1);
Serial.println(" degrees C");
}
myIMU.count = millis();
digitalWrite(myLed, !digitalRead(myLed));
} // if (myIMU.delt_t > 500)
} // if (!AHRS)
else
{
myIMU.delt_t = millis() - myIMU.count;
if (myIMU.delt_t > 500)
{
if(SerialDebug)
{
Serial.print("ax = "); Serial.print((int)1000*myIMU.ax);
Serial.print(" ay = "); Serial.print((int)1000*myIMU.ay);
Serial.print(" az = "); Serial.print((int)1000*myIMU.az);
Serial.println(" mg");
Serial.print("gx = "); Serial.print( myIMU.gx, 2);
Serial.print(" gy = "); Serial.print( myIMU.gy, 2);
Serial.print(" gz = "); Serial.print( myIMU.gz, 2);
Serial.println(" deg/s");
Serial.print("mx = "); Serial.print( (int)myIMU.mx );
Serial.print(" my = "); Serial.print( (int)myIMU.my );
Serial.print(" mz = "); Serial.print( (int)myIMU.mz );
Serial.println(" mG");
Serial.print("q0 = "); Serial.print(*getQ());
Serial.print(" qx = "); Serial.print(*(getQ() + 1));
Serial.print(" qy = "); Serial.print(*(getQ() + 2));
Serial.print(" qz = "); Serial.println(*(getQ() + 3));
}
myIMU.yaw = atan2(2.0f * (*(getQ()+1) * *(getQ()+2) + *getQ() *
*(getQ()+3)), *getQ() * *getQ() + *(getQ()+1) * *(getQ()+1)
- *(getQ()+2) * *(getQ()+2) - *(getQ()+3) * *(getQ()+3));
myIMU.pitch = -asin(2.0f * (*(getQ()+1) * *(getQ()+3) - *getQ() *
*(getQ()+2)));
myIMU.roll = atan2(2.0f * (*getQ() * *(getQ()+1) + *(getQ()+2) *
*(getQ()+3)), *getQ() * *getQ() - *(getQ()+1) * *(getQ()+1)
- *(getQ()+2) * *(getQ()+2) + *(getQ()+3) * *(getQ()+3));
myIMU.pitch *= RAD_TO_DEG;
myIMU.yaw *= RAD_TO_DEG;
myIMU.yaw -= 8.5;
myIMU.roll *= RAD_TO_DEG;
if(SerialDebug)
{
Serial.print("Yaw, Pitch, Roll: ");
Serial.print(myIMU.yaw, 2);
Serial.print(", ");
Serial.print(myIMU.pitch, 2);
Serial.print(", ");
Serial.println(myIMU.roll, 2);
Serial.print("rate = ");
Serial.print((float)myIMU.sumCount/myIMU.sum, 2);
Serial.println(" Hz");
}
myIMU.count = millis();
myIMU.sumCount = 0;
myIMU.sum = 0;
} // if (myIMU.delt_t > 500)
} // if (AHRS)
}
代码上传到零知板,即可看到九轴的数据如下所示: