磁力计LIS2MDL开发(4)----MotionMC 执行磁力计校准

描述

概述

磁力计测量结果容易受到周围环境中的硬铁(Hard Iron)和软铁(Soft Iron)效应的干扰,从而影响精度。为了解决这一问题,磁力计校准变得至关重要。STMicroelectronics提供的MotionMC库是一个高效的中间件解决方案,专门用于实时校准磁力计数据,以消除这些误差。
MotionMC库能够通过测量不同方向的磁场数据,自动计算并补偿硬铁和比例因子效应。它集成了在嵌入式系统中运行的轻量级算法,能够在系统运行期间进行动态校准,确保磁力计的输出数据始终准确可靠。
在本文中,将介绍如何使用LIS2MDL磁力计与MotionMC库执行磁力计校准。我们将探讨从传感器初始化、数据采集到最终应用校准参数的整个流程,并提供相应的代码示例,以帮助开发者更好地集成和利用MotionMC库提升系统的磁力测量精度。

需要样片的可以加群申请:615061293 。

磁力计

视频教学

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

样品申请

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

源码下载

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

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。

主控为STM32H503CB,陀螺仪为LSM6DS3TR-C,磁力计为LIS2MDL。

磁力计

开启CRC

磁力计

串口设置

设置串口速率为2000000。

磁力计

开启X-CUBE-MEMS1

磁力计

速率选择

磁力计数据最大可以设置100Hz。

磁力计

参考程序

这里参考 IKS01A3_MagnetometerCalibration 。

磁力计

磁力计校准过程

MotionMC 是一个用于校准磁力计传感器的库。校准过程旨在消除硬铁效应(由于设备内部或附近的磁性材料引起的误差)和软铁效应(由于设备内部或附近的导电材料引起的误差),从而提高磁力计的精度。

建议在三维空间中缓慢旋转。这个动作的重点在于它不是一个简单的平面运动,而是需要在不同的空间角度进行倾斜和旋转,以覆盖尽可能多的三维空间位置。

磁力计

初始化定义

