2020-02-03 10:06 PM
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
2020-02-05 07:47 AM
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
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
2020-02-07 01:03 AM
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 );
2020-02-07 03:06 AM
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
}
}