AnsweredAssumed Answered

how to get accelerometer continuous data

Question asked by Manish on May 29, 2014
Hello ,
         I am Manish woking on STM32F3Discovery for getting accelerometer data using arm-none-eabi toolchain on Linux platform.
I have sucessfully read accelerometer data in one iteration But Now I want accelerometer data  continuously so.
1.What configuration I need to get continuous data..?
2.How I should modify code to get continuous data from accelerometer ?
     please guide me related to that.I am mentioning my code with this post.



/**
 ******************************************************************************
 * @file    main.c
 * @author  MCD Application Team
 * @version V1.1.0
 * @date    20-September-2012
 * @brief   Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
 *
 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *        http://www.st.com/software_license_agreement_liberty_v2
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************
 */


#include<stdio.h>
#include <string.h>
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include </home/manish/VTS/MEMS-stm32f3/libs/STM32F30x_StdPeriph_Driver/inc/stm32f30x_rcc.h>
#include </home/manish/VTS/MEMS-stm32f3/libs/STM32F30x_StdPeriph_Driver/inc/stm32f30x_gpio.h>
#include </home/manish/VTS/MEMS-stm32f3/libs/STM32F30x_StdPeriph_Driver/inc/stm32f30x_misc.h>
#include </home/manish/VTS/MEMS-stm32f3/libs/STM32F30x_StdPeriph_Driver/inc/stm32f30x_spi.h>
#include </home/manish/VTS/MEMS-stm32f3/libs/STM32F30x_StdPeriph_Driver/inc/stm32f30x_i2c.h>
#include </home/manish/VTS/MEMS-stm32f3/libs/STM32F30x_StdPeriph_Driver/inc/stm32f30x_exti.h>
/** @addtogroup STM32F3-Discovery_Demo
 * @{
 */


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define ABS(x)         (x < 0) ? (-x) : x
#define N 10


#define L3G_Sensitivity_250dps     (float)   114.285f         /*!< gyroscope sensitivity with 250 dps full scale [LSB/dps] */
#define L3G_Sensitivity_500dps     (float)    57.1429f        /*!< gyroscope sensitivity with 500 dps full scale [LSB/dps] */
#define L3G_Sensitivity_2000dps    (float)    14.285f           /*!< gyroscope sensitivity with 2000 dps full scale [LSB/dps] */
#define PI                         (float)     3.14159265f


#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 12 g full scale [LSB/mg] */


/* Private variables ---------------------------------------------------------*/
double P[N] = { 0.0 }; //variance matrix
double R = 0.05;  // variance noise measurements
double Y[N] = { 0.0 }; // Estimated vector
double KK[N] = { 0.0 }; // Kalman gain vector


RCC_ClocksTypeDef RCC_Clocks;
__IO uint32_t TimingDelay = 0;
__IO uint32_t UserButtonPressed = 0;
__IO float HeadingValue = 0.0f;
float MagBuffer[3] = { 0.0f }, AccBuffer[3] = { 0.0f }, Buffer[3] = { 0.0f };
uint8_t Xval, Yval = 0x00;


__IO uint8_t DataReady = 0;
__IO uint8_t PrevXferComplete = 1;
__IO uint32_t USBConnectTimeOut = 100;


float fNormAcc, fSinRoll, fCosRoll, fSinPitch, fCosPitch = 0.0f, RollAng = 0.0f,
          PitchAng = 0.0f;
float fTiltedX, fTiltedY = 0.0f;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
 * @brief  function for kalman filtering.
 * @param  None
 * @retval None
 */


void kalman_filtering(double X[], double Q) {


     // Filter parameters
     double A[N] = { 1.00 };  // Transition matrix
     double A_Trans[N] = { 1.00 };
     unsigned int i;
     P[0] = 1.01; // initialization
     Y[0] = 0.00; // initialization


     double K[N] = { 0.0 };
     // begin
     for (i = 0; i < N; i++) {
          static double X_temp;
          static double P_temp;
          // time update
          X_temp = Y[i];
          P_temp = (A[i] * P[i] * A_Trans[i]) + Q;
          K[i] = P_temp / (P_temp + R);
          // measurment update
          Y[i] = X_temp + (K[i] * (X[i] - X_temp));
          P[i] = (1 - K[i]) * P_temp;
          //storing Gain's value
          KK[i] = K[i];
     }


}


/**
 * @brief  Main program.
 * @param  None
 * @retval None
 */
