cancel
Showing results for 
Search instead for 
Did you mean: 

MotionDI_update doesn't seem to be working

tkheang
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions

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

View solution in original post

8 REPLIES 8
Miroslav BATEK
ST Employee

Hello,

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

tkheang
Associate II

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

Miroslav BATEK
ST Employee

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.

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.

Miroslav BATEK
ST Employee

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.

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].

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

After setting the knobs parameters, the MotionDI library works. Thank you!