We are looking for the best way to use the lsm6dsl for a crash detection. Example: Device is belted to the human body. Body crashes while mountainbiking. device should report a crash and the force on the 3 axis.
We have used the TAP detection so far and used the fifo_in_continous_to_fifo mode for the acceleration data that lead to the tap detection, as here we can set the threshold individually from 0.5g up to 16g.
However even with slight taps or putting the device on the table, we get values of up to 10g which is way too much.
These are our settings and code. Please kindly help. Thanks a lot!
Settings:
{
uint8_t value;
// No duration
// 0x00 single-tap | 0x00 wake-up
lsm6dsl_write(accel, LSM6DSL_WAKE_UP_DUR, 0x00);
// Configure Activity/Inactivity threshold
// 0x02 single-tap | 0x00 wake-up
// 2g
#ifdef LSM_16G
lsm6dsl_write(accel, LSM6DSL_WAKE_UP_THS, 0x01);
#else
lsm6dsl_write(accel, LSM6DSL_WAKE_UP_THS, 0x08);
#endif
// Enable interrupts(TAP & WU), tap detection on X, Y, Z axis (TAP), apply slope filter (WU)
// 0x8E single-tap | 0x90 wake-up
lsm6dsl_write(accel, LSM6DSL_TAP_CFG, 0x9E);
// Set tap threshold
// 0x89 single-tap | 0x00 wake-up
// X * 0.0625 = threshold_in_g
// e.g 0x10 * 0.0625 = 1g
// so TAP_THS field of TAP_THS_6D register is 0b10000
#ifdef LSM_16G
lsm6dsl_write(accel, LSM6DSL_TAP_THS_6D, 0x84);
#else
lsm6dsl_write(accel, LSM6DSL_TAP_THS_6D, 0x90);
#endif
#ifdef LSM_16G
//BUG_CHECK (-> test avec 0x64 et 0x60 pour 416Hz)
lsm6dsl_write(accel, LSM6DSL_CTRL1_XL, 0x74);
//lsm6dsl_write(accel, LSM6DSL_CTRL1_XL, 0x64);
#else
lsm6dsl_write(accel, LSM6DSL_CTRL1_XL, 0x70);
//lsm6dsl_write(accel, LSM6DSL_CTRL1_XL, 0x60);
#endif
DELAY_MS(10);
lsm6dsl_read(accel, LSM6DSL_CTRL1_XL, &value, 1);
////lsm6dsl_write(accel, LSM6DSL_CTRL1_XL, 0x60);
lsm6dsl_write(accel, LSM6DSL_INT_DUR2, 0x06);
lsm6dsl_write(accel, LSM6DSL_MD1_CFG, 0x20) ;
//! NEW FIFO IMU
// Single tap on INT2
lsm6dsl_write(accel, LSM6DSL_MD2_CFG, 0x40);
return 0;
}
I'm not sure this is an issue related to the code itself, but maybe to a limitation in the detection range of the LSM6DSL (max FS = 16g). Do you have a target acceleration value to be detected? I mean do you know how many "g" you would expect b y the shock you would detect?
It's not so difficult to reach up to 10g, if the shock pulse is short enough. You might set some filters (low pass and high pass) on the LSM6DSL, so that you can concentrate the shock you want to detect and reduce the spurious acceleration peaks.
To do this, you can use the Composite filter described in the datasheet, p.67:
If you are using the TAP interrupt, you might try to increase the Interrupt duration, so that the shock must be over threshold for a minimum time (to be fine-tuned with the specific application).
Otherwise, you might try changing device using an high-g accelerometer (up to 200g) such as the H3LIS331DL, which is more suitable for the shock detections.
Not sure it is possible to apply both Low pass and High pass filter, since from the block diagram of the composite filter they are not on in cascade.
You should choose only one of them, maybe only the high pass path, that cuts all the low pass frequency. You will be able to see only shocks faster than ODR/x.
We have now set only the HighPass filters. It seems to work, BUT after a random number of detections and interrupts (approx 5-10), the device seems to stall and not send any more informations.
is there a hint if we should soft.reset the IMU after each detection or do anything else to avoid these issues?
Any advise on delays between setting the registers or having to read out EACH of the needed registers before writing into them?
maybe a 100ms delay would be a safe delay before and after reading the registers, but if you run the multiple registers SPI/I2C you don't have delays between reg_t and reg_t+1, and this should be a safe condition by design.
Not sure why the device seems to stall at a certain point... but yes, you can try enabling the SW_RESET bit of the CTRL3_C (12h), that performs the software reset. Did you already have the possibility to check this?