09-06-2022 08:56 AM
I'm using BMI160 IMU with STM32 microcontroller. I have wrote everything, from wrappers for implementing API to sensor fusion algorithms to process raw IMU data.
But for precise operation, I need to get new sensor data at a constant rate. Since I shouldn't skip any new sensor readings, my read will be equal to sensors ODR rate. Which is 1600 Hz.
My current Accel and Gyro settings are below:
sensor.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ; sensor.accel_cfg.range = BMI160_ACCEL_RANGE_4G; /* Select the power mode of accelerometer sensor */ sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE; sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4; /* Select the Output data rate, range of Gyroscope sensor */ sensor.gyro_cfg.odr = BMI160_GYRO_ODR_1600HZ; sensor.gyro_cfg.range = BMI160_GYRO_RANGE_500_DPS; /* Select the power mode of Gyroscope sensor */ sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE; sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
And my current interrupt settings are:
/* Select the Interrupt channel/pin */ int_config.int_channel = BMI160_INT_CHANNEL_1;// Interrupt channel/pin 1 /* Select the Interrupt type */ int_config.int_type = BMI160_ACC_GYRO_DATA_RDY_INT;// Choosing Any motion interrupt /* Select the interrupt channel/pin settings */ int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin int_config.int_pin_settg.output_type = BMI160_DISABLE;// Choosing active low output int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing edge triggered output int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE;// non-latched output /* Set the Any-motion interrupt */ rslt = bmi160_set_int_config(&int_config, &sensor); /* sensor is an instance of the structure bmi160_dev */
So, what type of interrupt routine should I implement?
Thank you for your answers.
09-06-2022 10:03 AM
You could implement interrupt routine like this:
struct bmi160_dev bmi160dev;
struct bmi160_sensor_data accel;
struct bmi160_sensor_data gyro;
int8_t rslt = BMI160_OK;
struct bmi160_dev *dev;
volatile union bmi160_int_status int_status;
dev = &bmi160dev;
memset(int_status.data, 0x00, sizeof(int_status.data));
bmi160_get_int_status(BMI160_INT_STATUS_ALL, &int_status, dev);
PDEBUG("data: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n", int_status.data, int_status.data, int_status.data, int_status.data);
/* To read both Accel and Gyro data */
bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel, &gyro, dev);
09-06-2022 01:38 PM
@BSTRobin thank you for your answer. I have one more question.
My interrupt settings of BMI160 were set as I shared in the initial post. With these settings, I turned on the sensor and looked at the physical interrupt pin with an oscilloscope, and I saw a square wave whose frequency was close to 1600 Hz, which is the ODR value I chose.
My question is when new data arrives, does the square wave go high or low?
09-07-2022 05:07 AM
According to your interrupt setting code, the interrupt is triggered by the falling edge.