[环境传感器] 基于STM32F401RE开发板的X-NUCLEO-IKS01A3传感器测试之四LIS2MDL磁力计测试

hujj   2019-7-23 11:00 楼主

    测试LIS2MDL磁力计花费了几天的时间,主要是在数据的显示时遇到了坑,从传感器返回的值是16位带符号的整数,开始我按二进制方式,大于32767的就按负数进行换算,但总是没有达到目的,折腾了许多才反映过来应该直接判断是否小于零,最后达到了目的,显示的结果与串口输出结果完全一致。下图是串口输出的测试结果:

LIS2MDL_test_01.jpg

    这是LCD显示的结果,显示分两个屏幕,第一屏显示轴向、自测前数据和自测数据。

LIS2MDL_test_04jpg.jpg

    第二屏显示三个轴向的自测前后数据差和下限、上限:

LIS2MDL_test_05jpg.jpg
    下图是测试时的照片:

LIS2MDL_test_02.jpg

    这是开机屏幕:

LIS2MDL_test_03jpg.jpg

    现在还不清楚自测前后的数据表示什么,在测试中,如果开发不移动,每次测试返回的值都有少许差别,如果移动了位置则差别较大,目前仍在继续测试中,看能否弄清楚数值与位置或方向之间的规律。

    下面是添加了显示的代码:

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url]  Performs LIS2MDL magnetometer self-test执行Lis2Mdl磁强计自检
  * @retval BSP status
  */
