当前位置:   article > 正文

Qmi8658a姿态传感器使用心得(2)linux

Qmi8658a姿态传感器使用心得(2)linux

1 .COD 原理

COD 支持按需校准陀螺仪的X和Y轴。QMI8658A可以校准陀螺仪的X和Y轴的内部增益,提供更精确的灵敏度和更紧密的灵敏度分布。注意:Z轴不受COD影响。

1.1 运行COD的步骤

  1. 设置CTRL7.aEN = 0 和 CTRL7.gEN = 0 以禁用加速度计和陀螺仪。
  2. 通过CTRL9命令发送CTRL_CMD_ON_DEMAND_CALIBRATION (0xA2)。
  3. 等待大约1.5秒,直到QMI8658A完成CTRL9命令。
  4. 读取COD_STATUS寄存器(0x46)以检查COD执行的结果和状态。

1.2 COD状态

如果COD命令成功执行,COD_STATUS寄存器将输出0x00表示成功。非零值表示不同的失败模式。参阅COD状态寄存器(5.7)的详细信息。

1.3 保存和恢复新的增益参数

在成功运行COD后,新的增益将应用于未来的X和Y轴数据,并将这些参数更新到以下寄存器,供主机读取和保存:

  1. 陀螺仪-X增益 (16 bits) 将存储在dVX_L和dVX_H寄存器 (0x51, 0x52)
  2. 陀螺仪-Y增益 (16 bits) 将存储在dVY_L和dVY_H寄存器 (0x53, 0x54)
  3. 陀螺仪-Z增益 (16 bits) 将存储在dVZ_L和dVZ_H寄存器 (0x55, 0x56)

1.4恢复增益参数

  1. 禁用加速度计和陀螺仪 (设置CTRL7.aEN = 0 和 CTRL7.gEN = 0)。
  2. 将保存的陀螺仪-X增益写入寄存器CAL1_L和CAL1_H (0x0B, 0x0C)。
  3. 将保存的陀螺仪-Y增益写入寄存器CAL2_L和CAL2_H (0x0D, 0x0E)。
  4. 将保存的陀螺仪-Z增益写入寄存器CAL3_L和CAL3_H (0x0F, 0x10)。
  5. 写入0xAA到CTRL9寄存器以执行CTRL_CMD_APPLY_GYRO_GAINS命令。

2. COD状态寄存器

COD_STATUS寄存器地址:0x46

Bits名称默认描述
7X_Limit_L_Fail1’b00: COD通过低灵敏度检查; 1: COD失败
6X_Limit_H_Fail1’b00: COD通过高灵敏度检查; 1: COD失败
5Y_Limit_L_Fail1’b00: COD通过低灵敏度检查; 1: COD失败
4Y_Limit_H_Fail1’b00: COD通过高灵敏度检查; 1: COD失败
3Accel_Check1’b00: 加速度计检查通过; 1: 加速度计检查失败
2Startup_Failed1’b00: 陀螺仪启动成功; 1: 陀螺仪启动失败
1Gyro_Enabled1’b00: COD调用时陀螺仪未启用; 1: COD调用时陀螺仪启用
0COD_Failed1’b00: COD成功; 1: COD失败

3.CTRL9命令列表

CTRL9寄存器地址:0x0A

