cancel
Showing results for 
Search instead for 
Did you mean: 

is there a timing diagram or procedural sequence of the LSM6DSL with I2C?

Aatif Shaikh1
Associate III

Hello everyone,

I'm looking for a basic timing diagram or procedural sequence of the LSM6DSL with I2C interface, which could explain me the working flow, reading and writing of register, I2C configurations, etc. At the moment, I just wanted to read the acceleration and angular movement. In future, I might want to implement the temperature sensing as well. Unfortunately, I'm not able to find any useful resources which guild me to complete my lower level initialization. Can anyone help me with a sample code, referential document (other than datasheet)? Also, does the temperature sensor gives the temperature reading of surrounding or the IC's temperature?

I've interface the LSM6DSL on STM32F103CBT6 (I2C1),

I'm using standard peripheral.

@Miroslav BATEK​ 

@Eleon BORLINI​ 

0690X00000ByBlbQAF.png

3 REPLIES 3
Eleon BORLINI
ST Employee

Hi @Community member​ ,

>> Can anyone help me with a sample code, referential document (other than datasheet)?

Since I2C is a standard communication protocol, there are a lot of complete descriptions in literature... I2C communication is also well described in the LSM6DSL datasheet p.38 and sgg

0690X00000ByWUvQAN.png

You can automatically configure the STM32 I2C peripheral though the STM32CubeIDE.

For the specific data to write via I2C you can refer to the github repository for the LSM6DSL.

>> Also, does the temperature sensor gives the temperature reading of surrounding or the IC's temperature?

Are you referring to the embedded LSM6DSL temperature sensor? If so, please note first that this sensor is not intended to be an accurate sensor, the offset can be between +-15°C, and t will measure mainly the IC temperature. To get a proper environmental reading, you have to use a standalone temperature sensor like STTS22H and following the standard mounting guidelines (example).

To understand in detail your problem, you should send us the oscilloscope I2C pattern...

Regards

Thanks for your response @Eleon BORLINI​, the above configuration seems to work perfectly fine. I'm able to read and write and able to communicate with IC, but I have got a question regarding the acceleration reading values. In the sample code, I've seen that we're reading the gravitational force applied on the different axis and based on that we're deciding the rate of acceleration force, is that correct?

How could I configure my device such that I'll get the "movement-based" acceleration reading when the device moves horizontally (probably in any one direction), I'll get the corresponding reading? 

Currently, I'm planning to use it in the car's motion detection system, where I need to capture harsh acceleration and harsh break.

 /* Read magnetic field data */
memset(stVarACCMTRVar_All.unRawAcceleration.u8bit, NULL , 
_DNumber_3 * sizeof(int16_t));
lsm6dsl_acceleration_raw_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR,
stVarACCMTRVar_All.unRawAcceleration.u8bit);
			
stVarACCMTRVar_All.flAcclerationG_1 = LSM6DSL_FROM_FS_2g_TO_g
(stVarACCMTRVar_All.unRawAcceleration.i16bit[0]);
stVarACCMTRVar_All.flAcclerationG_2 = LSM6DSL_FROM_FS_2g_TO_g
(stVarACCMTRVar_All.unRawAcceleration.i16bit[1]);
stVarACCMTRVar_All.flAcclerationG_3 = LSM6DSL_FROM_FS_2g_TO_g
(stVarACCMTRVar_All.unRawAcceleration.i16bit[2]); 
 
printf ( "Acceleration [g]   :%4.2f      %4.2f      %4.2f\r\n",
stVarACCMTRVar_All.flAcclerationG_1, 
stVarACCMTRVar_All.flAcclerationG_2,
stVarACCMTRVar_All.flAcclerationG_3 );
 

Aatif Shaikh1
Associate III

I'm trying to get the motion's intimation from the IC, but unfortunately, I've failed to get any successful response at all. I am uploading a snip-it of my code, can anyone help me in understanding where did I go wrong? I've tried with default configuration (without initializing the threshold value) as well, but no positive result.

