搜索
bottom↓
回复: 4

MPU9150 DMP AK8975电子罗盘

[复制链接]

出0入0汤圆

发表于 2015-12-27 15:16:59 | 显示全部楼层 |阅读模式
本帖最后由 yshihyu 于 2015-12-27 22:54 编辑

MPU9150 DMP , 我在 6050使用DMP 可以取得精确度 pitch and roll angle , 只是 yaw angle 有问题, 所以需要 magnetometer 修正 yaw angle , 所以我想使用 MPU9150 gyroscope accelerometer magnetometer 让 DMP 整合计算出来
mpu9150test.ino 里面 loop 函数里面
mpu.dmpGetMag(mag, fifoBuffer);
取出来 mag都是0


MPU9150_9Axis_MotionApps41.h 跟 dmp 有关
里面的 dmpInitialize 函数跟 magnetometer 有关系的函数是下面几段程式码 ,


  1. uint8_t dmpInitialize() {
  2.     DEBUG_PRINTLN(F("Setting magnetometer mode to power-down..."));
  3. //mag -> setMode(0);
  4.     I2Cdev::writeByte(0x0E, 0x0A, 0x00);
  5.     DEBUG_PRINTLN(F("Setting magnetometer mode to fuse access..."));
  6. //mag -> setMode(0x0F);
  7.     I2Cdev::writeByte(0x0E, 0x0A, 0x0F);
  8.     DEBUG_PRINTLN(F("Reading mag magnetometer factory calibration..."));
  9.     int8_t asax, asay, asaz;
  10. //mag -> getAdjustment(&asax, &asay, &asaz);
  11.     DEBUG_PRINTLN(F("Setting magnetometer mode to power-down..."));
  12. //mag -> setMode(0);
  13.     DEBUG_PRINTLN(F("Setting AK8975 to single measurement mode..."));
  14. //mag -> setMode(1);
  15.     I2Cdev::writeByte(0x0E, 0x0A, 0x01);
  16. }
复制代码



