Skip to main content
Visitor II
June 23, 2020
Solved

Motionfx problems with quaternions

  • June 23, 2020
  • 2 replies
  • 1525 views

Hello I have previous implemented the motionfx to get quartenions using lsm6dsl and lsm303agr over i2c, and everything was working great. Now I changed the sensor lsm6dsl with lsm6dsox who is communicating over spi with stm and lsm303agr in mode2(spi-to-i2c). I have configure it the same way as it was working with the old sensor. But now If I leave the board still on the table not moving, the quartenions are changing from -0.9 to 0.9 like there are incrementing. I tried to change the orientation,data_rate,sensitivity, but nothing. I checked the raw data from the sensors and seems ok,values are stable, but still getting weird quartenions. I can confirm that read and write are working for all sensors.

    This topic has been closed for replies.
    Best answer by suads

    Hi Eleon, to sync I m using Sensor hub trigger signal setting lsm6dsox_sh_syncro_mode_set(&dev,LSM6DSOX_XL_GY_DRDY); and setting the sh_data_rate to 100hz, and I m setting the output data rate from all sensors to 100hz. Here are my settings:

    while(LSM6DSOX_ID!=whoamI)
     {
     whoamI = 0;
     lsm6dsox_device_id_get(&lsm6dsox, &whoamI);
     printf("LSM6DSOX_ID %x=%x\n", LSM6DSOX_ID, whoamI);
     }
     
     /* Restore default configuration. */
     lsm6dsox_reset_set(&lsm6dsox, PROPERTY_ENABLE);
     do
     {
     lsm6dsox_reset_get(&lsm6dsox, &rst);
     } while(rst);
     /* Disable I3C interface. */
     lsm6dsox_i3c_disable_set(&lsm6dsox, LSM6DSOX_I3C_DISABLE); 
     
     
     while(whoamI != LSM303AGR_ID_XL)
     {
     lsm303agr_xl_device_id_get(&lsm303agr_acc, &whoamI);
     printf("LSM303AGR_ID_ACCELOMETER %x=%x\n", LSM303AGR_ID_XL,
     whoamI);
     }
     
     
     while(whoamI != LSM303AGR_ID_MG)
     {
     lsm303agr_mag_device_id_get(&lsm303agr_mag, &whoamI);
     printf("LSM303AGR_ID_MAGNETOMETER %x=%x\n", LSM303AGR_ID_MG,
     whoamI);
     }
     
    /*Configure Full scale xl and gy*/
     lsm6dsox_xl_full_scale_set(&lsm6dsox, LSM6DSOX_2g);
     lsm6dsox_gy_full_scale_set(&lsm6dsox, LSM6DSOX_2000dps);
     
     /*lsm303agr mag Set BDU,data rate,fullscale,operating mode,Sensor Hub Slave0*/
     lsm303agr_mag_block_data_update_set(&lsm303agr_mag, PROPERTY_ENABLE);
     lsm303agr_mag_data_rate_set(&lsm303agr_mag, LSM303AGR_MG_ODR_100Hz);
     lsm303agr_mag_set_rst_mode_set(&lsm303agr_mag,
    LSM303AGR_SENS_OFF_CANC_EVERY_ODR); 
     lsm303agr_mag_operating_mode_set(&lsm303agr_mag,LSM303AGR_CONTINUOUS_MODE);
     lsm6dsox_sh_slv0_cfg_read(&lsm6dsox, &mag_conf);
     
     /*lsm303agr xl Set BDU,data rate,fullscale,operating mode,Sensor Hub Slave1*/
     lsm303agr_xl_block_data_update_set(&lsm303agr_acc, PROPERTY_ENABLE);
     lsm303agr_xl_data_rate_set(&lsm303agr_acc, LSM303AGR_XL_ODR_100Hz);
     lsm303agr_xl_full_scale_set(&lsm303agr_acc, LSM303AGR_2g);
     lsm303agr_xl_operating_mode_set(&lsm303agr_acc, LSM303AGR_LP_8bit);
     lsm6dsox_sh_slv1_cfg_read(&lsm6dsox, &acc_conf);
     
     
     /*lsm6dsox enable Master and set BDU,ODR,number of slaves,Sensor hub trigger signal*/
     lsm6dsox_sh_master_set(&lsm6dsox, PROPERTY_ENABLE);
     lsm6dsox_xl_data_rate_set(&lsm6dsox, LSM6DSOX_XL_ODR_104Hz);
     lsm6dsox_gy_data_rate_set(&lsm6dsox, LSM6DSOX_XL_ODR_104Hz);
     lsm6dsox_sh_data_rate_set(&lsm6dsox, LSM6DSOX_SH_ODR_104Hz);
     lsm6dsox_sh_slave_connected_set(&lsm6dsox, LSM6DSOX_SLV_0_1);
     lsm6dsox_block_data_update_set(&lsm6dsox, PROPERTY_ENABLE);
     lsm6dsox_sh_syncro_mode_set(&lsm6dsox,LSM6DSOX_XL_GY_DRDY);
     
     /*After this I m reading the status flags and raw data and multple it with numbers according to datasheet */
     lsm6dsox_xl_flag_data_ready_get(&lsm6dsox, &drdy); and the reading the raw data
     lsm6dsox_acceleration_raw_get(&lsm6dsox, data_raw.u8bit);
     lsm6dsox_sh_read_data_raw_get(&lsm6dsox, (uint8_t*)&emb_sh,18);
     /*and for gyro*/
     lsm6dsox_gy_flag_data_ready_get(&lsm6dsox, &drdy);
     lsm6dsox_angular_rate_raw_get(&lsm6dsox, data_raw.u8bit);
     
     

    I have a question?

    according to the datasheet:

    "When this bit is set to 0, the accelerometer/gyroscope sensor has to be active (not in Power-Down mode) and the sensor hub trigger signal is the accelerometer/gyroscope data-ready signal.

    When this bit is set to 1, at least one sensor between the accelerometer and the gyroscope has to be active and the sensor hub trigger signal is the INT2 pin."

    In lsm6dsox_reg.h file

    typedef enum {
     LSM6DSOX_EXT_ON_INT2_PIN = 0,
     LSM6DSOX_XL_GY_DRDY = 1,
    } lsm6dsox_start_config_t;

    Shouldn't it be the opposite way?

    LSM6DSOX_EXT_ON_INT2_PIN = 1

     LSM6DSOX_XL_GY_DRDY  = 0

    2 replies

    ST Employee
    June 25, 2020

    Hi @suads​ , since the lsm6dsox is (almost on all parameters) more accurate than the lsm6dsl and the X-NUCLEO-IKS01A3 shield has a lsm6dso onboard, i believe it is some issue coming from the synchronization of the device, resulting in a misalignment on the output signals that are mixed together in the sensor fusion of the MotionFX library. This may result in an "integration" error that increase progressively the quaternions value without a real movement. How are you synchronizing the sensor output data? I suggest you to check the X-CUBE-MEMS1 Example in Projects\STM32F401RE-Nucleo\Applications\IKS01A3\DataLogFusion folder. Regards

    suadsAuthorAnswer
    Visitor II
    June 29, 2020

    Hi Eleon, to sync I m using Sensor hub trigger signal setting lsm6dsox_sh_syncro_mode_set(&dev,LSM6DSOX_XL_GY_DRDY); and setting the sh_data_rate to 100hz, and I m setting the output data rate from all sensors to 100hz. Here are my settings:

    while(LSM6DSOX_ID!=whoamI)
     {
     whoamI = 0;
     lsm6dsox_device_id_get(&lsm6dsox, &whoamI);
     printf("LSM6DSOX_ID %x=%x\n", LSM6DSOX_ID, whoamI);
     }
     
     /* Restore default configuration. */
     lsm6dsox_reset_set(&lsm6dsox, PROPERTY_ENABLE);
     do
     {
     lsm6dsox_reset_get(&lsm6dsox, &rst);
     } while(rst);
     /* Disable I3C interface. */
     lsm6dsox_i3c_disable_set(&lsm6dsox, LSM6DSOX_I3C_DISABLE); 
     
     
     while(whoamI != LSM303AGR_ID_XL)
     {
     lsm303agr_xl_device_id_get(&lsm303agr_acc, &whoamI);
     printf("LSM303AGR_ID_ACCELOMETER %x=%x\n", LSM303AGR_ID_XL,
     whoamI);
     }
     
     
     while(whoamI != LSM303AGR_ID_MG)
     {
     lsm303agr_mag_device_id_get(&lsm303agr_mag, &whoamI);
     printf("LSM303AGR_ID_MAGNETOMETER %x=%x\n", LSM303AGR_ID_MG,
     whoamI);
     }
     
    /*Configure Full scale xl and gy*/
     lsm6dsox_xl_full_scale_set(&lsm6dsox, LSM6DSOX_2g);
     lsm6dsox_gy_full_scale_set(&lsm6dsox, LSM6DSOX_2000dps);
     
     /*lsm303agr mag Set BDU,data rate,fullscale,operating mode,Sensor Hub Slave0*/
     lsm303agr_mag_block_data_update_set(&lsm303agr_mag, PROPERTY_ENABLE);
     lsm303agr_mag_data_rate_set(&lsm303agr_mag, LSM303AGR_MG_ODR_100Hz);
     lsm303agr_mag_set_rst_mode_set(&lsm303agr_mag,
    LSM303AGR_SENS_OFF_CANC_EVERY_ODR); 
     lsm303agr_mag_operating_mode_set(&lsm303agr_mag,LSM303AGR_CONTINUOUS_MODE);
     lsm6dsox_sh_slv0_cfg_read(&lsm6dsox, &mag_conf);
     
     /*lsm303agr xl Set BDU,data rate,fullscale,operating mode,Sensor Hub Slave1*/
     lsm303agr_xl_block_data_update_set(&lsm303agr_acc, PROPERTY_ENABLE);
     lsm303agr_xl_data_rate_set(&lsm303agr_acc, LSM303AGR_XL_ODR_100Hz);
     lsm303agr_xl_full_scale_set(&lsm303agr_acc, LSM303AGR_2g);
     lsm303agr_xl_operating_mode_set(&lsm303agr_acc, LSM303AGR_LP_8bit);
     lsm6dsox_sh_slv1_cfg_read(&lsm6dsox, &acc_conf);
     
     
     /*lsm6dsox enable Master and set BDU,ODR,number of slaves,Sensor hub trigger signal*/
     lsm6dsox_sh_master_set(&lsm6dsox, PROPERTY_ENABLE);
     lsm6dsox_xl_data_rate_set(&lsm6dsox, LSM6DSOX_XL_ODR_104Hz);
     lsm6dsox_gy_data_rate_set(&lsm6dsox, LSM6DSOX_XL_ODR_104Hz);
     lsm6dsox_sh_data_rate_set(&lsm6dsox, LSM6DSOX_SH_ODR_104Hz);
     lsm6dsox_sh_slave_connected_set(&lsm6dsox, LSM6DSOX_SLV_0_1);
     lsm6dsox_block_data_update_set(&lsm6dsox, PROPERTY_ENABLE);
     lsm6dsox_sh_syncro_mode_set(&lsm6dsox,LSM6DSOX_XL_GY_DRDY);
     
     /*After this I m reading the status flags and raw data and multple it with numbers according to datasheet */
     lsm6dsox_xl_flag_data_ready_get(&lsm6dsox, &drdy); and the reading the raw data
     lsm6dsox_acceleration_raw_get(&lsm6dsox, data_raw.u8bit);
     lsm6dsox_sh_read_data_raw_get(&lsm6dsox, (uint8_t*)&emb_sh,18);
     /*and for gyro*/
     lsm6dsox_gy_flag_data_ready_get(&lsm6dsox, &drdy);
     lsm6dsox_angular_rate_raw_get(&lsm6dsox, data_raw.u8bit);
     
     

    I have a question?

    according to the datasheet:

    "When this bit is set to 0, the accelerometer/gyroscope sensor has to be active (not in Power-Down mode) and the sensor hub trigger signal is the accelerometer/gyroscope data-ready signal.

    When this bit is set to 1, at least one sensor between the accelerometer and the gyroscope has to be active and the sensor hub trigger signal is the INT2 pin."

    In lsm6dsox_reg.h file

    typedef enum {
     LSM6DSOX_EXT_ON_INT2_PIN = 0,
     LSM6DSOX_XL_GY_DRDY = 1,
    } lsm6dsox_start_config_t;

    Shouldn't it be the opposite way?

    LSM6DSOX_EXT_ON_INT2_PIN = 1

     LSM6DSOX_XL_GY_DRDY  = 0

    ST Employee
    October 2, 2020

    Hi @suads​ ,

    found the post you were referring to in this other thread.

    Thank you again for the bug reporting.

    -Eleon