Skip to main content
Visitor II
July 6, 2021
Solved

MotionDI_update doesn't seem to be working

  • July 6, 2021
  • 4 replies
  • 3144 views

Hello,

I'm trying to use the MotionDI library for a dynamic inclinometer application. My IMU is the LSM9DS1. The returned data from MotionDI_update() is shown below:

0693W00000Bczh6QAB.pngThe values for rotation, quaternion, gravity, and linear acceleration never change, even when the IMU is moved. I initialized the MotionDI library according to the sample code in the documentation:

float freq = 100.0f;
MDI_knobs_t iKnobs;
MDI_knobs_t *ipKnobs = &iKnobs;
 
int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 MX_I2C1_Init();
 MX_CRC_Init();
 MX_NVIC_Init();
 
 MotionDI_Initialize(&freq);
 MotionDI_setKnobs(ipKnobs);
 
 while (1)
 {
 lsm9ds1_read_data_polling();
 }
}

The lsm9ds1_read_data_polling() function is from an LSM9DS1 driver sample code and handles the initialization and reading of data for the IMU. In that function's while loop I have the following:

while (1) {
 /* Read device status register */
 lsm9ds1_dev_status_get(&dev_ctx_mag, &dev_ctx_imu, &reg);
 
 if ( reg.status_imu.xlda && reg.status_imu.gda ) {
 /* Read imu data */
 memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
 memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
 lsm9ds1_acceleration_raw_get(&dev_ctx_imu,data_raw_acceleration);
 lsm9ds1_angular_rate_raw_get(&dev_ctx_imu,data_raw_angular_rate);
 
 acceleration_mg[0] = lsm9ds1_from_fs2g_to_mg(data_raw_acceleration[0]);
 acceleration_mg[1] = lsm9ds1_from_fs2g_to_mg(data_raw_acceleration[1]);
 acceleration_mg[2] = lsm9ds1_from_fs2g_to_mg(data_raw_acceleration[2]);
 
 angular_rate_mdps[0] = lsm9ds1_from_fs2000dps_to_mdps(data_raw_angular_rate[0]);
 angular_rate_mdps[1] = lsm9ds1_from_fs2000dps_to_mdps(data_raw_angular_rate[1]);
 angular_rate_mdps[2] = lsm9ds1_from_fs2000dps_to_mdps(data_raw_angular_rate[2]);
 
 // Process MEMS data in MotionDI
 data_in.Acc[0] = acceleration_mg[0] / 1000;
 data_in.Acc[1] = acceleration_mg[1] / 1000;
 data_in.Acc[2] = acceleration_mg[2] / 1000;
 
 data_in.Gyro[0] = angular_rate_mdps[0] / 1000;
 data_in.Gyro[1] = angular_rate_mdps[1] / 1000;
 data_in.Gyro[2] = angular_rate_mdps[2] / 1000;
 
 data_in.Timestamp = HAL_GetTick() * 1000;
 
 MotionDI_update(&data_out, &data_in);
 
 sprintf((char *)tx_buffer, "Timestamp: %d us\r\n", data_in.Timestamp);
 tx_com(tx_buffer, strlen((char const *)tx_buffer));
 
 sprintf((char *)tx_buffer,
 "IMU (Raw) - [g]: %4.2f\t%4.2f\t%4.2f\t[dps]:%4.2f\t%4.2f\t%4.2f\r\n",
 data_in.Acc[0], data_in.Acc[1], data_in.Acc[2],
 data_in.Gyro[0], data_in.Gyro[1], data_in.Gyro[2]);
 tx_com(tx_buffer, strlen((char const *)tx_buffer));
 
 sprintf((char *)tx_buffer,
		"IMU (MotionDI) - [g]: %4.2f\t%4.2f\t%4.2f\t[dps]:%4.2f\t%4.2f\t%4.2f\r\n\n",
		data_out.linear_acceleration[0], data_out.linear_acceleration[1], 
 data_out.linear_acceleration[2],
	 data_out.rotation[0], data_out.rotation[1], data_out.rotation[2]);
 tx_com(tx_buffer, strlen((char const *)tx_buffer));
 }
 HAL_Delay(100);
}