但是 MPU9150.cpp 使用 magnetometer 使用getMotion9函数取raw data可以取到 , 而里面的 MPU9150_RA_MAG_ADDRESS是 0x0C 跟DMP 使用的 0x0E 为什么不同? 我有试过把 0x0E 改成 0x0C 不过DMP 还是得不到 magnetometer 资料


  1. void MPU9150::getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz) {
  2. //get accel and gyro
  3.     getMotion6(ax, ay, az, gx, gy, gz);
  4. //read mag
  5.     I2Cdev::writeByte(devAddr, MPU9150_RA_INT_PIN_CFG, 0x02); //set i2c bypass enable pin to true to access magnetometer
  6.     delay(10);
  7.     I2Cdev::writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
  8.     delay(10);
  9.     I2Cdev::readBytes(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, 6, buffer);
  10.     *mx = (((int16_t)buffer[0]) << 8) | buffer[1];
  11.     *my = (((int16_t)buffer[2]) << 8) | buffer[3];
  12.     *mz = (((int16_t)buffer[4]) << 8) | buffer[5];
  13. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2015-12-27 21:29:31 | 显示全部楼层
lz,能否把源码打包一下上传?官方的可以下载到的代码里没有看到过你上面代码的内容

出0入0汤圆

 楼主| 发表于 2015-12-27 22:54:50 | 显示全部楼层
本帖最后由 yshihyu 于 2015-12-27 23:25 编辑

源码打包了by Jeff Rowberg <jeff@rowberg.net>这作者应该不是官方的代码

出0入0汤圆

 楼主| 发表于 2015-12-27 23:18:10 | 显示全部楼层
本帖最后由 yshihyu 于 2015-12-27 23:26 编辑

MPU9150Lib 后来我官方有找到下面代码 ,

void dataFusion();                                        // fuse mag data with the dmp quaternion

这样代表 dmp 没有把mag data真正作到硬件?  


我没权限可以贴网址所以贴关键代码


  1. boolean MPU9150Lib::read()
  2. {
  3.     short intStatus;
  4.     int result;
  5.     short sensors;
  6.     unsigned char more;
  7.     unsigned long timestamp;
  8.    
  9.     mpu_get_int_status(&intStatus);                       // get the current MPU state
  10.     if ((intStatus & MPU_INT_STATUS_DMP_0) == 0)          // return false if definitely not ready yet
  11.         return false;
  12.         
  13.     //  get the data from the fifo
  14.         
  15.     if ((result = dmp_read_fifo(m_rawGyro, m_rawAccel, m_rawQuaternion, &timestamp, &sensors, &more)) != 0) {
  16.       return false;
  17.     }      
  18.    
  19.     //  got the fifo data so now get the mag data
  20.    
  21.     if ((result = mpu_get_compass_reg(m_rawMag, &timestamp)) != 0) {
  22. #ifdef MPULIB_DEBUG
  23.          Serial.print("Failed to read compass: ");
  24.          Serial.println(result);
  25.          return false;
  26. #endif
  27.     }
  28.    
  29.     // got the raw data - now process
  30.    
  31.     m_dmpQuaternion[QUAT_W] = (float)m_rawQuaternion[QUAT_W];  // get float version of quaternion
  32.     m_dmpQuaternion[QUAT_X] = (float)m_rawQuaternion[QUAT_X];
  33.     m_dmpQuaternion[QUAT_Y] = (float)m_rawQuaternion[QUAT_Y];
  34.     m_dmpQuaternion[QUAT_Z] = (float)m_rawQuaternion[QUAT_Z];
  35.     MPUQuaternionNormalize(m_dmpQuaternion);                 // and normalize
  36.    
  37.     MPUQuaternionQuaternionToEuler(m_dmpQuaternion, m_dmpEulerPose);

  38.         //        *** Note mag axes are changed here to align with gyros: Y = -X, X = Y

  39.     if (m_useMagCalibration) {
  40.       m_calMag[VEC3_Y] = -(short)(((long)(m_rawMag[VEC3_X] - m_magXOffset) * (long)SENSOR_RANGE) / (long)m_magXRange);
  41.       m_calMag[VEC3_X] = (short)(((long)(m_rawMag[VEC3_Y] - m_magYOffset) * (long)SENSOR_RANGE) / (long)m_magYRange);
  42.       m_calMag[VEC3_Z] = (short)(((long)(m_rawMag[VEC3_Z] - m_magZOffset) * (long)SENSOR_RANGE) / (long)m_magZRange);
  43.     } else {
  44.       m_calMag[VEC3_Y] = -m_rawMag[VEC3_X];
  45.       m_calMag[VEC3_X] = m_rawMag[VEC3_Y];
  46.       m_calMag[VEC3_Z] = m_rawMag[VEC3_Z];
  47.     }

  48.     // Scale accel data

  49.     if (m_useAccelCalibration) {
  50.       m_calAccel[VEC3_X] = -(short)(((long)m_rawAccel[VEC3_X] * (long)SENSOR_RANGE) / (long)m_accelXRange);
  51.       m_calAccel[VEC3_Y] = (short)(((long)m_rawAccel[VEC3_Y] * (long)SENSOR_RANGE) / (long)m_accelYRange);
  52.       m_calAccel[VEC3_Z] = (short)(((long)m_rawAccel[VEC3_Z] * (long)SENSOR_RANGE) / (long)m_accelZRange);
  53.     } else {
  54.       m_calAccel[VEC3_X] = -m_rawAccel[VEC3_X];
  55.       m_calAccel[VEC3_Y] = m_rawAccel[VEC3_Y];
  56.       m_calAccel[VEC3_Z] = m_rawAccel[VEC3_Z];
  57.     }
  58.     dataFusion();
  59.     return true;
  60. }

  61. void MPU9150Lib::dataFusion()
  62. {
  63.   float qMag[4];
  64.   float deltaDMPYaw, deltaMagYaw;
  65.   float newMagYaw, newYaw;
  66.   float temp1[4], unFused[4];
  67.   float unFusedConjugate[4];

  68.   // *** NOTE *** pitch direction swapped here

  69.   m_fusedEulerPose[VEC3_X] = m_dmpEulerPose[VEC3_X];
  70.   m_fusedEulerPose[VEC3_Y] = -m_dmpEulerPose[VEC3_Y];
  71.   m_fusedEulerPose[VEC3_Z] = 0;       
  72.   MPUQuaternionEulerToQuaternion(m_fusedEulerPose, unFused);    // create a new quaternion

  73.   deltaDMPYaw = -m_dmpEulerPose[VEC3_Z] + m_lastDMPYaw;         // calculate change in yaw from dmp
  74.   m_lastDMPYaw = m_dmpEulerPose[VEC3_Z];                        // update that

  75.   qMag[QUAT_W] = 0;
  76.   qMag[QUAT_X] = m_calMag[VEC3_X];
  77.   qMag[QUAT_Y] = m_calMag[VEC3_Y];
  78.   qMag[QUAT_Z] = m_calMag[VEC3_Z];
  79.        
  80.   // Tilt compensate mag with the unfused data (i.e. just roll and pitch with yaw 0)
  81.        
  82.   MPUQuaternionConjugate(unFused, unFusedConjugate);
  83.   MPUQuaternionMultiply(qMag, unFusedConjugate, temp1);
  84.   MPUQuaternionMultiply(unFused, temp1, qMag);

  85.   // Now fuse this with the dmp yaw gyro information

  86.   newMagYaw = -atan2(qMag[QUAT_Y], qMag[QUAT_X]);

  87.   if (newMagYaw != newMagYaw) {                                 // check for nAn
  88. #ifdef MPULIB_DEBUG
  89.     Serial.println("***nAn\n");
  90. #endif
  91.     return;                                                     // just ignore in this case
  92.   }
  93.   if (newMagYaw < 0)
  94.     newMagYaw = 2.0f * (float)M_PI + newMagYaw;                 // need 0 <= newMagYaw <= 2*PI

  95.   newYaw = m_lastYaw + deltaDMPYaw;                             // compute new yaw from change
  96.   if (newYaw > (2.0f * (float)M_PI))                            // need 0 <= newYaw <= 2*PI
  97.     newYaw -= 2.0f * (float)M_PI;
  98.   if (newYaw < 0)
  99.     newYaw += 2.0f * (float)M_PI;

  100.   deltaMagYaw = newMagYaw - newYaw;                             // compute difference
  101.   if (deltaMagYaw >= (float)M_PI)
  102.     deltaMagYaw = deltaMagYaw - 2.0f * (float)M_PI;
  103.   if (deltaMagYaw <= -(float)M_PI)
  104.     deltaMagYaw = (2.0f * (float)M_PI + deltaMagYaw);

  105.   newYaw += deltaMagYaw/4;                                      // apply some of the correction

  106.   if (newYaw > (2.0f * (float)M_PI))                                            // need 0 <= newYaw <= 2*PI
  107.     newYaw -= 2.0f * (float)M_PI;
  108.   if (newYaw < 0)
  109.     newYaw += 2.0f * (float)M_PI;

  110.   m_lastYaw = newYaw;

  111.   if (newYaw > (float)M_PI)
  112.     newYaw -= 2.0f * (float)M_PI;

  113.   m_fusedEulerPose[VEC3_Z] = newYaw;                            // fill in output yaw value
  114.        
  115.   MPUQuaternionEulerToQuaternion(m_fusedEulerPose, m_fusedQuaternion);
  116. }
复制代码

出0入0汤圆

发表于 2016-3-14 10:03:58 | 显示全部楼层
我没用DMP,自己从MPU9250里面读取AK8963的数据,因为我是用的SPI接口,所有也不能直接读取AK8963,因为AK8963是通过6500的IIC下挂的,所有要使用MPU9250内部的SLV4(从机配置4)来读取写入AK8963寄存器,用SLV0来循环读取AK8963的数据。先前就要配置好SLV0 和SLV4,,,楼主应该找找他是如何配置的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 11:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表