MPU-6000(6050)為全球首例整合性6軸運動處理組件,相較于多組件方案,免除了組合陀螺儀與加速器時間軸之差的問題,減少了大量的封裝空間。
MPU-6000(6050)的角速度全格感測范圍為±250、±500、±1000與±2000°/sec (dps),可準確追蹤快速與慢速動作,并且,用戶可程式控制的加速器全格感測范圍為±2g、±4g±8g與±16g。產品傳輸可透過最高至400kHz的IIC或最高達20MHz的SPI(MPU-6050沒有SPI)。MPU-6000可在不同電壓下工作,VDD供電電壓介為2.5V±5%、3.0V±5%或3.3V±5%,邏輯接口VDDIO供電為1.8V± 5%(MPU6000僅用VDD)。MPU-6000的包裝尺寸4x4x0.9mm(QFN),在業界是革命性的尺寸。其他的特征包含內建的溫度感測器、包含在運作環境中僅有±1%變動的振蕩器。
對問題做個簡單的分析:為什么FIFO數據會溢出?MPU6050的DMP在工作的時候,其實大概的工作過程是mpu6050對陀螺儀和加速度計按照一定的采樣速率進行采樣,對采樣得到的陀螺儀和加速度計數據通過DMP處理后得到姿態角(pitch,roll,yaw),然后存入FIFO中,這個過程在你初始化完DMP后就會不受人為控制的持續進行,那么如果你不及時讀取FIFO的數據,FIFO數據很快就會溢出,那么就會出現以上的問題啦!
好了,說了那么一大堆,問題該如何解決呢? 其實很簡答啦,只要一個簡單循環其實就解決了!看如下的程序:
while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}
就是上面這么一句話,如果讀取失敗,馬上進行第二次讀取,這時候FIFO一般沒有溢出,搞定!(因為檢測到FIFO溢出后會馬上reset一下FIFO)。
最后上一發圖:
int dmp_read_fifo(short *gyro, short *accel, long *quat,
unsigned long *timestamp, short *sensors, unsigned char *more)
{
unsigned char fifo_data[MAX_PACKET_LENGTH];
unsigned char ii = 0;
/* TODO: sensors[0] only changes when dmp_enable_feature is called. We can
* cache this value and save some cycles.
*/
sensors[0] = 0;
/* Get a packet. */
if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more))
return -1;
/* Parse DMP packet. */
if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) {
#ifdef FIFO_CORRUPTION_CHECK
long quat_q14[4], quat_mag_sq;
#endif
quat[0] = ((long)fifo_data[0] 《《 24) | ((long)fifo_data[1] 《《 16) |
((long)fifo_data[2] 《《 8) | fifo_data[3];
quat[1] = ((long)fifo_data[4] 《《 24) | ((long)fifo_data[5] 《《 16) |
((long)fifo_data[6] 《《 8) | fifo_data[7];
quat[2] = ((long)fifo_data[8] 《《 24) | ((long)fifo_data[9] 《《 16) |
((long)fifo_data[10] 《《 8) | fifo_data[11];
quat[3] = ((long)fifo_data[12] 《《 24) | ((long)fifo_data[13] 《《 16) |
((long)fifo_data[14] 《《 8) | fifo_data[15];
ii += 16;
#ifdef FIFO_CORRUPTION_CHECK
/* We can detect a corrupted FIFO by monitoring the quaternion data and
* ensuring that the magnitude is always normalized to one. This
* shouldn‘t happen in normal operation, but if an I2C error occurs,
* the FIFO reads might become misaligned.
*
* Let’s start by scaling down the quaternion data to avoid long long
* math.
*/
quat_q14[0] = quat[0] 》》 16;
quat_q14[1] = quat[1] 》》 16;
quat_q14[2] = quat[2] 》》 16;
quat_q14[3] = quat[3] 》》 16;
quat_mag_sq = quat_q14[0] * quat_q14[0] + quat_q14[1] * quat_q14[1] +
quat_q14[2] * quat_q14[2] + quat_q14[3] * quat_q14[3];
if ((quat_mag_sq 《 QUAT_MAG_SQ_MIN) ||
(quat_mag_sq 》 QUAT_MAG_SQ_MAX)) {
/* Quaternion is outside of the acceptable threshold. */
mpu_reset_fifo();
sensors[0] = 0;
return -1;
}
sensors[0] |= INV_WXYZ_QUAT;
#endif
}
if (dmp.feature_mask & DMP_FEATURE_SEND_RAW_ACCEL) {
accel[0] = ((short)fifo_data[ii+0] 《《 8) | fifo_data[ii+1];
accel[1] = ((short)fifo_data[ii+2] 《《 8) | fifo_data[ii+3];
accel[2] = ((short)fifo_data[ii+4] 《《 8) | fifo_data[ii+5];
ii += 6;
sensors[0] |= INV_XYZ_ACCEL;
}
if (dmp.feature_mask & DMP_FEATURE_SEND_ANY_GYRO) {
gyro[0] = ((short)fifo_data[ii+0] 《《 8) | fifo_data[ii+1];
gyro[1] = ((short)fifo_data[ii+2] 《《 8) | fifo_data[ii+3];
gyro[2] = ((short)fifo_data[ii+4] 《《 8) | fifo_data[ii+5];
ii += 6;
sensors[0] |= INV_XYZ_GYRO;
}
/* Gesture data is at the end of the DMP packet. Parse it and call
* the gesture callbacks (if registered)。
*/
if (dmp.feature_mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT))
decode_gesture(fifo_data + ii);
get_ms(timestamp);
return 0;
}
評論
查看更多