Command NameCommand ValueProtocol TypeDescription
CTRL_CMD_ACK0x00Ctrl9Host acknowledges to end the protocol
CTRL_CMD_RST_FIFO0x04Ctrl9Reset FIFO from Host
CTRL_CMD_REQ_FIFO0x05Ctrl9RGet FIFO data from Device
CTRL_CMD_WRITE_WOM_SETTING0x08WCtrl9Set up and enable Wake on Motion (WoM)
CTRL_CMD_ACCEL_HOST_DELTA_OFFSET0x09WCtrl9Change accelerometer offset
CTRL_CMD_GYRO_HOST_DELTA_OFFSET0x0AWCtrl9Change gyroscope offset
CTRL_CMD_CONFIGURE_TAP0x0CWCtrl9Configure Tap detection
CTRL_CMD_CONFIGURE_PEDOMETER0x0DWCtrl9Configure Pedometer
CTRL_CMD_CONFIGURE_MOTION0x0EWCtrl9Configure Any Motion / No Motion detection
CTRL_CMD_RESET_PEDOMETER0x0FWCtrl9Reset pedometer count
CTRL_CMD_COPY_USID0x10Ctrl9RCopy USID and FW Version to UI registers
CTRL_CMD_SET_RPU0x11WCtrl9Configures IO pull-ups
CTRL_CMD_AHB_CLOCK_GATING0x12WCtrl9Internal AHB clock gating switch
CTRL_CMD_ON_DEMAND_CALIBRATION0xA2WCtrl9On-Demand Calibration on gyroscope
CTRL_CMD_APPLY_GYRO_GAINS0xAAWCtrl9Restore the saved Gyroscope gains

