cancel
Showing results for 
Search instead for 
Did you mean: 

Extraction of LSM303dlhc accelerometer data

ssena.1514
Associate III

Hi Sir/Madam,

I want to implement a vibration detector using stm32f401vc discovery board which mainly consists of LSM303dlhc mems accelerometer sensor.

The problem here is that when I am extracting the data from the sensor ,mostly the data is fluctuating  a lot.

Here my task is to find a certain threshold ,so that when data goes out of range an led will blink or a buzzer will blow.

So how to solve the problem for this purpose.

1.And second thing is shall we need any secondary software filter to avoid data fluctuation or only configuration of inbuilt filter is sufficient.

2.Third thing is how to select the time delay of data extraction from data rate.

 

Please reply to this post.

 

The content of c code is given as below.

 

#include "stm32f4xx.h"
#include "stm32f401_discovery_lsm303dlhc.h"
 
 
 
 
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define  LSM_Acc_Sensitivity_2g     (float)     1.0f            /*!< accelerometer sensitivity with 2 g full scale [LSB/mg] */
#define  LSM_Acc_Sensitivity_4g     (float)     0.5f            /*!< accelerometer sensitivity with 4 g full scale [LSB/mg] */
#define  LSM_Acc_Sensitivity_8g     (float)     0.25f           /*!< accelerometer sensitivity with 8 g full scale [LSB/mg] */
#define  LSM_Acc_Sensitivity_16g    (float)     0.0834f         /*!< accelerometer sensitivity with 16 g full scale [LSB/mg] */                      
 
 
#define  ABS(x) (x<0)?(-x):x
/* Private variables ---------------------------------------------------------*/
static __IO uint32_t TimingDelay;
 
 
float AccBuffer[3] = {0.0f};
 
/* Private function prototypes -----------------------------------------------*/
static void Delay(__IO uint32_t nTime);
static void LSM303DLHC_AccConfig(void);
static void LSM303DLHC_ReadAcc(float*);
 
 
 
 
/* Private functions ---------------------------------------------------------*/
int main(void)
{
 
GPIO_InitTypeDef GPIO_InitStruct;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
 
 
  GPIO_InitStruct.GPIO_Pin= GPIO_Pin_12 | GPIO_Pin_14;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP ;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ;
  GPIO_Init(GPIOD,&GPIO_InitStruct);
 
  if (SysTick_Config(SystemCoreClock / 1000))
  { 
    /* Capture error */ 
    while (1);
  }
 
LSM303DLHC_AccConfig();
 
while(1)
{
Delay(1);
  GPIO_ToggleBits(GPIOD,GPIO_Pin_12);
  LSM303DLHC_ReadAcc(AccBuffer);
}
}//main end
 
 
 
 
 
static void LSM303DLHC_AccConfig(void)
{
  LSM303DLHCAcc_InitTypeDef LSM303DLHCAcc_InitStructure;
  LSM303DLHCAcc_FilterConfigTypeDef LSM303DLHCFilter_InitStructure;
  
  /* MEMS configuration ------------------------------------------------------*/
  /* Fill the accelerometer structure */
  LSM303DLHCAcc_InitStructure.Power_Mode = LSM303DLHC_NORMAL_MODE;
  LSM303DLHCAcc_InitStructure.AccOutput_DataRate = LSM303DLHC_ODR_25_HZ;
  LSM303DLHCAcc_InitStructure.Axes_Enable= LSM303DLHC_AXES_ENABLE;
  LSM303DLHCAcc_InitStructure.AccFull_Scale = LSM303DLHC_FULLSCALE_16G;
  LSM303DLHCAcc_InitStructure.BlockData_Update = LSM303DLHC_BlockUpdate_Continous;
  LSM303DLHCAcc_InitStructure.Endianness=LSM303DLHC_BLE_LSB;
  LSM303DLHCAcc_InitStructure.High_Resolution=LSM303DLHC_HR_ENABLE;
  /* Configure the accelerometer main parameters */
  LSM303DLHC_AccInit(&LSM303DLHCAcc_InitStructure);
  
  /* Fill the accelerometer LPF structure */
  LSM303DLHCFilter_InitStructure.HighPassFilter_Mode_Selection =LSM303DLHC_HPM_NORMAL_MODE;
  LSM303DLHCFilter_InitStructure.HighPassFilter_CutOff_Frequency = LSM303DLHC_HPFCF_16;
  LSM303DLHCFilter_InitStructure.HighPassFilter_AOI1 = LSM303DLHC_HPF_AOI1_DISABLE;
  LSM303DLHCFilter_InitStructure.HighPassFilter_AOI2 = LSM303DLHC_HPF_AOI2_DISABLE;
 
  /* Configure the accelerometer LPF main parameters */
  LSM303DLHC_AccFilterConfig(&LSM303DLHCFilter_InitStructure);
 
 
}
 
 
 
