cancel
Showing results for 
Search instead for 
Did you mean: 

Motionfx problems with quaternions

suads
Associate III

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.

1 ACCEPTED SOLUTION

Accepted Solutions
suads
Associate III

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

View solution in original post

3 REPLIES 3
Eleon BORLINI
ST Employee

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

suads
Associate III

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

Hi @suads​ ,

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

Thank you again for the bug reporting.

-Eleon