/* USER CODE BEGIN 2 */
    printf("HELLO!n");
  HAL_GPIO_WritePin(CS1_GPIO_Port, CS1_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
    HAL_Delay(100);


  /* Initialize mems driver interface */
  stmdev_ctx_t dev_ctx;
  dev_ctx.write_reg = platform_write;
  dev_ctx.read_reg = platform_read;
  dev_ctx.mdelay = platform_delay;
  dev_ctx.handle = &SENSOR_BUS;
  /* Initialize platform specific hardware */
//  platform_init();
  /* Wait sensor boot time */
  platform_delay(BOOT_TIME);

  /* Check device ID */
  lis2mdl_device_id_get(&dev_ctx, &whoamI);
    printf("LIS2MDL_ID=0x%x,whoamI=0x%xn",LIS2MDL_ID,whoamI);
  if (whoamI != LIS2MDL_ID)
    while (1) {
      /* manage here device not found */
    }

  /* Restore default configuration */
  lis2mdl_reset_set(&dev_ctx, PROPERTY_ENABLE);

  do {
    lis2mdl_reset_get(&dev_ctx, &rst);
  } while (rst);

  /* Enable Block Data Update */
  lis2mdl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
  /* Set Output Data Rate */
  lis2mdl_data_rate_set(&dev_ctx, LIS2MDL_ODR_50Hz);
  /* Set / Reset sensor mode */
  lis2mdl_set_rst_mode_set(&dev_ctx, LIS2MDL_SENS_OFF_CANC_EVERY_ODR);
  /* Enable temperature compensation */
  lis2mdl_offset_temp_comp_set(&dev_ctx, PROPERTY_ENABLE);
  /* Set device in continuous mode */
  lis2mdl_operating_mode_set(&dev_ctx, LIS2MDL_CONTINUOUS_MODE);    


    MX_MEMS_Init();

  /* USER CODE END 2 */

MotionMC文件

主要包含app_mems.c和app_mems.h, 它们提供了一些与MEMS传感器相关的初始化、处理和管理函数。这些文件在磁力计校准、数据处理以及传感器初始化等方面发挥着重要作用。
● MX_MEMS_Init(void) 和 MX_MEMS_Process(void):这些函数用于初始化和处理MEMS传感器的操作。
● MotionMC_manager_init(int sampletime, unsigned short int enable):初始化MotionMC库。
● MotionMC_manager_update(MMC_Input_t *data_in):使用新的传感器数据更新MotionMC库。
● MotionMC_manager_get_params(MMC_Output_t *data_out):获取校准后的参数。
● MotionMC_manager_compensate(MOTION_SENSOR_Axes_t *data_raw, MOTION_SENSOR_Axes_t *data_comp):对传感器数据应用校准补偿。

MotionMC_Initialize

MotionMC_manager_init中主要执行MotionMC_Initialize,MotionMC_Initialize用途主要初始化MotionMC库并设置内部机制。这个函数在使用磁力计校准库之前必须调用。
参数:
sampletime: 设置更新函数调用之间的时间间隔(以毫秒为单位)。
enable: 启用(1)或禁用(0)该库。

磁力计

MotionMC_manager_get_version

MotionMC_manager_get_version中主要执行MotionMC_GetLibVersion,MotionMC_GetLibVersion用途主要是检索库的版本信息。
参数:
version: 一个指向字符数组的指针,用于存储版本字符串。
返回值: 版本字符串中的字符数量。

磁力计

MotionMC_manager_update

MotionMC_manager_update中主要执行MotionMC_Update,MotionMC_Update用途主要是运行磁力计校准算法。这个函数需要周期性地调用,其周期与初始化函数中设置的sampletime参数相同。
参数:
data_in: 指向包含输入数据的结构体的指针。这个结构体包含了当前的磁力计传感器数据和时间戳。

磁力计

MotionMC_manager_get_params

MotionMC_manager_get_params中主要执行MotionMC_GetCalParams,MotionMC_GetCalParams用途主要是获取磁力计的硬铁(HI)和比例因子(SF)校准系数。
参数:
data_out: 指向包含输出数据的结构体的指针。这个结构体包括了HI偏置、SF矩阵和校准质量因子。

磁力计

CalQuality = 0:校准参数的准确性未知。
CalQuality = 1:校准参数的准确性较差,不能被信任。
CalQuality = 2:校准参数的准确性尚可。
CalQuality = 3:校准参数的准确性良好。

MotionMC_manager_compensate

MotionMC_manager_compensate 的主要作用是对磁力计数据进行硬铁(Hard Iron)和软铁(Soft Iron)校准,从而补偿磁力计测量中的误差。

/**
 * @brief  Do hard & soft iron calibration
 * @param  data_raw  Raw magnetometer data [mGauss]
 * @param  data_comp  Calibrated (compensated) data (hard & soft iron calibration) [mGauss]
 * @retval None
 */
void MotionMC_manager_compensate(MOTION_SENSOR_Axes_t *data_raw, MOTION_SENSOR_Axes_t *data_comp)
{
  MMC_Output_t data_out;
  MotionMC_GetCalParams(&data_out);

  float mag_raw_mG[3];
  float mag_comp_mG[3];

  mag_raw_mG[0] = (float)data_raw- >x;
  mag_raw_mG[1] = (float)data_raw- >y;
  mag_raw_mG[2] = (float)data_raw- >z;

  /* Compensate magnetometer data */
  /* NOTE: Convert hard iron coefficients [uT] to [mGauss] */
  for (int i = 0; i < 3; i++)
  {
    mag_comp_mG[i] = 0.0f;
    for (int j = 0; j < 3; j++)
    {
      mag_comp_mG[i] += (mag_raw_mG[j]  -  data_out.HI_Bias[j] * 10.0f)  *  data_out.SF_Matrix[i][j];
    }

    mag_comp_mG[i] += (mag_comp_mG[i] >= 0.0f) ? 0.5f : -0.5f;
  }

  data_comp- >x = (int32_t)mag_comp_mG[0];
  data_comp- >y = (int32_t)mag_comp_mG[1];
  data_comp- >z = (int32_t)mag_comp_mG[2];
}

● 硬铁效应:由设备内部或附近的永久磁铁或磁性材料引起的偏移,会导致测量结果出现恒定的误差。
● 软铁效应:由设备内部或附近的导磁材料(如铁)引起的误差,会影响测量结果的方向和幅度。
● 补偿计算:
● 对每个轴(X, Y, Z)进行硬铁和软铁效应的补偿计算。计算过程中:
○ 硬铁效应补偿:从原始数据中减去硬铁偏置,单位从微特斯拉(uT)转换为毫高斯(mGauss),即乘以10。
○ 软铁效应补偿:通过乘以校正矩阵 SF_Matrix,对软铁效应进行补偿。
● 结果修正和输出:
● 补偿后的磁力计数据 mag_comp_mG 进行四舍五入,然后转换为整数并存储到 data_comp 中。

磁力计

主程序执行流程

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    uint8_t reg;
    /* Read output only if new value is available */
    lis2mdl_mag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read magnetic field data */
      memset(data_raw_magnetic, 0x00, 3 * sizeof(int16_t));
      lis2mdl_magnetic_raw_get(&dev_ctx, data_raw_magnetic);
      magnetic_mG[0] = lis2mdl_from_lsb_to_mgauss(data_raw_magnetic[0]);
      magnetic_mG[1] = lis2mdl_from_lsb_to_mgauss(data_raw_magnetic[1]);
      magnetic_mG[2] = lis2mdl_from_lsb_to_mgauss(data_raw_magnetic[2]);
            MX_MEMS_Process();


//      printf("Magnetic field [mG]:%4.2ft%4.2ft%4.2frn",
//              magnetic_mG[0], magnetic_mG[1], magnetic_mG[2]);
//      /* Read temperature data */
//      memset(&data_raw_temperature, 0x00, sizeof(int16_t));
//      lis2mdl_temperature_raw_get(&dev_ctx, &data_raw_temperature);
//      temperature_degC = lis2mdl_from_lsb_to_celsius(data_raw_temperature);
//      printf("Temperature [degC]:%6.2frn",
//              temperature_degC);
    }        


    /* USER CODE END WHILE */

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

演示

未校准成功时未0。

磁力计

校准成功时为3。

磁力计

指向北数据。

磁力计

指向南数据。

磁力计

审核编辑 黄宇

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

全部0条评论

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

×
20
完善资料,
赚取积分