cancel
Showing results for 
Search instead for 
Did you mean: 

ISM330DLC gyroscope zero offset

cbaron
Associate

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

3 REPLIES 3
Federica Bossi
ST Employee

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.

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

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ò