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

2024-08-26

概述

磁力计测量结果容易受到周围环境中的硬铁(Hard Iron)和软铁(Soft Iron)效应的干扰,从而影响精度。为了解决这一问题,磁力计校准变得至关重要。STMicroelectronics提供的MotionMC库是一个高效的中间件解决方案,专门用于实时校准磁力计数据,以消除这些误差。

MotionMC库能够通过测量不同方向的磁场数据,自动计算并补偿硬铁和比例因子效应。它集成了在嵌入式系统中运行的轻量级算法,能够在系统运行期间进行动态校准,确保磁力计的输出数据始终准确可靠。

在本文中,将介绍如何使用LIS2MDL磁力计与MotionMC库执行磁力计校准。我们将探讨从传感器初始化、数据采集到最终应用校准参数的整个流程,并提供相应的代码示例,以帮助开发者更好地集成和利用MotionMC库提升系统的磁力测量精度。

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

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第1张

视频教学

[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。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第2张

开启CRC

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第3张

串口设置

设置串口速率为2000000。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第4张

开启X-CUBE-MEMS1

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第5张

速率选择

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

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第6张

参考程序

这里参考 IKS01A3_MagnetometerCalibration 。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第7张

磁力计校准过程

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

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

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第8张

初始化定义

/* 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)该库。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第9张

MotionMC_manager_get_version

MotionMC_manager_get_version中主要执行MotionMC_GetLibVersion,MotionMC_GetLibVersion用途主要是检索库的版本信息。

参数:

version: 一个指向字符数组的指针,用于存储版本字符串。

返回值: 版本字符串中的字符数量。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第10张

MotionMC_manager_update

MotionMC_manager_update中主要执行MotionMC_Update,MotionMC_Update用途主要是运行磁力计校准算法。这个函数需要周期性地调用,其周期与初始化函数中设置的sampletime参数相同。

参数:

data_in: 指向包含输入数据的结构体的指针。这个结构体包含了当前的磁力计传感器数据和时间戳。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第11张

MotionMC_manager_get_params

MotionMC_manager_get_params中主要执行MotionMC_GetCalParams,MotionMC_GetCalParams用途主要是获取磁力计的硬铁(HI)和比例因子(SF)校准系数。

参数:

data_out: 指向包含输出数据的结构体的指针。这个结构体包括了HI偏置、SF矩阵和校准质量因子。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第12张

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 中。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第13张

主程序执行流程

/* 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。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第14张

校准成功时为3。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第15张

指向北数据。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第16张

指向南数据。

磁力计LIS2MDL开发(4)- 执行磁力计校准 (https://ic.work/) 技术资料 第17张

审核编辑 黄宇

文章推荐

相关推荐