int main(void) {
     uint8_t i = 0;
     /* SysTick end of count event each 10ms */
     RCC_GetClocksFreq(&RCC_Clocks);
     SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);


     float gx, gy, gz, ax, ay, az, mx, my, mz;
     // gx =  0;
     //gy =  -1;
     //gz =  0;
     //ax = -192;
     //ay = 0;
     //az = 944;
     //mx = 183;
     //my = -450;
     //mz = -126;


     gx = 100;
     gy = 200;
     gz = 300;
     ax = 100;
     ay = 200;
     az = 300;
     mx = 100;
     my = 200;
     mz = 300;
     MadgwickAHRSupdate(gx, gy, gz, ax, ay, az, mx, my, mz);


     
     //Initialization
     Demo_GyroConfig();
    Demo_CompassConfig(); /* Demo Compass */
     
    
    /* Read Gyro Angular data */
    Demo_GyroReadAngRate(Buffer);
     
    /* Read Compass data */
    Demo_CompassReadMag(MagBuffer);
    Demo_CompassReadAcc(AccBuffer);
}
     
               
/**
 * @brief  Configure the Mems to gyroscope application.
 * @param  None
 * @retval None
 */
void Demo_GyroConfig(void) {
     L3GD20_InitTypeDef L3GD20_InitStructure;
     L3GD20_FilterConfigTypeDef L3GD20_FilterStructure;


     /* Configure Mems L3GD20 */
     L3GD20_InitStructure.Power_Mode = L3GD20_MODE_ACTIVE;
     L3GD20_InitStructure.Output_DataRate = L3GD20_OUTPUT_DATARATE_1;
     L3GD20_InitStructure.Axes_Enable = L3GD20_AXES_ENABLE;
     L3GD20_InitStructure.Band_Width = L3GD20_BANDWIDTH_4;
     L3GD20_InitStructure.BlockData_Update = L3GD20_BlockDataUpdate_Continous;
     L3GD20_InitStructure.Endianness = L3GD20_BLE_LSB;
     L3GD20_InitStructure.Full_Scale = L3GD20_FULLSCALE_500;
     L3GD20_Init(&L3GD20_InitStructure);


     L3GD20_FilterStructure.HighPassFilter_Mode_Selection =
               L3GD20_HPM_NORMAL_MODE_RES;
     L3GD20_FilterStructure.HighPassFilter_CutOff_Frequency = L3GD20_HPFCF_0;
     L3GD20_FilterConfig(&L3GD20_FilterStructure);


     L3GD20_FilterCmd(L3GD20_HIGHPASSFILTER_ENABLE);
}


/**
 * @brief  Calculate the angular Data rate Gyroscope.
 * @param  pfData : Data out pointer
 * @retval None
 */
void Demo_GyroReadAngRate(float* pfData) {
     uint8_t tmpbuffer[6] = { 0 };
     int16_t RawData[3] = { 0 };
     uint8_t tmpreg = 0;
     float sensitivity = 0;
     int i = 0;


     L3GD20_Read(&tmpreg, L3GD20_CTRL_REG4_ADDR, 1);


     L3GD20_Read(tmpbuffer, L3GD20_OUT_X_L_ADDR, 6);


     
}


/**
 * @brief  Configure the Mems to compass application.
 * @param  None
 * @retval None
 */