4.配置方法:

        特别注意:在校准过程中,尽量保持安静,减少环境对于校准结果的干扰;
        并且可以在开发过程中设计循环来实现定期校准的效果。保证陀螺仪的准确
        回复过往的增益参数时要注意变化。

  1. void start_calibration(){
  2. // Disable sensor and set calibration
  3. writeRegister(CTRL7, 0x00); // Disable sensor
  4. writeRegister(CTRL9, 0xA2); // send calibration command
  5. delay(1500); // delay
  6. uint8_t statusInt = readRegister(STATUSINT);
  7. if (statusInt & 0x80) {
  8. // CmdDone is ok
  9. } else {
  10. // CmdDone is fail
  11. }
  12. writeRegister(CTRL9, 0x00); // comfirm calibratino success
  13. uint8_t COD_STATUS = readRegister(0x46);
  14. if (COD_STATUS == 0x00) {
  15. // calibration success
  16. } else {
  17. // calibration fail
  18. }
  19. //update the gain
  20. uint16_t gyroXGain = readRegister(0x51) | (readRegister(0x52) << 8);
  21. uint16_t gyroYGain = readRegister(0x53) | (readRegister(0x54) << 8);
  22. uint16_t gyroZGain = readRegister(0x55) | (readRegister(0x56) << 8);
  23. //save the data and send back to qmi8658a
  24. // Disable sensor and set calibration
  25. writeRegister(CTRL7, 0x00);
  26. // write in gyrox
  27. writeRegister(0x0B, gyroXGain & 0xFF);
  28. writeRegister(0x0C, (gyroXGain >> 8) & 0xFF);
  29. // write in gyroy
  30. writeRegister(0x0D, gyroYGain & 0xFF);
  31. writeRegister(0x0E, (gyroYGain >> 8) & 0xFF);
  32. // write in gytoz
  33. writeRegister(0x0F, gyroZGain & 0xFF);
  34. writeRegister(0x10, (gyroZGain >> 8) & 0xFF);
  35. //send command to CTRL9 and follow the permision
  36. writeRegister(CTRL9, 0xAA); // update the gain

5.自检:

5.1加速度计自检

加速度计自检用于确定加速度计是否工作在可接受的参数范围内。该功能通过对加速度计的 X、Y 和 Z 轴施加静电力,并检测其机械结构响应。以下是实现自检的步骤:

  1. 禁用传感器 (CTRL7 = 0x00)。
  2. 设置适当的加速度计 ODR(CTRL2.aODR)并将 CTRL2.aST(bit7)置 1 以触发自检。
  3. 如果启用 INT2(CTRL1.bit4 = 1),等待 QMI8658A 将 INT2 置高,或 STATUSINT.bit0 置 1。
  4. 将 CTRL2.aST(bit7) 置 0,以清除 STATUSINT1.bit0 和/或 INT2。
  5. 检查 QMI8658A 将 INT2 置低,并将 STATUSINT1.bit0 置 0。
  6. 读取加速度计自检结果:
    • X 轴:dVX_L 和 dVX_H(寄存器 0x51 和 0x52)
    • Y 轴:dVY_L 和 dVY_H(寄存器 0x53 和 0x54)
    • Z 轴:dVZ_L 和 dVZ_H(寄存器 0x55 和 0x56)

如果三个轴的绝对结果均高于 200mg,则加速度计可视为功能正常。否则,视为功能不正常。

5.2陀螺仪自检

陀螺仪自检用于确定陀螺仪是否工作正常。该功能通过对陀螺仪的 X、Y 和 Z 轴施加静电力,并检测其机械结构响应。以下是实现自检的步骤:

  1. 禁用传感器 (CTRL7 = 0x00)。
  2. 将 gST 置 1(CTRL3.bit7 = 1)。
  3. 如果启用 INT2,等待 QMI8658A 将 INT2 置高,或 STATUSINT.bit0 置 1。
  4. 将 CTRL3.aST(bit7) 置 0,以清除 STATUSINT1.bit0 和/或 INT2。
  5. 检查 QMI8658A 将 INT2 置低,或将 STATUSINT1.bit0 置 0。
  6. 读取陀螺仪自检结果:
    • X 轴:dVX_L 和 dVX_H(寄存器 0x51 和 0x52)
    • Y 轴:dVY_L 和 dVY_H(寄存器 0x53 和 0x54)
    • Z 轴:dVZ_L 和 dVZ_H(寄存器 0x55 和 0x56)
  1. // 加速度计自检
  2. void accelerometer_self_test() {
  3. printf("Starting Accelerometer Self-Test...\n");
  4. // 禁用传感器
  5. write_register(CTRL7, 0x00);
  6. // 设置加速度计自检
  7. uint8_t ctrl2_val = read_register(CTRL2);
  8. ctrl2_val |= (1 << 7); // 设置aST位
  9. write_register(CTRL2, ctrl2_val);
  10. // 等待自检完成
  11. while (!(read_register(STATUSINT) & 0x01));
  12. // 读取自检结果
  13. int16_t ax = (int16_t)read_register_16(dVX_L, dVX_H);
  14. int16_t ay = (int16_t)read_register_16(dVY_L, dVY_H);
  15. int16_t az = (int16_t)read_register_16(dVZ_L, dVZ_H);
  16. printf("Accelerometer Self-Test Results:\n");
  17. printf("X: %d mg\n", ax);
  18. printf("Y: %d mg\n", ay);
  19. printf("Z: %d mg\n", az);
  20. // 清除aST位
  21. ctrl2_val &= ~(1 << 7);
  22. write_register(CTRL2, ctrl2_val);
  23. }
  24. // 陀螺仪自检
  25. void gyroscope_self_test() {
  26. printf("Starting Gyroscope Self-Test...\n");
  27. // 禁用传感器
  28. write_register(CTRL7, 0x00);
  29. // 设置陀螺仪自检
  30. uint8_t ctrl3_val = read_register(CTRL3);
  31. ctrl3_val |= (1 << 7); // 设置gST位
  32. write_register(CTRL3, ctrl3_val);
  33. // 等待自检完成
  34. while (!(read_register(STATUSINT) & 0x01));
  35. // 读取自检结果
  36. int16_t gx = (int16_t)read_register_16(dVX_L, dVX_H);
  37. int16_t gy = (int16_t)read_register_16(dVY_L, dVY_H);
  38. int16_t gz = (int16_t)read_register_16(dVZ_L, dVZ_H);
  39. printf("Gyroscope Self-Test Results:\n");
  40. printf("X: %d dps\n", gx);
  41. printf("Y: %d dps\n", gy);
  42. printf("Z: %d dps\n", gz);
  43. // 清除gST位
  44. ctrl3_val &= ~(1 << 7);
  45. write_register(CTRL3, ctrl3_val);
  46. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/864758
推荐阅读
相关标签
  

闽ICP备14008679号