void FnAccParaInit (void)
{
stVarACCMTRVar_All.stVarACCMTRSTACKPTR
.write_reg  =  FnACCMTRPlatformWrite		 ;
stVarACCMTRVar_All.stVarACCMTRSTACKPTR
.read_reg  =  FnACCMTRPlatformRead		 ;
stVarACCMTRVar_All.stVarACCMTRSTACKPTR
.handle  	= NULL ;  
 
		
lsm6dsl_device_id_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
&stVarACCMTRVar_All.stVarACCMTRConfig.ucDeviceID );
		
	
#ifdef _USE_DEBUG_ACCMTR
	    _DEBUG_ALL_ENABLE_DIABLE	
	      printf ("ACCELEROMETER ID = %x \n\r",
	      stVarACCMTRVar_All.stVarACCMTRConfig.ucDeviceID);
#endif
			
if( LSM6DSL_ID != stVarACCMTRVar_All
   .stVarACCMTRConfig.ucDeviceID		)
{
  stVarACCMTRVar_All.stVarACCMTRConfig
  .ucAccelerometerActive = RESET ;
   #ifdef _USE_DEBUG_ACCMTR
	      _DEBUG_ALL_ENABLE_DIABLE	
		printf ("ACCELEROMETER IS NOT WORKING\n\r" );
   #endif	
return _DNumber_1 ;	
}
else
{
  stVarACCMTRVar_All.stVarACCMTRConfig
  .ucAccelerometerActive = SET ;
   #ifdef _USE_DEBUG_ACCMTR
	       _DEBUG_ALL_ENABLE_DIABLE	
		 printf ("ACCELEROMETER IS WORKING\n\r" );
    #endif	
}		
	
// Restore default configuration
   lsm6dsl_reset_set(&stVarACCMTRVar_All
  .stVarACCMTRSTACKPTR, PROPERTY_ENABLE);
 
do 
{
   lsm6dsl_reset_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
  &stVarACCMTRVar_All.stVarACCMTRConfig.ucDeviceReset);
 }
 while (stVarACCMTRVar_All.stVarACCMTRConfig.ucDeviceReset);
	
// Enable Block Data Update
 lsm6dsl_block_data_update_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, PROPERTY_ENABLE);
 
// Set Output Data Rate
  lsm6dsl_xl_data_rate_set(&stVarACCMTRVar_All
  .stVarACCMTRSTACKPTR, LSM6DSL_XL_ODR_12Hz5);
 lsm6dsl_gy_data_rate_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, LSM6DSL_GY_ODR_12Hz5);
 
// Set full scale
 lsm6dsl_xl_full_scale_set(&stVarACCMTRVar_All
 .stVarACCMTRSTACKPTR, LSM6DSL_2g);
 lsm6dsl_gy_full_scale_set(&stVarACCMTRVar_All
 .stVarACCMTRSTACKPTR, LSM6DSL_2000dps);
 
lsm6dsl_motion_sens_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, PROPERTY_ENABLE);
do
 {
	lsm6dsl_motion_sens_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
	&stVarACCMTRVar_All.stVarACCMTRConfig.ucAccelerometerEnable);
 }
 while (stVarACCMTRVar_All.stVarACCMTRConfig.ucAccelerometerEnable != PROPERTY_ENABLE );
		 		 
uint8_t ucMotionSensorThreshold [ _DNumber_2 ];
ucMotionSensorThreshold [ _DNumber_0 ] = _DNumber_2 ;
lsm6dsl_motion_threshold_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, ucMotionSensorThreshold ); 
		 
// Configure filtering chain(No aux interface)
// Accelerometer - analog filter
lsm6dsl_xl_filter_analog_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, LSM6DSL_XL_ANA_BW_400Hz);
		
/* Accelerometer - LPF1 + LPF2 path */   
lsm6dsl_xl_lp2_bandwidth_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, LSM6DSL_XL_LOW_NOISE_LP_ODR_DIV_100);
		
/* Gyroscope - filtering chain */
lsm6dsl_gy_band_pass_set(&stVarACCMTRVar_All
.stVarACCMTRSTACKPTR, LSM6DSL_HP_260mHz_LP1_STRONG);	 
 
#ifdef _USE_DEBUG_ACCMTR
	    _DEBUG_ALL_ENABLE_DIABLE	
	    printf ("ACCELEROMETER PARA INIT COMPLETE\n\r" );
#endif	
	
return _DNumber_0 ;
}
 
 
void FnACCMTRScanAndRead(void)
{
 
lsm6dsl_status_reg_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
&stVarACCMTRVar_All.stVarACCMTRSTACKREG.status_reg); 
		
lsm6dsl_all_sources_t stVarlsm6dsl_all_sources_t;
lsm6dsl_all_sources_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
&stVarlsm6dsl_all_sources_t);
	