void Demo_CompassConfig(void) {
     LSM303DLHCMag_InitTypeDef LSM303DLHC_InitStructure;
     LSM303DLHCAcc_InitTypeDef LSM303DLHCAcc_InitStructure;
     LSM303DLHCAcc_FilterConfigTypeDef LSM303DLHCFilter_InitStructure;


     /* Configure MEMS magnetometer main parameters: temp, working mode, full Scale and Data rate */
     LSM303DLHC_InitStructure.Temperature_Sensor = LSM303DLHC_TEMPSENSOR_DISABLE;
     LSM303DLHC_InitStructure.MagOutput_DataRate = LSM303DLHC_ODR_30_HZ;/*!< Output Data Rate = 30 Hz */
     LSM303DLHC_InitStructure.MagFull_Scale = LSM303DLHC_FS_8_1_GA; /*!< Full scale = \B18.1 Gauss */
     LSM303DLHC_InitStructure.Working_Mode = LSM303DLHC_CONTINUOS_CONVERSION; /*!< Continuous-Conversion Mode */
     LSM303DLHC_MagInit(&LSM303DLHC_InitStructure);


     /* Fill the accelerometer structure */
     LSM303DLHCAcc_InitStructure.Power_Mode = LSM303DLHC_NORMAL_MODE; /*! Normal Mode */
     LSM303DLHCAcc_InitStructure.AccOutput_DataRate = LSM303DLHC_ODR_50_HZ; /*! OUT data rate */
     LSM303DLHCAcc_InitStructure.Axes_Enable = LSM303DLHC_AXES_ENABLE;
     LSM303DLHCAcc_InitStructure.AccFull_Scale = LSM303DLHC_FULLSCALE_2G; /*! Full Scale selection */
     LSM303DLHCAcc_InitStructure.BlockData_Update =LSM303DLHC_BlockUpdate_Continous; /*! output register Data Update */
     // LSM303DLHCAcc_InitStructure.BlockData_Update =LSM303DLHC_BlockUpdate_Single;   /*! output register Data Update */
     LSM303DLHCAcc_InitStructure.Endianness = LSM303DLHC_BLE_LSB; /*!< Little Endian: data LSB @ lower address */
     LSM303DLHCAcc_InitStructure.High_Resolution = LSM303DLHC_HR_ENABLE;/*! High Resolution enabling */
     // LSM303DLHCAcc_InitStructure.High_Resolution=LSM303DLHC_HR_DISABLE ;/*! High Resolution enabling */
     /* 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 Demo_CompassReadAcc(float* pfData) {
     int16_t pnRawData[3];
     uint8_t ctrlx[2];
     uint8_t buffer[N] = { 0 };
     uint8_t cDivider;
     float Q = 0.00005;


     uint8_t X_H_outbuff[N] = { 0 };
     uint8_t X_L_outbuff[N] = { 0 };
     uint8_t Y_H_outbuff[N] = { 0 };
     uint8_t Y_L_outbuff[N] = { 0 };
     uint8_t Z_H_outbuff[N] = { 0 };
     uint8_t Z_L_outbuff[N] = { 0 };


     uint8_t X_H_out_result[N] = { 0 };
     uint8_t X_L_out_result[N] = { 0 };
     uint8_t Y_H_out_result[N] = { 0 };
     uint8_t Y_L_out_result[N] = { 0 };
     uint8_t Z_H_out_result[N] = { 0 };
     uint8_t Z_L_out_result[N] = { 0 };
     double out_buffer_X_H[N] = { 0.0 };
     double out_buffer_X_L[N] = { 0.0 };
     double out_buffer_Y_H[N] = { 0.0 };
     double out_buffer_Y_L[N] = { 0.0 };
     double out_buffer_Z_H[N] = { 0.0 };
     double out_buffer_Z_L[N] = { 0.0 };
     uint8_t i = 0;
     float LSM_Acc_Sensitivity = LSM_Acc_Sensitivity_2g;


     /* Read the register content */


     /*!
      *  read content of control regsiter so as to check
      * 1.BlockData_Update
      * 2.Endianness
      * 3.AccFull_Scale
      * 4.High_Resolution
      */


     LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, ctrlx, 2);
     LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG1_A, ctrlx, 2);
     /*!
      * Output Register X acceleration
      * X-axis acceleration data.
      * The value is expressed as two’s complement.
      */


     //LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, buffer, 6);
     for (i = 0; i < N; i++) {
          LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_H_A, buffer, 1);
          LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_X_L_A, buffer + 1, 1);
          LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_A, buffer + 2, 1);
          LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_A, buffer + 3, 1);
          LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_A, buffer + 4, 1);
          LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_A, buffer + 5, 1);
          X_H_outbuff[i] = buffer[0];
          X_L_outbuff[i] = buffer[1];
          Y_H_outbuff[i] = buffer[2];
          Y_L_outbuff[i] = buffer[3];
          Z_H_outbuff[i] = buffer[4];
          Z_L_outbuff[i] = buffer[5];


          X_H_out_result[i] = (X_H_outbuff[i] ^ 0xFF) + 0x01;
          X_L_out_result[i] = (X_L_outbuff[i] ^ 0xFF) + 0x01;
          Y_H_out_result[i] = (Y_H_outbuff[i] ^ 0xFF) + 0x01;
          Y_L_out_result[i] = (Y_L_outbuff[i] ^ 0xFF) + 0x01;
          Z_H_out_result[i] = (Z_H_outbuff[i] ^ 0xFF) + 0x01;
          Z_L_out_result[i] = (Z_L_outbuff[i] ^ 0xFF) + 0x01;
     }
     memcpy(out_buffer_X_H, X_H_out_result, N);
     memcpy(out_buffer_X_L, X_L_out_result, N);
     memcpy(out_buffer_Y_H, Y_H_out_result, N);
     memcpy(out_buffer_Y_L, Y_L_out_result, N);
     memcpy(out_buffer_Z_H, Z_H_out_result, N);
     memcpy(out_buffer_Z_L, Z_L_out_result, N);


     kalman_filtering(out_buffer_X_H, Q);
     kalman_filtering(out_buffer_X_L, Q);
     kalman_filtering(out_buffer_Y_H, Q);
     kalman_filtering(out_buffer_Y_L, Q);
     kalman_filtering(out_buffer_Z_L, Q);
     kalman_filtering(out_buffer_Z_H, Q);


     
     /* Read the register content */
     LSM303DLHC_Read(ACC_I2C_ADDRESS, LSM303DLHC_CTRL_REG4_A, ctrlx, 2);


}


