2022-04-27 05:22 PM
Hi folks,
I am using the LSM6DSO sensor and trying to output data via the pin 2 interrupt. I've set up the interrupt to fire when the FIFO is full to a predetermined threshold. After the FIFO interrupt fires, the system will empty the FIFO of the data and wait for the next interrupt. I've included the following information regarding this issue: code to set up the sensor, code to empty the FIFO, and an example of the incorrect/inaccurate data.
Code to set up the sensor
XL Specific Setup:
struct lsm6dso_data *dev_data = imu->data;
lsm6dso_xl_power_mode_set(dev_data->ctx, LSM6DSO_HIGH_PERFORMANCE_MD)
lsm6dso_xl_full_scale_set(dev_data->ctx, LSM6DSO_2g)
lsm6dso_xl_data_rate_set(dev_data->ctx, LSM6DSO_XL_ODR_26Hz)
FIFO Specific Setup:
struct lsm6dso_data *dev_data = imu->data;
lsm6dso_block_data_update_set(dev_data->ctx, PROPERTY_ENABLE)
lsm6dso_fifo_watermark_set(dev_data->ctx, DATA_FIFO_2_SECOND) // watermark set to 2 seconds of data (52 samples)
lsm6dso_fifo_xl_batch_set(dev_data->ctx, LSM6DSO_XL_BATCHED_AT_26Hz)
lsm6dso_fifo_mode_set(dev_data->ctx, LSM6DSO_STREAM_MODE)
Interrupt Specific Setup:
struct lsm6dso_data *dev_data = imu->data;
lsm6dso_pin_int2_route_t int2_route;
struct sensor_trigger trig;
trig.type = SENSOR_TRIG_PRIV_START;
trig.chan = SENSOR_CHAN_ACCEL_XYZ;
lsm6dso_pin_int2_route_get(dev_data->ctx, NULL, &int2_route);
int2_route.fifo_th = PROPERTY_ENABLE;
lsm6dso_pin_int2_route_set(dev_data->ctx, NULL, int2_route);
lsm6dso_trigger_set(imu, &trig, fifo_trigger);
Code to empty the FIFO
When the interrupt fires, I utilize a semaphore to pass to a thread where I call this code:
struct lsm6dso_data *dev_data = imu->data;
union axis3bit16_t xl_fifo_raw, gy_fifo_raw;
float xl_data[3], gy_data[3];
char xl_char[25], gy_char[25];
lsm6dso_fifo_wtm_flag_get(dev_data->ctx, &fifo_wtm);
if (fifo_wtm > 0)
{
lsm6dso_fifo_data_level_get(dev_data->ctx, &fifo_num);
LOG_DBG("%i unread fifo samples", fifo_num);
while (fifo_num--)
{
lsm6dso_fifo_out_raw_get(dev_data->ctx, xl_fifo_raw.u8bit);
lsm6dso_fifo_out_raw_get(dev_data->ctx, gy_fifo_raw.u8bit);
xl_data[0] = lsm6dso_from_fs2_to_mg(xl_fifo_raw.i16bit[0]) / CONVERSION_1000;
xl_data[1] = lsm6dso_from_fs2_to_mg(xl_fifo_raw.i16bit[1]) / CONVERSION_1000;
xl_data[2] = lsm6dso_from_fs2_to_mg(xl_fifo_raw.i16bit[2]) / CONVERSION_1000;
sprintf(xl_char, "(%0.2f,%0.2f,%0.2f)[g]", xl_data[0], xl_data[1], xl_data[2]);
gy_data[0] = lsm6dso_from_fs250_to_mdps(gy_fifo_raw.i16bit[0]) / CONVERSION_1000;
gy_data[1] = lsm6dso_from_fs250_to_mdps(gy_fifo_raw.i16bit[1]) / CONVERSION_1000;
gy_data[2] = lsm6dso_from_fs250_to_mdps(gy_fifo_raw.i16bit[2]) / CONVERSION_1000;
sprintf(gy_char, "(%0.2f,%0.2f,%0.2f)[dps]", gy_data[0], gy_data[1], gy_data[2]);
LOG_INF("%i: %s, %s", fifo_num, log_strdup(xl_char), log_strdup(gy_char));
}
}
Example of the incorrect/inaccurate data
When the interrupt fires, this is the data I get. The data for (~0, ~0, ~1)[g] is correct to the orientation of the board but the data for (~0, ~0, ~0)[g] is not correct.
Does anyone know what might be causing the (~0, ~0, ~0)[g] data from the FIFO?
P.S. Please let me know if more information is required - I'm more than happy to provide what I can.