Skip to main content
Associate
July 3, 2023
Question

ISM330DLC gyroscope zero offset

  • July 3, 2023
  • 2 replies
  • 1884 views

Hello,

Overview: STM32F4 talks to an ISM330DLC (SPI serial interface) using the ST library. (https://github.com/zephyrproject-rtos/hal_st/blob/master/sensor/stmemsc/ism330dlc_STdC/driver/ism330dlc_reg.c)

Problem: I have 5 boards, device at zero level, 4 of the boards output an angular rate X dps around 0.5 dps and 1 of the board output an angular rate X dps between 3 dps and 4 dps. Datasheet says angular rate zero level should be within +/- 2 dps. (https://www.st.com/resource/en/datasheet/ism330dlc.pdf)

The 5 boards have an ISM330DLC fitted on them, same orientation and same software running.

here's the settings used:

 

 

uint8_t ISM330DLC_Setup(void)
{
uint8_t rst;

 /*
 * Initialize mems driver interface
 */
 dev_ctx.write_reg = platform_write;
 dev_ctx.read_reg = platform_read;
 /*
 * Check device ID
 */
 ism330_dev_id = 0;
 (void)ism330dlc_device_id_get(&dev_ctx, &ism330_dev_id);
 if(ism330_dev_id != ISM330DLC_ID)
 {
 return ism330_dev_id;
 }
 /*
 * Restore default configuration
 */
 (void)ism330dlc_reset_set(&dev_ctx, PROPERTY_ENABLE);
 do {
 (void)ism330dlc_reset_get(&dev_ctx, &rst);
 } while (rst != 0U);
 /*
 * Enable Block Data Update
 */
 (void)ism330dlc_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
 /*
 * Set Output Data Rate
 */
 (void)ism330dlc_xl_data_rate_set(&dev_ctx, ISM330DLC_XL_ODR_833Hz);
 (void)ism330dlc_gy_data_rate_set(&dev_ctx, ISM330DLC_GY_ODR_833Hz);
 /*
 * Set full scale
 */
 (void)ism330dlc_xl_full_scale_set(&dev_ctx, ISM330DLC_4g);
 (void)ism330dlc_gy_full_scale_set(&dev_ctx, ISM330DLC_125dps);

 /*
 * Select high-performance measurement mode
 */
 (void)ism330dlc_xl_power_mode_set(&dev_ctx, ISM330DLC_XL_HIGH_PERFORMANCE);
 (void)ism330dlc_gy_power_mode_set(&dev_ctx, ISM330DLC_GY_HIGH_PERFORMANCE);

 /*
 * Configure filtering chain(No aux interface)
 */
 /* Accelerometer - analog filter */
 (void)ism330dlc_xl_filter_analog_set(&dev_ctx, ISM330DLC_XL_ANA_BW_400Hz);

 /* Accelerometer - LPF1 path ( LPF2 not used )*/
 //(void)ism330dlc_xl_lp1_bandwidth_set(&dev_ctx, ISM330DLC_XL_LP1_ODR_DIV_4);

 /* Accelerometer - LPF1 + LPF2 path */
 (void)ism330dlc_xl_lp2_bandwidth_set(&dev_ctx, ISM330DLC_XL_LOW_NOISE_LP_ODR_DIV_100);

 /* Accelerometer - High Pass / Slope path */
 //(void)ism330dlc_xl_reference_mode_set(&dev_ctx, PROPERTY_DISABLE);
 //(void)ism330dlc_xl_hp_bandwidth_set(&dev_ctx, ISM330DLC_XL_HP_ODR_DIV_100);

 /* Gyroscope - filtering chain */
 //(void)ism330dlc_gy_band_pass_set(&dev_ctx, ISM330DLC_HP_65mHz_LP1_NORMAL);

 /* All ok */
 return(ism330_dev_id);
}

 

 

Changing the filtering chain to any of the values (light, normal, etc.) doesn't help and smoothed the angular rate too much.

Any idea of what I am missing here?

Thanks

This topic has been closed for replies.

2 replies

Federica Bossi
Technical Moderator
July 7, 2023

Hi @cbaron ,

Welcome to ST Community!

I don't see anything wrong in the configuration, can you please share the reading procedure too? 

Are you acquiring the sensors synchronously by polling data ready?

I'm asking this because I don't see an interrupt configured.  

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
cbaronAuthor
Associate
July 10, 2023

HI @Federica Bossi,

Please find the reading function below, this is called every 10ms and yes polling data ready, the "platform_wirte" and "platform_read" function pointers are being called from the ST IMS330 library where I read/write SPI data.

uint8_t ISM330DLC_Proc(struct Ism330DlcStruct * a_ism330dlc_out)
{
ism330dlc_reg_t reg;

 if(!ism330dlc_status_reg_get(&dev_ctx, &reg.status_reg))
 {
 if(reg.status_reg.xlda != 0U)
 {
 (void)memset(&data_raw_acceleration[0], 0, 3U * sizeof(int16_t));
 // Read data
 if(!ism330dlc_acceleration_raw_get(&dev_ctx, &data_raw_acceleration[0]))
 {
 a_ism330dlc_out->m_acc_x_mg = ism330dlc_from_fs4g_to_mg(data_raw_acceleration[0]);
 a_ism330dlc_out->m_acc_y_mg = ism330dlc_from_fs4g_to_mg(data_raw_acceleration[1]);
 a_ism330dlc_out->m_acc_z_mg = ism330dlc_from_fs4g_to_mg(data_raw_acceleration[2]);
 a_ism330dlc_out->m_acc_angle_x_deg=ISM330DLC_ToAngleX(a_ism330dlc_out->m_acc_x_mg, a_ism330dlc_out->m_acc_y_mg, a_ism330dlc_out->m_acc_z_mg);
 a_ism330dlc_out->m_acc_angle_y_deg=ISM330DLC_ToAngleY(a_ism330dlc_out->m_acc_x_mg, a_ism330dlc_out->m_acc_y_mg, a_ism330dlc_out->m_acc_z_mg);
 a_ism330dlc_out->m_acc_angle_z_deg=ISM330DLC_ToAngleZ(a_ism330dlc_out->m_acc_x_mg, a_ism330dlc_out->m_acc_y_mg, a_ism330dlc_out->m_acc_z_mg);
 }
 }
 if(reg.status_reg.gda != 0U)
 {
 (void)memset(&data_raw_angular_rate[0], 0, 3U * sizeof(int16_t));
 // Read data
 if(!ism330dlc_angular_rate_raw_get(&dev_ctx, &data_raw_angular_rate[0]))
 {
 a_ism330dlc_out->m_angular_rate_x_mdps = ism330dlc_from_fs125dps_to_mdps(data_raw_angular_rate[0]);
 a_ism330dlc_out->m_angular_rate_y_mdps = ism330dlc_from_fs125dps_to_mdps(data_raw_angular_rate[1]);
 a_ism330dlc_out->m_angular_rate_z_mdps = ism330dlc_from_fs125dps_to_mdps(data_raw_angular_rate[2]);
 }
 }
 if(reg.status_reg.tda != 0U)
 {
 (void)memset(&data_raw_temperature, 0, sizeof(int16_t));
 // Read temperature data
 if(!ism330dlc_temperature_raw_get(&dev_ctx, &data_raw_temperature))
 {
 a_ism330dlc_out->m_temperature_degC = ism330dlc_from_lsb_to_celsius(data_raw_temperature);
 }
 }
 }
 return(reg.status_reg.xlda | reg.status_reg.gda | reg.status_reg.tda);
}

 Thanks,
Christophe

niccolò
ST Employee
July 11, 2023

Hi @cbaron ,

the gyroscope offset level can vary when the sensor is soldered on a board, due to mechanical and thermal stress, if the soldering tips were not followed, maybe that is the reason why this occurs?
have you soldered the sensors personally? if not, can you ask the one who did it if they followed the tips shown here?

also, the offset can slightly vary with temperature, did you perform the measurements with the same environmental conditions?

Niccolò