cancel
Showing results for 
Search instead for 
Did you mean: 

Understanding Output Data from I3G4250D Gyro Sensor on STM32F411e-Discovery

Duc
Associate II

Hello STM32 community,

I'm relatively new to STM32 development and I'm currently working with the I3G4250D Gyro Sensor on the STM32F411e-Discovery board. I've been using the stm32f411e_discovery_gyroscope.c file provided by STM32Cube to interface with the sensor.

I've managed to retrieve data from the sensor using the provided code snippet:

BSP_GYRO_GetXYZ(Buffer2);

Xval = Buffer2[0];
Yval = Buffer2[1];
Zval = Buffer2[2];

 

However, the output I'm getting seems to be raw data, and I'm not quite sure how to interpret it correctly. My understanding is that these values represent the raw sensor readings, but I'm unsure how to convert them into meaningful X, Y, and Z values.

Could someone please provide guidance on how to properly interpret and convert these raw values into meaningful data? Additionally, if there are any specific calibration steps or formulas that need to be applied to obtain accurate results, I would greatly appreciate any insights on that as well.

Thank you in advance for your help!

15 REPLIES 15

The code I use to test my board works perfectly, without any issues.

So what was the key which took you from not being "unable to understand Output Data from I3G4250D" to having "perfectly working" software?

Please mark that post as the solution.

See: https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

You can read my post — at the beginning, I had the correct data, but it was in raw form. My main issue was that I wasn’t sure whether it was actually raw data, and if it was, how to convert it into usable or "real" data. In @Kushal_Es’s case, the problem is different: he doesn’t have reliable data to begin with. When he enters it into the table, the results are unstable. In contrast, even though my data was raw, once I entered it into the table, I still got stable results.


@Duc wrote:

You can read my post — at the beginning, I had the correct data, but it was in raw form. My main issue was that I wasn’t sure whether it was actually raw data, and if it was, how to convert it into usable or "real" data. 


So mark the post which enabled you to resolve that issue.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Kushal_Es
Associate

The solution provided by you is not able to solve my problem.
I'm still getting unstable readings when the board is stationery.

Here is my output when the board is stationary.

Duc_0-1746711561368.png

Please update my main.c file as follows:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */

#include "main.h"
#include "stdio.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

uint32_t startTick, endTick, elapsedTime, previousTime = 0;
uint16_t Timeinterval = 5;

float Buffer2[3] = {0};
float Xmag = 0.0, Ymag = 0.0, Zmag = 0.0;


int main(void)
{


  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  I2C_Init();

  if(BSP_LSM303AGR_Mag_Init() == 0){
	  printf("I2C Mag Sensor OK \n");
  }
  else{
	  printf("I2C Mag Sensor Error \n");
  }


  while (1)
  {
	  startTick = HAL_GetTick();

	  if (startTick - previousTime > Timeinterval){

		  Mag_GetData(Buffer2);

		  Xmag = Buffer2[0];
		  Ymag = Buffer2[1];
		  Zmag = Buffer2[2];

		  printf("Xmag: %.2f, Ymag: %.2f, Zmag: %.2f \n", Xmag, Ymag, Zmag);

		  previousTime = HAL_GetTick();
	  }

  }

}



/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 8;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(CS_I2C_SPI_GPIO_Port, CS_I2C_SPI_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, Green_Led_Pin|Orange_Led_Pin|Red_Led_Pin|Blue_Led_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : I2C_DRDY_Pin SPI_INT1_Pin SPI_INT2_Pin */
  GPIO_InitStruct.Pin = I2C_DRDY_Pin|SPI_INT1_Pin|SPI_INT2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pin : CS_I2C_SPI_Pin */
  GPIO_InitStruct.Pin = CS_I2C_SPI_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  HAL_GPIO_Init(CS_I2C_SPI_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : I2C_INT1_Pin I2C_INT2_Pin */
  GPIO_InitStruct.Pin = I2C_INT1_Pin|I2C_INT2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pins : Green_Led_Pin Orange_Led_Pin Red_Led_Pin Blue_Led_Pin */
  GPIO_InitStruct.Pin = Green_Led_Pin|Orange_Led_Pin|Red_Led_Pin|Blue_Led_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @PAram  file: pointer to the source file name
  * @PAram  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */