2021-06-25 02:30 AM
Hi,
While trying to calibrate the magnetometer, upon successive failures, I noticed that the values that were read for the Y and Z axes are successively repeated until a different value is read (as can be seen below). It appears that there's some kind of great threshold for a new value to be stored in the register.
It's hard to debug this issue, especially since the documentation on the magnetometer of the LSM9DS1 is quite scarce (namely its functionality, as opposed to the accelerometer and gyroscope on the datasheet).
The configuration is as follows:
int32_t IMU_config(IMU_FW * imu){
/* Check device ID */
lsm9ds1_id_t whoamI;
lsm9ds1_dev_id_get(&imu->dev_ctx_mag, &imu->dev_ctx_imu, &whoamI);
if (whoamI.imu != LSM9DS1_IMU_ID || whoamI.mag != LSM9DS1_MAG_ID){
while(1){
return 0;
}
}
/* Restore default configuration */
uint8_t rst;
lsm9ds1_dev_reset_set(&imu->dev_ctx_mag, &imu->dev_ctx_imu, PROPERTY_ENABLE);
do {
lsm9ds1_dev_reset_get(&imu->dev_ctx_mag, &imu->dev_ctx_imu, &rst);
} while (rst);
/* Little-Endian Format Selection */
lsm9ds1_dev_data_format_set(&imu->dev_ctx_mag, &imu->dev_ctx_imu, LSM9DS1_LSB_LOW_ADDRESS);
/* Enable Block Data Update */
lsm9ds1_block_data_update_set(&imu->dev_ctx_mag, &imu->dev_ctx_imu, PROPERTY_DISABLE);
/* Set INT1 as Gyroscope Data Ready */
lsm9ds1_pin_int1_route_t val;
val.int1_drdy_xl = 0;
val.int1_drdy_g = 1;
val.int1_boot = 0;
val.int1_fth = 0;
val.int1_ovr = 0;
val.int1_fss5 = 0;
val.int1_ig_xl = 0;
val.int1_ig_g = 0;
lsm9ds1_pin_int1_route_set(&imu->dev_ctx_imu, val);
/* Set full scale */
lsm9ds1_xl_full_scale_set(&imu->dev_ctx_imu, LSM9DS1_4g);
lsm9ds1_gy_full_scale_set(&imu->dev_ctx_imu, LSM9DS1_2000dps);
lsm9ds1_mag_full_scale_set(&imu->dev_ctx_mag, LSM9DS1_16Ga);
/* Configure filtering chain - See datasheet for filtering chain details */
/* Accelerometer filtering chain */
lsm9ds1_xl_filter_aalias_bandwidth_set(&imu->dev_ctx_imu, LSM9DS1_AUTO);
lsm9ds1_xl_filter_lp_bandwidth_set(&imu->dev_ctx_imu, LSM9DS1_LP_ODR_DIV_50);
lsm9ds1_xl_filter_out_path_set(&imu->dev_ctx_imu, LSM9DS1_LP_OUT);
/* Gyroscope filtering chain */
lsm9ds1_gy_filter_lp_bandwidth_set(&imu->dev_ctx_imu, LSM9DS1_LP_STRONG);
lsm9ds1_gy_filter_hp_bandwidth_set(&imu->dev_ctx_imu, LSM9DS1_HP_MEDIUM);
lsm9ds1_gy_filter_out_path_set(&imu->dev_ctx_imu, LSM9DS1_LPF1_HPF_LPF2_OUT);
/* Set Output Data Rate / Power mode */
lsm9ds1_imu_data_rate_set(&imu->dev_ctx_imu, 0xA2);
lsm9ds1_mag_data_rate_set(&imu->dev_ctx_mag, 0x27);
//IMU_setInertialRate(imu, IMU_59Hz5);
//IMU_setMagnetometerRate(imu, MAG_80Hz);
/* Set SPI as communication interface */
lsm9ds1_sim_t random;
uint32_t ret = lsm9ds1_spi_mode_set(&imu->dev_ctx_mag, &imu->dev_ctx_imu,LSM9DS1_SPI_4_WIRE);
lsm9ds1_spi_mode_get(&imu->dev_ctx_mag, &imu->dev_ctx_imu,&random);
lsm9ds1_i2c_dis_t rand;
ret = lsm9ds1_i2c_interface_set(&imu->dev_ctx_mag,&imu->dev_ctx_imu,LSM9DS1_I2C_DISABLE);
ret = lsm9ds1_i2c_interface_get(&imu->dev_ctx_mag,&imu->dev_ctx_imu,&rand);
return 1;
}
I have attached a .csv file that serves as a datalog of the several readings while rotating the LSM9DS1 with the motion described in section 2.2.5 of the UM2192.
Any idea on what might be causing this issue?
Thanks in advance.
2021-06-29 03:10 AM
Hi @Community member ,
From your acquisition data, it looks as the Y and Z axis were blocked, or at least not refreshed.
Are you implementing the SPI multiple reading (datasheet p.36), or are you looping the single register reading?
If you otherwise suspect a damage in the magnetic sensor, you could try to run the self test procedure, as coded in lsm9ds1_self_test.c: this will allow you to check whether there are issues on some axis.
-Eleon
2021-06-30 06:51 AM
Hi, Eleon,
Thanks for your answer.
The SPI is reading multiple registers with the following function:
int32_t read_reg_M(void * handle, uint8_t reg, uint8_t * data, uint16_t len){
HAL_GPIO_WritePin(IMU_CS_M_GPIO_Port, IMU_CS_M_Pin, RESET);
uint8_t val = 0xC0 | reg; //Read bit = 1
HAL_SPI_Transmit(&hspi1, &val, 1, SPI_TIMEOUT_IMU);
HAL_SPI_Receive(&hspi1, data, len, SPI_TIMEOUT_IMU);
HAL_GPIO_WritePin(IMU_CS_M_GPIO_Port, IMU_CS_M_Pin, SET);
return 0;
}
When called, reg=0x28U (LSM9DS1_OUT_X_L_M) and len=6.
I can run a self-test, but I highly doubt it is a matter of damage to the sensor since I've tried the same software for several different boards with the same MEMS and the verified behaviour is always the same.
2021-07-29 01:21 AM
Any idea?
2021-07-30 07:21 AM
Hi @Community member ,
not many ideas indeed. Did you try to acquire for example only the Y axis?
And are all the sensors you have tested coming from the same lot? If so, could you share the reference?
-Eleon
2021-08-31 09:08 AM
Hi, Eleon,
Sorry for the late response.
I have tried to acquire only the Y or the Z axis, with the same behavior.
Regarding the lot, I'm not sure where to find its reference, so I'll share what's written on top of the package: 2911-9S1-X1KB. Is that it? If so then, yes, all the sensors are from the same lot.
2021-09-02 07:17 AM
Hi @Community member ,
if you see the issue on all the sensors, I believe it is an issue related to the acquisition procedure.
Try for example a lower ODR for the magnetometer (less than 80Hz).
Are the Y and Z axis of the accelerometer and gyroscope working well?
-Eleon