/**
* @brief Read LSM303DLHC output register, and calculate the acceleration ACC=(1/SENSITIVITY)* (out_h*256+out_l)/16 (12 bit rappresentation)
* @PAram pnData: pointer to float buffer where to store data
* @retval None
*/
void LSM303DLHC_ReadAcc(float* pfData)
{
  int16_t pnRawData[3];
  uint8_t ctrlx[2];
  uint8_t buffer[6], cDivider;
  uint8_t i = 0;
  float LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_2g;
  
  /* Read the register content */
  LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, 2, ctrlx);
  LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, 6, buffer);
  
  if(ctrlx[1]&0x40)
    cDivider=64;
  else
    cDivider=16;
  
  /* check in the control register4 the data alignment*/
  if(!(ctrlx[0] & 0x40) || (ctrlx[1] & 0x40)) /* Little Endian Mode or FIFO mode */
  {
    for(i=0; i<3; i++)
    {
      pnRawData[i]=((int16_t)((uint16_t)buffer[2*i+1] << 8) + buffer[2*i])/cDivider;
    }
  }
  else /* Big Endian Mode */
  {
    for(i=0; i<3; i++)
      pnRawData[i]=((int16_t)((uint16_t)buffer[2*i] << 8) + buffer[2*i+1])/cDivider;
  }
  /* Read the register content */
  LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, 2, ctrlx);
  
  
  if(ctrlx[1]&0x40)
  {
    /* FIFO mode */
    LSM_Acc_Sensitivity = 0.25;
  }
  else
  {
    /* normal mode */
    /* switch the sensitivity value set in the CRTL4*/
    switch(ctrlx[0] & 0x30)
    {
    case LSM303DLHC_FULLSCALE_2G:
      LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_2g;
      break;
    case LSM303DLHC_FULLSCALE_4G:
      LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_4g;
      break;
    case LSM303DLHC_FULLSCALE_8G:
      LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_8g;
      break;
    case LSM303DLHC_FULLSCALE_16G:
      LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_16g;
      break;
    }
  }
  
  /* Obtain the mg value for the three axis */
  for(i=0; i<3; i++)
  {
    pfData[i]=(float)pnRawData[i]/LSM_Acc_Sensitivity;
  }
}
 
 
 
 
/**
  * @brief  Inserts a delay time.
  * @PAram  nTime: specifies the delay time length, in milliseconds.
  * @retval None
  */
static void Delay(__IO uint32_t nTime)
  TimingDelay = nTime;
 
  while(TimingDelay != 0);
}
 
/**
  * @brief  Decrements the TimingDelay variable.
  * @PAram  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  { 
    TimingDelay--;
  }
}
 
 
/**
  * @brief  This function handles SysTick Handler.
  * @PAram  None
  * @retval None
  */
void SysTick_Handler(void)
{
  TimingDelay_Decrement();
}
 
//////////////////////////////////end///////////////////////////////////////////
 

IDE - KEIL mdk arm

BOARD - stm32f401vc discovery kit

 

Thanks & Regards

Satyabrata Senapati(firmware Developer)

 

 

  

1 REPLY 1
codebuk
Associate III

The filter required will depend on characteristics of vibration. I use the following median filter for an ST IIS3DHHC. For my purposes I use a 3 x 257 element filters which uses minimal CPU at ~1000HZ update speed on a 168Mhz STM32F427.  I find this code works perfectly for my purposes:  

https://github.com/accabog/MedianFilter

Consider using an interrupt rather than polling. I think that dev board has a DRDY pin wired to an input that can be used a interrupt.