Skip to main content
Visitor II
February 4, 2020
Question

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

  • February 4, 2020
  • 2 replies
  • 820 views

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

    This topic has been closed for replies.

    2 replies

    ST Employee
    February 5, 2020

    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

    Visitor II
    February 7, 2020

    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 );
     

    Visitor II
    February 7, 2020

    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	
     }	
    }