static int32_t LIS2MDL_SelfTest(void)
{
  int32_t test_result = BSP_ERROR_NONE;
  uint32_t i;
  IKS01A3_MOTION_SENSOR_Axes_t data_nost;
  IKS01A3_MOTION_SENSOR_Axes_t data_st;
  IKS01A3_MOTION_SENSOR_Axes_t data;
  uint8_t prev_reg_values[ST_REG_COUNT];
  int32_t ret;
	
	int16_t temp;

  (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\nStarting LIS2MDL magnetometer self-test ...\r\nKeep the device still!!!\r\n");
  printf("%s", dataOut);

  HAL_Delay(INDICATION_DELAY);
  BSP_LED_On(LED2);

  /* Store current settings of the sensor 存储传感器的当前设置*/
  for (i = 0; i < ST_REG_COUNT; i++)
  {
    if ((ret = IKS01A3_MOTION_SENSOR_Read_Register(IKS01A3_LIS2MDL_0, reg_addr[i], &prev_reg_values[i])) != BSP_ERROR_NONE)
    {
      return ret;
    }
  }

  /* Set the sensor for self-test 设置传感器进行自检*/
  for (i = 0; i < ST_REG_COUNT; i++)
  {
    if ((ret = IKS01A3_MOTION_SENSOR_Write_Register(IKS01A3_LIS2MDL_0, reg_addr[i], st_reg_values[i])) != BSP_ERROR_NONE)
    {
      return ret;
    }
  }

  /* Wait defined time for stable output 等待确定的稳定输出时间*/
  HAL_Delay(POWER_UP_DELAY);

  /* Read first data and discard it 读取第一个数据并丢弃它*/
  if (LIS2MDL_M_Get_Data(&data) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  data_nost.x = 0;
  data_nost.y = 0;
  data_nost.z = 0;

  /* Read valid data multiple times and average it 多次读取有效数据并取其平均值*/
  for (i = 0; i < (uint32_t)N_SAMPLES; i++)
  {
    if (LIS2MDL_M_Get_Data(&data) != BSP_ERROR_NONE)
    {
      Error_Handler();
    }
    data_nost.x += data.x;
    data_nost.y += data.y;
    data_nost.z += data.z;
  }
  data_nost.x /= N_SAMPLES;
  data_nost.y /= N_SAMPLES;
  data_nost.z /= N_SAMPLES;

  /* Enable self-test 启用自检*/
  if ((ret = IKS01A3_MOTION_SENSOR_Set_SelfTest(IKS01A3_LIS2MDL_0, MOTION_MAGNETO, 1)) != BSP_ERROR_NONE)
  {
    return ret;
  }

  /* Wait defined time for stable output */
  HAL_Delay(ST_ENABLED_DELAY);

  /* Read first data and discard it 读取第一个数据并丢弃它*/
  if (LIS2MDL_M_Get_Data(&data) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }
  data_st.x = 0;
  data_st.y = 0;
  data_st.z = 0;

  /* Read valid data multiple times and average it 多次读取有效数据并取其平均值*/
  for (i = 0; i < (uint32_t)N_SAMPLES; i++)
  {
    if (LIS2MDL_M_Get_Data(&data) != BSP_ERROR_NONE)
    {
      Error_Handler();
    }
    data_st.x += data.x;
    data_st.y += data.y;
    data_st.z += data.z;
  }
  data_st.x /= N_SAMPLES;
  data_st.y /= N_SAMPLES;
  data_st.z /= N_SAMPLES;

  /* Restore previous settings of the sensor 恢复传感器以前的设置*/
  for (i = 0; i < ST_REG_COUNT; i++)
  {
    if ((ret = IKS01A3_MOTION_SENSOR_Write_Register(IKS01A3_LIS2MDL_0, reg_addr[i], prev_reg_values[i])) != BSP_ERROR_NONE)
    {
      return ret;
    }
  }

  /* Evaluate the test 评估测试*/
  if (abs(data_st.x - data_nost.x) < LO_LIM)
  {
    test_result = BSP_ERROR_COMPONENT_FAILURE;
  }
  if (abs(data_st.x - data_nost.x) > HI_LIM)
  {
    test_result = BSP_ERROR_COMPONENT_FAILURE;
  }
  if (abs(data_st.y - data_nost.y) < LO_LIM)
  {
    test_result = BSP_ERROR_COMPONENT_FAILURE;
  }
  if (abs(data_st.y - data_nost.y) > HI_LIM)
  {
    test_result = BSP_ERROR_COMPONENT_FAILURE;
  }
  if (abs(data_st.z - data_nost.z) < LO_LIM)
  {
    test_result = BSP_ERROR_COMPONENT_FAILURE;
  }
  if (abs(data_st.z - data_nost.z) > HI_LIM)
  {
    test_result = BSP_ERROR_COMPONENT_FAILURE;
  }

  /* Print measured data 打印测量数据*/
  (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\nMeasured magnetic field [mgauss]:\r\n");
  //测量磁场: 轴,自测前,自测
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n     AXIS     | PRE-SELFTEST |   SELFTEST\r\n");
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "--------------|--------------|--------------\r\n");
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "       X      | %8ld     | %8ld\r\n", data_nost.x, data_st.x);
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "       Y      | %8ld     | %8ld\r\n", data_nost.y, data_st.y);
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "       Z      | %8ld     | %8ld\r\n", data_nost.z, data_st.z);
  printf("%s", dataOut);
    //添加LCD显示的代码开始
    LCD_clear();
    LCD_write_BG(10,0,(uint8_t *)"磁场传感器");
    LCD_write_ASCII(0,2,(uint8_t *)"PRE-SEL. SELF.");
    LCD_write_ASCII(0,3,(uint8_t *)"X");
    LCD_write_ASCII(0,4,(uint8_t *)"Y");
    LCD_write_ASCII(0,5,(uint8_t *)"Z");
	if(data_nost.x < 0){
		LCD_write_value(15,3,5,0,0,65536 - data_nost.x);
		LCD_write_ASCII(15,3,(uint8_t *)"-");
	}
	else
        LCD_write_value(15,3,5,0,0,data_nost.x);

	if(data_st.x < 0){
		LCD_write_value(50,3,5,0,0,65536 - data_st.x);
		LCD_write_ASCII(50,3,(uint8_t *)"-");
	}
	else	
	    LCD_write_value(50,3,5,0,0,data_st.x);
	
	if(data_nost.y < 0){
		LCD_write_value(15,4,5,0,0,65536 - data_nost.y);
		LCD_write_ASCII(15,4,(uint8_t *)"-");
	}
	else
        LCD_write_value(15,4,5,0,0,data_nost.y);

	if(data_st.y < 0){
		LCD_write_value(50,4,5,0,0,65536 - data_st.y);
		LCD_write_ASCII(50,4,(uint8_t *)"-");
	}
	else
    	LCD_write_value(50,4,5,0,0,data_st.y);
    
	if(data_nost.z < 0){
		LCD_write_value(15,5,5,0,0,65536 - data_nost.z);
		LCD_write_ASCII(15,5,(uint8_t *)"-");
	}
	else
        LCD_write_value(15,5,5,0,0,data_nost.z);
	
	if(data_st.z < 0){
		LCD_write_value(50,5,5,0,0,65536 - data_st.z);
		LCD_write_ASCII(50,5,(uint8_t *)"-");
	}
	else
	    LCD_write_value(50,5,5,0,0,data_st.z);
	
	//添加LCD显示的代码结束
	
  /* Print test limits and data 打印测试限值和数据*/
  (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\nTest limits and data [mgauss]:\r\n");
  //试验限值和数据: 下限,差异,上限
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\n  LOW LIMIT   |  DIFFERENCE  |  HIGH LIMIT\r\n");
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "--------------|--------------|--------------\r\n");
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "%8d      | %8d     | %8d\r\n", LO_LIM, (int)abs(data_st.x - data_nost.x), HI_LIM);
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "%8d      | %8d     | %8d\r\n", LO_LIM, (int)abs(data_st.y - data_nost.y), HI_LIM);
  printf("%s", dataOut);
  (void)snprintf(dataOut, MAX_BUF_SIZE, "%8d      | %8d     | %8d\r\n", LO_LIM, (int)abs(data_st.z - data_nost.z), HI_LIM);
  printf("%s", dataOut);
    
	//添加LCD显示的代码开始
    HAL_Delay(8000);
    LCD_clear();
    LCD_write_BG(10,0,(uint8_t *)"磁场传感器");
    LCD_write_ASCII(0,2,(uint8_t *)"LOW DIFF. HIGH");

    LCD_write_value(0,3,2,0,0,LO_LIM);
    temp = data_st.x - data_nost.x;
	if(temp < 0){
		LCD_write_value(15,3,5,0,0,65536 - temp);
		LCD_write_ASCII(15,3,(uint8_t *)"-");
	}
	else
        LCD_write_value(15,3,5,0,0,temp);
	LCD_write_value(60,3,3,0,0,HI_LIM);
	
	LCD_write_value(0,4,2,0,0,LO_LIM);
    temp = data_st.y - data_nost.y;
	if(temp < 0){
		LCD_write_value(15,4,5,0,0,65536 - temp);
		LCD_write_ASCII(15,4,(uint8_t *)"-");
	}
	else
        LCD_write_value(15,4,5,0,0,temp);
	LCD_write_value(60,4,3,0,0,HI_LIM);
	
	LCD_write_value(0,5,2,0,0,LO_LIM);
    temp = data_st.z - data_nost.z;
	if(temp < 0){
		LCD_write_value(15,5,5,0,0,65536 - temp);
		LCD_write_ASCII(15,5,(uint8_t *)"-");
	}
	else
        LCD_write_value(15,5,5,0,0,temp);
	LCD_write_value(60,5,3,0,0,HI_LIM);
	
	//添加LCD显示的代码结束
	
  /* Print the test result */
  if (test_result == BSP_ERROR_NONE)
  {
    (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\nLIS2MDL magnetometer self-test PASSED!\r\n");
  }
  else
  {
    (void)snprintf(dataOut, MAX_BUF_SIZE, "\r\nLIS2MDL magnetometer self-test FAILED!\r\n");
  }
  printf("%s", dataOut);

  BSP_LED_Off(LED2);

  return ret;
}



此内容由EEWORLD论坛网友hujj原创,如需转载或用于商业用途需征得作者同意并注明出处

回复评论 (1)

用int16_t类型存数据不就好了?不用判断正负值。

点赞  2019-12-6 11:31
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复