打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
I2C通信之加速度计、陀螺仪、磁强计(345+3205+5883)
       之前简单写了陀螺仪传感器ITG3205加速度传感器ADXL345 的相关帖子。现在把这两种传感器和HMC5883L磁强计放在一起,使用I2C与Arduino通信,读出这三种传感器的原始数据。没有加入滤波算法,没有额外库文件。方便大家对I2C通信、几种常见惯性传感器初步配置进行学习、交流~
IDE环境:Arduino1.0.5      I2C速率 :100Kbps
ARDUINO 代码
                        
  1. #include <Wire.h>
  2. #define Acc_address   0x53      //ADXL345的I2C地址(ADDR接地)
  3. #define Gyr_address   0x68      //ITG3205的I2C地址(AD0接地)
  4. #define HMCAddress    0x1E      //HMC5883L的I2C地址

  5. #define A_DATA_FORMAT 0x31      //Acc设置量程、分辨率的寄存器
  6. #define A_BW_RATE     0x2C      //Acc设置输出数据速率和功率模式的寄存器
  7. #define A_POWER_CTL   0x2D      //Acc设置测量模式的寄存器

  8. #define G_SMPLRT_DIV  0x15      // Gyr设置采样率的寄存器
  9. #define G_DLPF_FS     0x16      // Gyr设置量程、低通滤波带宽、时钟频率的寄存器
  10. #define G_INT_CFG     0x17      // Gyr设置中断的寄存器
  11. #define G_PWR_MGM     0x3E      // Gyr设置电源管理的寄存器

  12. #define ConfigurationRegisterA 0x00  //Mag配置寄存器A
  13. #define ConfigurationRegisterB 0x01  //Mag配置寄存器B
  14. #define ModeRegister 0x02            //Mag模式寄存器


  15. int xAcc,  yAcc,  zAcc;         //存放加速度值
  16. int xGyro, yGyro, zGyro;        //存放角速度值
  17. int xMag,  yMag,  zMag;         // 存放地磁场值

  18. int buff[6];                    //存放寄存器高低位值,X、Y、Z轴共6个

  19. // 加速度传感器误差修正的偏移量
  20. int a_offx = -2;
  21. int a_offy = -3;
  22. int a_offz =10;

  23. // 陀螺仪传感器误差修正的偏移量
  24. int g_offx = 83;
  25. int g_offy = 27;
  26. int g_offz = 17;

  27. // 磁强计椭圆校正的偏移量
  28. int m_offx=-45;
  29. int m_offy=-98;
  30. int m_offz= 75;

  31. void writeRegister(int deviceAddress, byte address, byte val)
  32. {
  33.    Wire.beginTransmission(deviceAddress);
  34.    Wire.write(address);      
  35.    Wire.write(val);        
  36.    Wire.endTransmission();
  37. }

  38. void readRegister(int deviceAddress, byte address)
  39. {
  40.   Wire.beginTransmission(deviceAddress);  
  41.   Wire.write(address);        
  42.   Wire.endTransmission();
  43.   Wire.beginTransmission(deviceAddress);
  44.   Wire.requestFrom(deviceAddress, 6);   

  45.   int i = 0;
  46.   while(Wire.available())   
  47.   {  buff[i++] = Wire.read();  }
  48.   Wire.endTransmission();
  49. }

  50. void initAcc()
  51. {
  52.   /*****************************************
  53.    * ADXL345
  54.    * A_DATA_FORMAT:量程=+-2g,10位分辨率 3.9 LSB/mg
  55.    * A_BW_RATE: 输出数据速率50Hz,带宽25Hz
  56.    * A_POWER_CTL:测量模式
  57.    ******************************************/
  58.   writeRegister (Acc_address, A_DATA_FORMAT, 0x00);
  59.   writeRegister (Acc_address, A_BW_RATE, 0x09);
  60.   writeRegister (Acc_address, A_POWER_CTL, 0x08);  
  61. }

  62. void getAccData()
  63. {
  64.   readRegister(Acc_address, 0x32);  
  65.   xAcc = ((buff[1] << 8) | buff[0] )+ a_offx;   
  66.   yAcc = ((buff[3] << 8) | buff[2] )+ a_offy;
  67.   zAcc = ((buff[5] << 8) | buff[4]) + a_offz;
  68. }

  69. void initGyro()
  70. {
  71.   /*****************************************
  72.    * ITG3205     分辨率  14.375 LSB 度/秒
  73.    * G_SMPLRT_DIV:采样率 = 125Hz
  74.    * G_DLPF_FS:+ - 2000度/秒、低通滤波器5HZ、内部采样率1kHz
  75.    * G_INT_CFG:没有中断
  76.    * G_PWR_MGM:电源管理设定:无复位、无睡眠模式、无待机模式、内部振荡器
  77.    ******************************************/
  78.   writeRegister(Gyr_address, G_SMPLRT_DIV, 0x07); //设置采样率
  79.   writeRegister(Gyr_address, G_DLPF_FS, 0x1E); //设置量程、低通滤波、内部采样率
  80.   writeRegister(Gyr_address, G_INT_CFG, 0x00); //设置中断(默认值)
  81.   writeRegister(Gyr_address, G_PWR_MGM, 0x00);    //设置电源管理(默认值)
  82. }

  83. void getGyroValues()
  84. {
  85.   readRegister(Gyr_address, 0x1D); //读取陀螺仪ITG3205的数据
  86.   xGyro = ((buff[0] << 8) | buff[1]) + g_offx;
  87.   yGyro = ((buff[2] << 8) | buff[3]) + g_offy;
  88.   zGyro = ((buff[4] << 8) | buff[5]) + g_offz;
  89. }

  90. void initMagn()
  91. {  /*****************************************
  92.    * HMC5883L
  93.    * ModeRegister:连续测量模式
  94.    * ConfigurationRegisterA:输出数据速率15Hz、内部采样8次平均、正常测量配置
  95.    * ConfigurationRegisterB:磁场范围=+-1.3Ga、1090 LSB/Gauss
  96.    ******************************************/
  97.   writeRegister(HMCAddress, ModeRegister, 0x00);
  98.   writeRegister(HMCAddress, ConfigurationRegisterA, 0x70);
  99.   writeRegister(HMCAddress, ConfigurationRegisterB, 0x20);
  100. }

  101. void getMagnValues()
  102. {
  103.   readRegister(HMCAddress, 0x03); //读取磁强计HMC5883L的数据
  104.   xMag = ((buff[0] << 8) | buff[1] ) +m_offx ;
  105.   zMag = (( buff[2] << 8) | buff[3] ) +m_offz;
  106.   yMag = (( buff[4] << 8) | buff[5] )+m_offy ;
  107. }

  108. void setup()
  109. {
  110.   Serial.begin(9600);
  111.   Wire.begin();
  112.   initAcc();
  113.   initGyro();
  114.   initMagn();
  115.   delay(50);
  116. }

  117. void loop()
  118. {
  119.     getAccData();
  120.     Serial.print("xAcc=");
  121.     Serial.print(xAcc);
  122.     Serial.print("  yAcc=");
  123.     Serial.print(yAcc);
  124.     Serial.print("  zAcc=");
  125.     Serial.println(zAcc);

  126.     getGyroValues();
  127.     Serial.print("xGyro=");
  128.     Serial.print(xGyro);
  129.     Serial.print("  yGyro=");
  130.     Serial.print(yGyro);
  131.     Serial.print("  zGyro=");
  132.     Serial.println(zGyro);

  133.     getMagnValues();
  134.     Serial.print("xMag=");
  135.     Serial.print(xMag);
  136.     Serial.print("  yMag=");
  137.     Serial.print(yMag);
  138.     Serial.print("  zMag=");
  139.     Serial.println(zMag);
  140.     delay(200);
  141. }




       看到这里,大家或许会去把这些原始数据转换成对应的物理量,没关系,请参考Malc童鞋的:加速度计和陀螺仪指南。如果希望滤波,以便得到更准确的姿态角,请参考黑马前辈的:我的自平衡小车D3和笨笨童鞋的:Arduino+MPU6050+Kalman filter。 需要注意的是帖子中的kalman滤波算法只能对水平面姿态角之一:Pitch或者Roll正确滤波(欧拉角微分方程简化形式:yaw=0&&pitch=0||roll=0)。如果打算使用全姿态欧拉角,推荐用四元数法,再采用卡尔曼滤波估计最优的全姿态角。当然,还是推荐互补滤波算法解决这类问题。






本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
重力加速度陀螺仪传感器MPU
超详细陀螺仪MPU6050模块输出姿态角(有完整版源码)
如何使用STM32F1/F4驱动CS5463
ADXL345基本介绍
LoRa协议在Arduino上的应用——原理及代码分析(一)
圆点博士——代码注释——初版——来自波波——attitude.c
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服