#if _USE_DEBUG_ACCMTR
      _DEBUG_ALL_ENABLE_DIABLE				
	 printf("MOTION VALUE = %d \n\r",
	 stVarlsm6dsl_all_sources_t.reg.func_src1.sign_motion_ia);	
#endif
	
    if (stVarACCMTRVar_All.stVarACCMTRSTACKREG.status_reg.xlda)
    { 
      /* Read magnetic field data */
      memset(stVarACCMTRVar_All.unRawAcceleration.u8bit, NULL , _DNumber_3 * 
      sizeof(int16_t));
      lsm6dsl_acceleration_raw_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
      stVarACCMTRVar_All.unRawAcceleration.u8bit);
			
      stVarACCMTRVar_All.flAcclerationG_1 = LSM6DSL_FROM_FS_2g_TO_g
     (stVarACCMTRVar_All.unRawAcceleration.i16bit[0]);
      stVarACCMTRVar_All.flAcclerationG_2 = LSM6DSL_FROM_FS_2g_TO_g
     (stVarACCMTRVar_All.unRawAcceleration.i16bit[1]);
      stVarACCMTRVar_All.flAcclerationG_3 = LSM6DSL_FROM_FS_2g_TO_g
      (stVarACCMTRVar_All.unRawAcceleration.i16bit[2]); 
 
      #if _USE_DEBUG_ACCMTR
	    _DEBUG_ALL_ENABLE_DIABLE
	    printf ( "Acceleration [g]   :%4.2f      %4.2f      %4.2f\r\n",
	    stVarACCMTRVar_All.flAcclerationG_1, 
	    stVarACCMTRVar_All.flAcclerationG_2,
	     stVarACCMTRVar_All.flAcclerationG_3 );
       #endif
		
    }
 
    if( stVarACCMTRVar_All.stVarACCMTRSTACKREG.status_reg.gda )
      {
	/* Read magnetic field data */
	 memset(stVarACCMTRVar_All.unRawAngularRate.u8bit,  NULL , _DNumber_3 * 
         sizeof(int16_t));
				 
         lsm6dsl_angular_rate_raw_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
	 stVarACCMTRVar_All.unRawAngularRate.u8bit);
					
	 stVarACCMTRVar_All.angular_rate_mdps[0] = LSM6DSL_FROM_FS_2000dps_TO_mdps
	(stVarACCMTRVar_All.unRawAngularRate.i16bit[0]);
	 stVarACCMTRVar_All.angular_rate_mdps[1] = LSM6DSL_FROM_FS_2000dps_TO_mdps
	(stVarACCMTRVar_All.unRawAngularRate.i16bit[1]);
	 stVarACCMTRVar_All.angular_rate_mdps[2] = LSM6DSL_FROM_FS_2000dps_TO_mdps
	(stVarACCMTRVar_All.unRawAngularRate.i16bit[2]);
			
	#if _USE_DEBUG_ACCMTR
	      _DEBUG_ALL_ENABLE_DIABLE
	      printf( "Angular rate [mdps]:%4.2f      %4.2f     %4.2f\r\n",
	      stVarACCMTRVar_All.angular_rate_mdps[0] ,
	      stVarACCMTRVar_All.angular_rate_mdps[1] ,
	      stVarACCMTRVar_All.angular_rate_mdps[2] );
	#endif		
       }
			
    if ( stVarACCMTRVar_All.stVarACCMTRSTACKREG.status_reg.tda  )
    {  
      // Read temperature data 
          memset( stVarACCMTRVar_All.unRawTemperature.u8bit,  NULL , _DNumber_3 * 
          sizeof(int16_t) );
          lsm6dsl_temperature_raw_get(&stVarACCMTRVar_All.stVarACCMTRSTACKPTR, 
	  stVarACCMTRVar_All.unRawTemperature.u8bit);
          stVarACCMTRVar_All.flTemperatureDegree   = 
			 
          LSM6DSL_FROM_LSB_TO_degC(stVarACCMTRVar_All.unRawTemperature.i16bit[0] );
	  #if _USE_DEBUG_ACCMTR
		_DEBUG_ALL_ENABLE_DIABLE
                   printf("Temperature [degC]:%.2f\r\n\n",
                   stVarACCMTRVar_All.flTemperatureDegree );
	#endif	
    }	
}