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 名称 默认 描述
7 X_Limit_L_Fail 1’b0 0: COD通过低灵敏度检查; 1: COD失败
6 X_Limit_H_Fail 1’b0 0: COD通过高灵敏度检查; 1: COD失败
5 Y_Limit_L_Fail 1’b0 0: COD通过低灵敏度检查; 1: COD失败
4 Y_Limit_H_Fail 1’b0 0: COD通过高灵敏度检查; 1: COD失败
3 Accel_Check 1’b0 0: 加速度计检查通过; 1: 加速度计检查失败
2 Startup_Failed 1’b0 0: 陀螺仪启动成功; 1: 陀螺仪启动失败
1 Gyro_Enabled 1’b0 0: COD调用时陀螺仪未启用; 1: COD调用时陀螺仪启用
0 COD_Failed 1’b0 0: COD成功; 1: COD失败

3.CTRL9命令列表

CTRL9寄存器地址:0x0A

Command Name Command Value Protocol Type Description
CTRL_CMD_ACK 0x00 Ctrl9 Host acknowledges to end the protocol
CTRL_CMD_RST_FIFO 0x04 Ctrl9 Reset FIFO from Host
CTRL_CMD_REQ_FIFO 0x05 Ctrl9R Get FIFO data from Device
CTRL_CMD_WRITE_WOM_SETTING 0x08 WCtrl9 Set up and enable Wake on Motion (WoM)
CTRL_CMD_ACCEL_HOST_DELTA_OFFSET 0x09 WCtrl9 Change accelerometer offset
CTRL_CMD_GYRO_HOST_DELTA_OFFSET 0x0A WCtrl9 Change gyroscope offset
CTRL_CMD_CONFIGURE_TAP 0x0C WCtrl9 Configure Tap detection
CTRL_CMD_CONFIGURE_PEDOMETER 0x0D WCtrl9 Configure Pedometer
CTRL_CMD_CONFIGURE_MOTION 0x0E WCtrl9 Configure Any Motion / No Motion detection
CTRL_CMD_RESET_PEDOMETER 0x0F WCtrl9 Reset pedometer count
CTRL_CMD_COPY_USID 0x10 Ctrl9R Copy USID and FW Version to UI registers
CTRL_CMD_SET_RPU 0x11 WCtrl9 Configures IO pull-ups
CTRL_CMD_AHB_CLOCK_GATING 0x12 WCtrl9 Internal AHB clock gating switch
CTRL_CMD_ON_DEMAND_CALIBRATION 0xA2 WCtrl9 On-Demand Calibration on gyroscope
CTRL_CMD_APPLY_GYRO_GAINS 0xAA WCtrl9 Restore the saved Gyroscope gains

4.配置方法:

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

void start_calibration(){
    // Disable sensor and set calibration
    writeRegister(CTRL7, 0x00);  // Disable sensor
    
    writeRegister(CTRL9, 0xA2);  // send calibration command
    
    delay(1500);  // delay
    
    uint8_t statusInt = readRegister(STATUSINT);
    if (statusInt & 0x80) {
        // CmdDone is ok
    } else {
        // CmdDone is fail
    }

    writeRegister(CTRL9, 0x00);  // comfirm calibratino success
    
    uint8_t COD_STATUS = readRegister(0x46);
    if (COD_STATUS == 0x00) {
        // calibration success
    } else {
        // calibration fail
    }
    
    //update the gain 
    uint16_t gyroXGain = readRegister(0x51) | (readRegister(0x52) << 8);
    uint16_t gyroYGain = readRegister(0x53) | (readRegister(0x54) << 8);
    uint16_t gyroZGain = readRegister(0x55) | (readRegister(0x56) << 8);
    
    //save the data and send back to qmi8658a
    // Disable sensor and set calibration
    writeRegister(CTRL7, 0x00);

    // write in gyrox
    writeRegister(0x0B, gyroXGain & 0xFF);
    writeRegister(0x0C, (gyroXGain >> 8) & 0xFF);

    // write in gyroy
    writeRegister(0x0D, gyroYGain & 0xFF);
    writeRegister(0x0E, (gyroYGain >> 8) & 0xFF);

    // write in gytoz
    writeRegister(0x0F, gyroZGain & 0xFF);
    writeRegister(0x10, (gyroZGain >> 8) & 0xFF);

    //send command to CTRL9 and follow the permision
    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)
// 加速度计自检
void accelerometer_self_test() {
    printf("Starting Accelerometer Self-Test...\n");
    
    // 禁用传感器
    write_register(CTRL7, 0x00);

    // 设置加速度计自检
    uint8_t ctrl2_val = read_register(CTRL2);
    ctrl2_val |= (1 << 7); // 设置aST位
    write_register(CTRL2, ctrl2_val);

    // 等待自检完成
    while (!(read_register(STATUSINT) & 0x01));

    // 读取自检结果
    int16_t ax = (int16_t)read_register_16(dVX_L, dVX_H);
    int16_t ay = (int16_t)read_register_16(dVY_L, dVY_H);
    int16_t az = (int16_t)read_register_16(dVZ_L, dVZ_H);

    printf("Accelerometer Self-Test Results:\n");
    printf("X: %d mg\n", ax);
    printf("Y: %d mg\n", ay);
    printf("Z: %d mg\n", az);

    // 清除aST位
    ctrl2_val &= ~(1 << 7);
    write_register(CTRL2, ctrl2_val);
}

// 陀螺仪自检
void gyroscope_self_test() {
    printf("Starting Gyroscope Self-Test...\n");

    // 禁用传感器
    write_register(CTRL7, 0x00);

    // 设置陀螺仪自检
    uint8_t ctrl3_val = read_register(CTRL3);
    ctrl3_val |= (1 << 7); // 设置gST位
    write_register(CTRL3, ctrl3_val);

    // 等待自检完成
    while (!(read_register(STATUSINT) & 0x01));

    // 读取自检结果
    int16_t gx = (int16_t)read_register_16(dVX_L, dVX_H);
    int16_t gy = (int16_t)read_register_16(dVY_L, dVY_H);
    int16_t gz = (int16_t)read_register_16(dVZ_L, dVZ_H);

    printf("Gyroscope Self-Test Results:\n");
    printf("X: %d dps\n", gx);
    printf("Y: %d dps\n", gy);
    printf("Z: %d dps\n", gz);

    // 清除gST位
    ctrl3_val &= ~(1 << 7);
    write_register(CTRL3, ctrl3_val);
}

相关推荐

  1. Qmi8658a姿态传感器使用心得2linux

    2024-07-20 15:58:01       18 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 15:58:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 15:58:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 15:58:01       45 阅读
  4. Python语言-面向对象

    2024-07-20 15:58:01       55 阅读

热门阅读

  1. springcloud与dubbo的rpc通信都是分别基于什么实现的

    2024-07-20 15:58:01       16 阅读
  2. AI论文写作软件哪些比较好用?

    2024-07-20 15:58:01       17 阅读
  3. vue-treeselect

    2024-07-20 15:58:01       22 阅读
  4. 反悔贪心

    2024-07-20 15:58:01       19 阅读
  5. 我们的耳穴项目迈进了一大步

    2024-07-20 15:58:01       21 阅读
  6. 【前后端联调】HttpMessageNotReadableException

    2024-07-20 15:58:01       19 阅读
  7. 恒等式结论

    2024-07-20 15:58:01       15 阅读
  8. Https post 请求时绕过证书验证方案

    2024-07-20 15:58:01       20 阅读
  9. 素数极差

    2024-07-20 15:58:01       15 阅读
  10. 数据结构——栈

    2024-07-20 15:58:01       17 阅读