2023-05-20 03:17 AM
Hello,
I have an issue with my STM32G431 MCU communicating with an LSM6DSV16BX sensor via 4-wire SPI. The problem occurs randomly when the device is stationary and mounted securely. The gyroscope provides incorrect measurements consistently, with gy_raw_data[axis_0] always being 8192, gy_raw_data[axis_1] being something normal, and gy_raw_data[axis_3] equal to 704. Similarly, the accelerometer occasionally gives a 1g acceleration in the Y axis instead of the expected Z axis.
I have ruled out communication errors through various tests, including the use of a high-end logic analyzer. The inconsistent data from the LSM6DSV16BX sensor occurs randomly.
My question is: How can I determine if the sensor is malfunctioning? Can a self-test sequence be used to identify any errors?
2023-05-22 04:44 AM
Hi @stefsach,
Welcome to St Community :)
You can follow the reference code here to perform a self test procedure.
If this helps you, please mark my answer as "Best Answer" by clicking on the "Select as Best" button, this can be helpful for Community users to find this solution faster.
2023-05-22 05:13 AM
Hi @Federica Bossi ,
Thank you for the welcome.
I implemented a self test procedure, but the sensor passed the test for both the XL and GY.
I will try and swap the IC in case there is an error with the sensor
2023-05-22 05:16 AM
Hi @stefsach ,
If the self test procedure succeeded, this is not a problem related to the sensor.
You could try to follow our PID example and let me know if the issue is still present.
2023-05-28 03:41 AM
Hi @Federica Bossi,
So I have been using the PID drivers from the official github repository and its seems that I have identified the issue.
Whenever the SFLP algorithm is enabled, the sensor will output erroneous data. I have yet to confirm whether this is a hardware issue relating to the sensor or a driver issue, but once I have an answer I will come back to you.
I would appreciate your input in this matter.
This is the function I use to initialize the sensor:
static void lsm6dsvbx_init(){
/* Set device platform */
dev_ctx_lsm.write_reg = platform_write_lsm;
dev_ctx_lsm.read_reg = platform_read_lsm;
dev_ctx_lsm.handle = &LSM_BUS;
dev_ctx_lsm.mdelay = platform_delay;
platform_delay(BOOT_TIME);
/* Get device ID */
lsm6dsv16bx_device_id_get(&dev_ctx_lsm, &lsm.whoamI_lsm);
if (lsm.whoamI_lsm != LSM6DSV16BX_ID)
while (1);
/* Restore default configuration */
lsm6dsv16bx_reset_set(&dev_ctx_lsm, LSM6DSV16BX_RESTORE_CTRL_REGS);
do {
lsm6dsv16bx_reset_get(&dev_ctx_lsm, &lsm.rst_lsm);
} while (lsm.rst_lsm != LSM6DSV16BX_READY);
// lsm6dsv16bx_sflp_configure(&dev_ctx_lsm);
/* Enable Block Data Update */
lsm6dsv16bx_block_data_update_set(&dev_ctx_lsm, PROPERTY_ENABLE);
/* Set full scale */
lsm6dsv16bx_xl_full_scale_set(&dev_ctx_lsm, LSM6DSV16BX_4g);
lsm6dsv16bx_gy_full_scale_set(&dev_ctx_lsm, LSM6DSV16BX_500dps);
/* Configure filtering chain */
lsm.filt_settling_mask.drdy = PROPERTY_ENABLE;
lsm.filt_settling_mask.irq_xl = PROPERTY_ENABLE;
lsm.filt_settling_mask.irq_g = PROPERTY_ENABLE;
lsm6dsv16bx_filt_settling_mask_set(&dev_ctx_lsm, lsm.filt_settling_mask);
lsm6dsv16bx_filt_gy_lp1_set(&dev_ctx_lsm, PROPERTY_ENABLE);
lsm6dsv16bx_filt_gy_lp1_bandwidth_set(&dev_ctx_lsm, LSM6DSV16BX_GY_LIGHT);
lsm6dsv16bx_filt_xl_lp2_set(&dev_ctx_lsm, PROPERTY_ENABLE);
lsm6dsv16bx_filt_xl_lp2_bandwidth_set(&dev_ctx_lsm, LSM6DSV16BX_XL_STRONG);
/*
* Set FIFO watermark (number of unread sensor data TAG + 6 bytes
* stored in FIFO) to FIFO_WATERMARK samples
*/
lsm6dsv16bx_fifo_watermark_set(&dev_ctx_lsm, FIFO_WATERMARK);
/* Set FIFO batch of sflp data */
lsm.fifo_sflp.game_rotation = 0;
lsm.fifo_sflp.gravity = 1;
lsm.fifo_sflp.gbias = 1;
lsm6dsv16bx_fifo_sflp_batch_set(&dev_ctx_lsm, lsm.fifo_sflp);
/* Set FIFO mode to Stream mode (aka Continuous Mode) */
lsm6dsv16bx_fifo_mode_set(&dev_ctx_lsm, LSM6DSV16BX_STREAM_MODE);
/* Set operating mode */
lsm6dsv16bx_xl_mode_set(&dev_ctx_lsm, LSM6DSV16BX_XL_HIGH_PERFORMANCE_MD);
lsm6dsv16bx_gy_mode_set(&dev_ctx_lsm, LSM6DSV16BX_GY_HIGH_PERFORMANCE_MD);
/* Set Output Data Rate */
lsm6dsv16bx_xl_data_rate_set(&dev_ctx_lsm, LSM6DSV16BX_XL_ODR_AT_1920Hz);
lsm6dsv16bx_gy_data_rate_set(&dev_ctx_lsm, LSM6DSV16BX_GY_ODR_AT_1920Hz);
lsm6dsv16bx_sflp_data_rate_set(&dev_ctx_lsm, LSM6DSV16BX_SFLP_480Hz);
/* Enable game rotation */
// lsm6dsv16bx_sflp_game_rotation_set(&dev_ctx_lsm, PROPERTY_ENABLE);
/*
* here application may initialize offset with latest values
* calculated from previous run and saved to non volatile memory.
*/
lsm.gbias.gbias_x = 0.0f;
lsm.gbias.gbias_y = 0.0f;
lsm.gbias.gbias_z = 0.0f;
// lsm6dsv16bx_sflp_game_gbias_set(&dev_ctx_lsm, &gbias);
/* Set Interrupt route and mode */
/* Set Interrupt route and mode */
lsm.int1_route.drdy_xl = PROPERTY_ENABLE;
lsm.int2_route.drdy_gy = PROPERTY_ENABLE;
lsm6dsv16bx_pin_int1_route_set(&dev_ctx_lsm, lsm.int1_route);
lsm6dsv16bx_pin_int2_route_set(&dev_ctx_lsm, lsm.int2_route);
lsm6dsv16bx_data_ready_mode_set(&dev_ctx_lsm, LSM6DSV16BX_DRDY_PULSED );
lsm6dsv16bx_pin_polarity_set(&dev_ctx_lsm, LSM6DSV16BX_ACTIVE_HIGH);
lsm6dsv16bx_int_pin_mode_set(&dev_ctx_lsm, LSM6DSV16BX_PUSH_PULL);
}
Afterwards, I use an RTOS Task to read the data sensor whenever an interrupt occurs, in a similar manner to the exmaple you sent me.