Is there anything that could be the problem? Thanks.

    This topic has been closed for replies.
    Best answer by Miroslav BATEK

    OK, the data are OK. I'm able to get correct output values from MotionDI library using your data.

    I checked you code and I see you call MotionDI_setKnobs(ipKnobs); function without settings the knobs parameters.

    You can check application example in X_CUBE-MEMS1 package.

    You should read the default knobs settings and the modify the only settings you need.

     MotionDI_getKnobs(ipKnobs);

     ipKnobs->AccKnob.CalType = MDI_CAL_CONTINUOUS;

     ipKnobs->GyrKnob.CalType = MDI_CAL_CONTINUOUS;

     BSP_SENSOR_ACC_GetOrientation(ipKnobs->AccOrientation);

     BSP_SENSOR_GYR_GetOrientation(ipKnobs->GyroOrientation);

     ipKnobs->SFKnob.output_type = MDI_ENGINE_OUTPUT_ENU;

     ipKnobs->SFKnob.modx = DECIMATION;

     MotionDI_setKnobs(ipKnobs);

    4 replies

    ST Employee
    July 15, 2021

    Hello,

    can you please share datalog with accelerometer and gyroscope data which you pass to the library?

    tkheangAuthor
    Visitor II
    July 15, 2021

    Hi Miroslav,

    By datalog do you mean the output on the serial monitor? If so here it is, with the IMU tilted 45 degrees:

    0693W00000CzkRrQAJ.png

    ST Employee
    July 16, 2021

    By datalog, I mean text file (ideally csv) in which you record like 30 seconds of the accelerometer and gyroscope data which you pass to the library.

    tkheangAuthor
    Visitor II
    July 16, 2021

    Here is the datalog. Each row has data_in.Timestamp, data_in.Acc[0], data_in.Acc[1], data_in.Acc[2], data_in.Gyro[0], data_in.Gyro[1], data_in.Gyro[2] in that order. The IMU is laid flat on a vibrating surface with the Z axis pointing up.

    ST Employee
    July 19, 2021

    Thank you for the datalog, the data from accelerometer and gyroscope looks good, but your update data rate is low. I see the update data period is about 115ms.

    Can you please update your code to increase the speed so the period is ideally 10ms.

    tkheangAuthor
    Visitor II
    July 22, 2021

    I increased the speed to 10ms but the output still hasn't changed. I've attached another datalog, this time with the outputs in addition to the inputs. Each row is data_in.Timestamp, data_in.Acc[0], data_in.Acc[1], data_in.Acc[2], data_in.Gyro[0], data_in.Gyro[1], data_in.Gyro[2], data_out.linear_acceleration[0], data_out.linear_acceleration[1], data_out.linear_acceleration[2], data_out.rotation[0], data_out.rotation[1], data_out.rotation[2].

    ST Employee
    July 26, 2021

    OK, the data are OK. I'm able to get correct output values from MotionDI library using your data.

    I checked you code and I see you call MotionDI_setKnobs(ipKnobs); function without settings the knobs parameters.

    You can check application example in X_CUBE-MEMS1 package.

    You should read the default knobs settings and the modify the only settings you need.

     MotionDI_getKnobs(ipKnobs);

     ipKnobs->AccKnob.CalType = MDI_CAL_CONTINUOUS;

     ipKnobs->GyrKnob.CalType = MDI_CAL_CONTINUOUS;

     BSP_SENSOR_ACC_GetOrientation(ipKnobs->AccOrientation);

     BSP_SENSOR_GYR_GetOrientation(ipKnobs->GyroOrientation);

     ipKnobs->SFKnob.output_type = MDI_ENGINE_OUTPUT_ENU;

     ipKnobs->SFKnob.modx = DECIMATION;

     MotionDI_setKnobs(ipKnobs);