/**
 * @brief  calculate the magnetic field Magn.
 * @param  pfData: pointer to the data out
 * @retval None
 */
void Demo_CompassReadMag(float* pfData) {
     static uint8_t buffer[N] = { 0 };
     uint8_t CTRLB = 0;
     uint16_t Magn_Sensitivity_XY = 0, Magn_Sensitivity_Z = 0;
     uint8_t i = 0;
     float Q = 0.00005;
     uint8_t X_H_M_outbuff[N] = { 0 };
     uint8_t X_L_M_outbuff[N] = { 0 };
     uint8_t Y_H_M_outbuff[N] = { 0 };
     uint8_t Y_L_M_outbuff[N] = { 0 };
     uint8_t Z_H_M_outbuff[N] = { 0 };
     uint8_t Z_L_M_outbuff[N] = { 0 };


     uint8_t X_H_M_out_result[N] = { 0 };
     uint8_t X_L_M_out_result[N] = { 0 };
     uint8_t Y_H_M_out_result[N] = { 0 };
     uint8_t Y_L_M_out_result[N] = { 0 };
     uint8_t Z_H_M_out_result[N] = { 0 };
     uint8_t Z_L_M_out_result[N] = { 0 };


     double out_buffer_X_H_M[N] = { 0.0 };
     double out_buffer_X_L_M[N] = { 0.0 };
     double out_buffer_Y_H_M[N] = { 0.0 };
     double out_buffer_Y_L_M[N] = { 0.0 };
     double out_buffer_Z_H_M[N] = { 0.0 };
     double out_buffer_Z_L_M[N] = { 0.0 };
     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_CRB_REG_M, &CTRLB, 1);


     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_H_M, buffer, 1);
     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_X_L_M, buffer + 1, 1);
     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_H_M, buffer + 2, 1);
     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Y_L_M, buffer + 3, 1);
     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_H_M, buffer + 4, 1);
     LSM303DLHC_Read(MAG_I2C_ADDRESS, LSM303DLHC_OUT_Z_L_M, buffer + 5, 1);
     for (i = 0; i < N; i++) {
          X_H_M_outbuff[i] = buffer[0];
          X_L_M_outbuff[i] = buffer[1];
          Y_H_M_outbuff[i] = buffer[2];
          Y_L_M_outbuff[i] = buffer[3];
          Z_H_M_outbuff[i] = buffer[4];
          Z_L_M_outbuff[i] = buffer[5];


          X_H_M_out_result[i] = (X_H_M_outbuff[i] ^ 0xFF) + 0x01;
          X_L_M_out_result[i] = (X_L_M_outbuff[i] ^ 0xFF) + 0x01;
          Y_H_M_out_result[i] = (Y_H_M_outbuff[i] ^ 0xFF) + 0x01;
          Y_L_M_out_result[i] = (Y_L_M_outbuff[i] ^ 0xFF) + 0x01;
          Z_H_M_out_result[i] = (Z_H_M_outbuff[i] ^ 0xFF) + 0x01;
          Z_L_M_out_result[i] = (Z_L_M_outbuff[i] ^ 0xFF) + 0x01;
     }
     memcpy(out_buffer_X_H_M, X_H_M_out_result, N);
     memcpy(out_buffer_X_L_M, X_L_M_out_result, N);
     memcpy(out_buffer_Y_H_M, Y_H_M_out_result, N);
     memcpy(out_buffer_Y_L_M, Y_L_M_out_result, N);
     memcpy(out_buffer_Z_H_M, Z_H_M_out_result, N);
     memcpy(out_buffer_Z_L_M, Z_L_M_out_result, N);


     kalman_filtering(out_buffer_X_H_M, Q);
     kalman_filtering(out_buffer_X_L_M, Q);
     kalman_filtering(out_buffer_Y_H_M, Q);
     kalman_filtering(out_buffer_Y_L_M, Q);
     kalman_filtering(out_buffer_Z_L_M, Q);
     kalman_filtering(out_buffer_Z_H_M, Q);
}




Regards
Manish Baing

Outcomes