三轴加速度计LIS2DUX12开发(2)----静态校准

描述

概述

最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:615061293 。

零偏是影响加速度计输出精度的重要指标之一,零偏可分为静态零偏和动态零偏 。静态零偏也称为固定零偏,通常经标定与补偿减小静态零偏。动态零偏是由于加速度计自身的缺陷或环境因素(如温度、振动、电子干扰等)引起的,悬丝加速度计在运动过程中其精度会受到动态零偏的影响,因此在投入使用前要先对加速度计的动态零偏进行测试。

stm32cubemx

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。 主控为STM32U073CC,加速度计为LIS2DUX12

stm32cubemx

视频教学

[https://www.bilibili.com/video/BV17J4m1W7Fb/]

样品申请

[https://www.wjx.top/vm/OhcKxJk.aspx#]

源码下载

[https://download.csdn.net/download/qq_24312945/89197967]

六位置法的标定方案

本文在校准三轴加速度计时使用六位置校准法,该方法使用地球的重力力加速度在静态下校准三轴加速度传感器,具体的校准过程如下图所示。具体校准过程如下:

  1. 将传感器的Y轴垂直水平面向下;
  2. 以X轴为基准轴,绕其逆旋转90°,使乙轴垂直水平面向上
  3. 以Y轴为基准轴,绕其逆旋转90°,使X轴垂直水平面向下
  4. 以Y轴为基准轴,绕其逆时针旋转90°使2轴垂直水平面向下
  5. 绕Y轴逆时针旋转909、使X轴垂直水平面向上
  6. 绕Z轴顺时针旋转90°、使Y轴垂直水平面向上

stm32cubemx

在没有精密设备的情况下。这种方法基本上是在试图找到每个轴的偏移(zero-g offset)和灵敏度(scale factor)。这种方法通常称为静态校准方法,因为它不需要动态输入,只需将设备置于静态的已知方向即可。

旋转加速度计以找到极值

将加速度计沿每个轴正向和反向对齐,使其尽可能地与地球重力向量对齐。在理想情况下,当某一轴完全与地球的重力向量对齐时,该轴应显示约 ±1g 的读数,而其他轴应显示 0g。

记录每个轴在这六个方向(X+, X-, Y+, Y-, Z+, Z-)的输出,即每个轴的最大值和最小值。

在未校准情况下,读出的数据会超过1g的数值,所以要进行加速度计校准。

stm32cubemx

计算偏移和灵敏度

偏移(Offset):可以通过计算每个轴最大值和最小值的平均值得到:

Offset=(Max value+Min value)/2

灵敏度(Scale factor):可以通过两个极值之差与2g(因为从+1g到-1g的总变化是2g)的比例来计算:

Scale factor=(Max value-Min value)/2g

应用校准参数

一旦计算得到每个轴的偏移量和灵敏度,校准参数就可以应用到新的加速度计测量数据中以修正这些数据。修正后的加速度值由下列公式计算得出:

Calibrated value= (Raw value−Offset)/Scale Factor

这个步骤实质上是一个线性变换,它调整原始加速度读数以反映真实的加速度。

这些算法步骤基于直接的数学操作,并不涉及复杂的统计算法或优化算法。这些方法足以处理大多数基本应用场景下的加速度计校准需求,尤其是在资源受限的嵌入式系统中。如果环境变化大或加速度计的非理想特性影响较大(如高温、机械应力等),可能需要更复杂的算法来进行动态校准或更高级的误差补偿。

注意事项

  1. 确保在静态环境中进行测试,避免任何震动或移动。
  2. 使用精确的水平仪确保加速度计的对齐。
  3. 可以通过多次测量和取平均值来增加校准的准确性。 这种校准方法相对简单,适合大多数基本应用,但对于需要极高精度的应用,可能需要更复杂的校准技术和专业设备。

串口中断

开启串口中断来接收数据。

stm32cubemx

要在主程序钟开启中断接收。

HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //打开串口中断接收

定义接收函数。

// 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
{

    Rx_flag=RxBuff[0];   
    RxBuff[0]=0;
//    printf("flag=%d",Rx_flag);
    HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //每接收一个数据,就打开一次串口中断接收,否则只会接收一个数据就停止接收

}

变量定义

data_accx_min, data_accx_max, data_accy_min, data_accy_max, data_accz_min, data_accz_max:这些变量存储加速度计在X、Y、Z轴上的最小值和最大值。这些极值通常是通过在特定时间内收集加速度计数据,然后从这些数据中找出最小值和最大值得到的。
Offset_x, Offset_y, Offset_z:这些是各轴的偏移值,计算方法是各轴最大值和最小值的算术平均值。偏移值用于调整每个轴的零点位置,使其在没有运动时接近零。
Scale_factor_x, Scale_factor_y, Scale_factor_z:这些是各轴的灵敏度系数,计算方法是各轴最大值和最小值的差除以2。这个系数用于调整每个轴的测量值,使其在已知加速度的情况下反映实际的物理加速度。
calibrated_x, calibrated_y, calibrated_z:这些变量用于存储校准后的加速度值,校准的目的是确保加速度计输出准确反映实际加速度。
校准参数计算函数 calculate_calibration_params,此函数执行以下操作:
计算偏移(Offset):通过取每个轴的最大值和最小值的平均值来计算偏移。这样做是为了将未校准的加速度计读数的中心调整到0点附近,以补偿传感器的系统偏差。
计算灵敏度(Scale factor):通过取每个轴的最大值和最小值之差的一半来计算灵敏度。这个值表示了在理想条件下,传感器输出从最小到最大应覆盖的理想范围(通常是±1g)。通过这种方式,您可以根据实际的传感器响应调整加速度计的读数。

float data_accx_min=0,data_accx_max=0;//加速度计x轴极值
float data_accy_min=0,data_accy_max=0;//加速度计y轴极值
float data_accz_min=0,data_accz_max=0;//加速度计z轴极值

float Offset_x=0.0f;//x偏移
float Scale_factor_x=0.0f;//x灵敏度
float Offset_y=0.0f;//y偏移
float Scale_factor_y=0.0f;//y灵敏度
float Offset_z=0.0f;//z偏移
float Scale_factor_z=0.0f;//z灵敏度

float calibrated_x=0.0f;//校准后加速度计x轴值
float calibrated_y=0.0f;//校准后加速度计y轴值
float calibrated_z=0.0f;//校准后加速度计z轴值

int acc_i=0;

uint8_t RxBuff[1];      //进入中断接收数据的数组
int Rx_flag=0;                    //接受到数据标志


void calculate_calibration_params(void) {

    Offset_x=(data_accx_max+data_accx_min)/2;
    Offset_y=(data_accy_max+data_accy_min)/2;            
    Offset_z=(data_accz_max+data_accz_min)/2;        


    Scale_factor_x=(data_accx_max-data_accx_min)/2;
    Scale_factor_y=(data_accy_max-data_accy_min)/2;            
    Scale_factor_z=(data_accz_max-data_accz_min)/2;        

}

主程序流程

使用 lis2dux12_status_get 函数检查新的加速度计数据是否已经准备好。如果status.drdy(数据就绪标志)为真,这意味着有新数据可读。
通过调用 lis2dux12_xl_data_get 函数读取加速度计数据。这些数据被存储在 data_xl.mg 数组中,分别对应 X、Y、Z 轴的加速度值。
根据 Rx_flag 的值,更新对应轴的最小值或最大值。每次更新后,调用 calculate_calibration_params 函数重新计算校准参数。
Rx_flag == 1 和 Rx_flag == 2 分别更新 X 轴的最小和最大值。
Rx_flag == 3 和 Rx_flag == 4 分别更新 Y 轴的最小和最大值。
Rx_flag == 5 和 Rx_flag == 6 分别更新 Z 轴的最小和最大值。
使用更新后的校准参数(偏移和灵敏度)来校准读取的加速度数据。校准公式为:
Calibrated value= 1000*(Raw value−Offset)/Scale Factor
这里乘以1000是为了将结果转换为毫重力单位(mg),常用于显示加速度计的读数。

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

   /* Read output only if new values are available */
    lis2dux12_status_get(&dev_ctx, &status);
    if (status.drdy) {
      lis2dux12_xl_data_get(&dev_ctx, &md, &data_xl);
        if(Rx_flag==1)//X轴min
        {
            data_accx_min=data_xl.mg[0];
            Rx_flag=0;
            calculate_calibration_params();
        }
        else if(Rx_flag==2)//X轴max
        {
            data_accx_max=data_xl.mg[0];
            Rx_flag=0;
            calculate_calibration_params();
        }
        else if(Rx_flag==3)//Y轴min
        {
            data_accy_min=data_xl.mg[1];
            Rx_flag=0;
            calculate_calibration_params();
        }        
        else if(Rx_flag==4)//Y轴max
        {
            data_accy_max=data_xl.mg[1];
            Rx_flag=0;
            calculate_calibration_params();
        }        
        else if(Rx_flag==5)//Y轴min
        {
            data_accz_min=data_xl.mg[2];
            Rx_flag=0;
            calculate_calibration_params();
        }        
        else if(Rx_flag==6)//Y轴max
        {
            data_accz_max=data_xl.mg[2];
            Rx_flag=0;
            calculate_calibration_params();
        }            

            calibrated_x=1000*(data_xl.mg[0]-Offset_x)/Scale_factor_x;
            calibrated_y=1000*(data_xl.mg[1]-Offset_y)/Scale_factor_y;            
            calibrated_z=1000*(data_xl.mg[2]-Offset_z)/Scale_factor_z;            


            printf("min_x=%4.2f,max_x=%4.2lf,min_y=%4.2f,max_y=%4.2f,min_z=%4.2f,max_z=%4.2frn",
            data_accx_min,data_accx_max,data_accy_min,data_accy_max,data_accz_min,data_accz_max);                
            printf("校准前acc[mg]:%4.2ft%4.2ft%4.2frn",
            data_xl.mg[0], data_xl.mg[1], data_xl.mg[2]);            
            printf("校准后acc[mg]:%4.2ft%4.2ft%4.2frn",
            calibrated_x, calibrated_y, calibrated_z);            

        HAL_Delay(10);


    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

串口发送定义

stm32cubemx

演示

stm32cubemx

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分