10-08-2019 09:28 PM
Hi
I was trying to setup the TAP sensing on a BMX160 sensor, using the API from GitHub.
I had trouble setting the sensitivity of the TAP sensing and getting a TAP interrupt triggering on INT2. The only real difference in tap force to detect a tap, was by changing the Acc range. I'll create an issue on this if I have further issues with it.
When I printed out the registers to ensure they are being set correctly, I saw that the TAP_INT[0] and TAP_INT[1] registers were not being updated according to my settings.
Also the tap INT was being set on INT1 instead of INT2
Here is my init code (without my fix):
// --------------- Init BMX160 ---------------------
bmi.id = BMI160_I2C_ADDR;
bmi.interface = BMI160_I2C_INTF;
bmi.read = I2C_0_readDataBlock;
bmi.write = performDimWrite;
bmi.delay_ms = delay_miliSec;
bmm.dev_id = BMM150_DEFAULT_I2C_ADDRESS;
bmm.intf = BMM150_I2C_INTF;
bmm.read = bmm150_aux_read;
bmm.write = bmm150_aux_write;
bmm.delay_ms = delay_miliSec;
rslt_ = bmi160_init(&bmi);
printf("bmi160_init:%i\r\n", rslt_);
bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE;
bmi.aux_cfg.aux_i2c_addr = bmm.dev_id;
bmi.aux_cfg.manual_enable = BMI160_ENABLE;
bmi.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3;
rslt_ = bmi160_aux_init(&bmi);
printf("bmi160_aux_init:%i\r\n", rslt_);
rslt_ = bmm150_init(&bmm);
printf("bmm150_init:%i\r\n", rslt_);
//// --------------- Acc & Gryo ---------------------
////printf("Init:AccGyro\r\n");
//// Configure accel and gyro sensors in normal mode
bmi.accel_cfg.odr = BMI160_ACCEL_ODR_50HZ;
bmi.accel_cfg.range = BMI160_ACCEL_RANGE_4G;
bmi.accel_cfg.bw = BMI160_ACCEL_BW_OSR4_AVG1;
bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
bmi.gyro_cfg.odr = BMI160_GYRO_ODR_50HZ;
bmi.gyro_cfg.range = BMI160_GYRO_RANGE_125_DPS;
bmi.gyro_cfg.bw = BMI160_GYRO_BW_OSR4_MODE;
bmi.gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE;
rslt_ = bmi160_set_sens_conf(&bmi);
printf("bmi160_set_sens_conf:%i\r\n", rslt_);
// Configure sensor interrupt (Data Ready)
//printf("Init:DataReady\r\n");
/* Select the Interrupt channel/pin */
bmi_int_config.int_channel = BMI160_INT_CHANNEL_1;// Interrupt channel/pin 1
/* Select the Interrupt type */
bmi_int_config.int_type = BMI160_ACC_GYRO_DATA_RDY_INT;// Choosing Data Readay interrupt
/* Select the interrupt channel/pin settings */
bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
bmi_int_config.int_pin_settg.latch_dur =BMI160_LATCH_DUR_NONE;// non-latched output
/* Set the Data Ready interrupt */
rslt_ = bmi160_set_int_config(&bmi_int_config, &bmi); /* sensor is an instance of the structure bmi160_dev */
printf("bmi160_set_int_config:%i\r\n", rslt_);
// Configure sensor interrupt (Tap)
//printf("Init:Tap\r\n");
/* Select the Interrupt channel/pin */
bmi_int_config.int_channel = BMI160_INT_CHANNEL_2;// Interrupt channel/pin 2
/* Select the Interrupt type: Tap */
bmi_int_config.int_type = BMI160_ACC_SINGLE_TAP_INT;// Choosing Step Detector interrupt
/* Select the interrupt channel/pin settings */
bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
bmi_int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE;// non-latched output
/* Select the Step Detector interrupt parameters, Kindly use the recommended settings for step detector */
bmi_int_config.int_type_cfg.acc_tap_int.tap_en = BMI160_ENABLE;// 1-enable, 0-disable the detector
bmi_int_config.int_type_cfg.acc_tap_int.tap_data_src=BMI160_ENABLE; // use pre-filter
bmi_int_config.int_type_cfg.acc_tap_int.tap_dur = 0b001;
bmi_int_config.int_type_cfg.acc_tap_int.tap_quiet = BMI160_DISABLE; // 30/20ms
bmi_int_config.int_type_cfg.acc_tap_int.tap_shock = BMI160_DISABLE; // 50/75ms
bmi_int_config.int_type_cfg.acc_tap_int.tap_thr = 0b11111; // 125mg/2 = 62.5mg per bit (4g range)
Here is the code that I ran directly after this init procedure to print out the registers:
// check if Tap INT1 is enabled
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_2_ADDR , &rslt_, 1);
printf("IntMap2=%x\r\n", rslt_ );
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_1_ADDR , &rslt_, 1);
printf("IntMap1=%x\r\n", rslt_ );
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_0_ADDR , &rslt_, 1);
printf("IntMap0=%x\r\n", rslt_ );
// check if Tap detection is enabled
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_ENABLE_2_ADDR , &rslt_, 1);
printf("IntEn2=%x\r\n", rslt_ );
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_ENABLE_1_ADDR , &rslt_, 1);
printf("IntEn1=%x\r\n", rslt_ );
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_ENABLE_0_ADDR , &rslt_, 1);
printf("IntEn0=%x\r\n", rslt_ );
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_TAP_0_ADDR , &rslt_, 1);
printf("INT_TAP[0]=%x\r\n", rslt_ );
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_TAP_1_ADDR , &rslt_, 1);
printf("INT_TAP[1]=%x\r\n", rslt_ );
Here is the output of the printout:
IntMap2=0
IntMap1=80
IntMap0=20
IntEn2=0
IntEn1=10
IntEn0=20
INT_TAP[0]=7
INT_TAP[1]=a
Then I had-coded the TAP registers, by changing the TAP init sequence to the following (before the printf sequence):
// Configure sensor interrupt (Tap)
//printf("Init:Tap\r\n");
/* Select the Interrupt channel/pin */
bmi_int_config.int_channel = BMI160_INT_CHANNEL_2;// Interrupt channel/pin 2
/* Select the Interrupt type: Tap */
bmi_int_config.int_type = BMI160_ACC_SINGLE_TAP_INT;// Choosing Step Detector interrupt
/* Select the interrupt channel/pin settings */
bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
bmi_int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE;// non-latched output
/* Select the Step Detector interrupt parameters, Kindly use the recommended settings for step detector */
bmi_int_config.int_type_cfg.acc_tap_int.tap_en = BMI160_ENABLE;// 1-enable, 0-disable the detector
bmi_int_config.int_type_cfg.acc_tap_int.tap_data_src=BMI160_ENABLE; // use pre-filter
bmi_int_config.int_type_cfg.acc_tap_int.tap_dur = 0b001;
bmi_int_config.int_type_cfg.acc_tap_int.tap_quiet = BMI160_DISABLE; // 30/20ms
bmi_int_config.int_type_cfg.acc_tap_int.tap_shock = BMI160_DISABLE; // 50/75ms
bmi_int_config.int_type_cfg.acc_tap_int.tap_thr = 0b11111; // 125mg/2 = 62.5mg per bit (4g range)
// Setup INT_TAP[0] correctly
rslt_ = 0b00000111;
performDimWrite(BMI160_I2C_ADDR, BMI160_INT_TAP_0_ADDR, &rslt_, 1 );
// Setup INT_TAP[1] correctly
rslt_ = 0b00001111;
performDimWrite(BMI160_I2C_ADDR, BMI160_INT_TAP_1_ADDR, &rslt_, 1 );
/* Set the Tap Detector interrupt */
rslt_ = bmi160_set_int_config(&bmi_int_config, &bmi); /* sensor is an instance of the structure bmi160_dev */
printf("bmi160_set_int_config:%i\r\n", rslt_);
// correct INT channel for Tap. Bug in library
// disable int1_s_tap
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_0_ADDR , &rslt_, 1);
rslt_ = rslt_ & 0b11011111;
performDimWrite(BMI160_I2C_ADDR, BMI160_INT_MAP_0_ADDR, &rslt_, 1 );
// enable int2_s_tap
I2C_0_readDataBlock(BMI160_I2C_ADDR, BMI160_INT_MAP_2_ADDR , &rslt_, 1);
rslt_ = rslt_ | 0b00100000;
performDimWrite(BMI160_I2C_ADDR, BMI160_INT_MAP_2_ADDR, &rslt_, 1 );
which gave the following output:
IntMap2=20
IntMap1=80
IntMap0=0
IntEn2=0
IntEn1=10
IntEn0=20
INT_TAP[0]=7
INT_TAP[1]=f
After hard-coding the registers, TAP sensing was generating an interrupt on INT2.
Is there a bug in the API?
Solved! Go to Solution.
10-10-2019 03:52 PM
10-12-2019 06:39 PM
Hi o_o
I added a function to print out the BMX160's registers, 1sec after init completed. This helped me to debug.
I added bmi160_set_int_config just after the TAP config. This did help, but on its own did not solve my problem.
What I found to be the final crucial step is the order of bmi160_set_int_config,bmi160_set_sens_conf and bmi160_set_power_mode. (I couldn't find where the GitHub README is clear on this).
I originally had the order as follows (without bmi160_set_power_mode) - NOT WORKING:
The registers were set correctly when I added (bmi160_set_power_mode) and set the order as follows - WORKING:
For those who need a guide, here is what my init code looks like:
struct bmi160_dev bmi;
// --------------- Init BMX160 ---------------------
bmi.id = BMI160_I2C_ADDR;
bmi.interface = BMI160_I2C_INTF;
bmi.read = I2C_0_readDataBlock;
bmi.write = performDimWrite;
bmi.delay_ms = delay_miliSec;
bmm.dev_id = BMM150_DEFAULT_I2C_ADDRESS;
bmm.intf = BMM150_I2C_INTF;
bmm.read = bmm150_aux_read;
bmm.write = bmm150_aux_write;
bmm.delay_ms = delay_miliSec;
rslt_ = bmi160_init(&bmi);
printf("bmi160_init:%i\r\n", rslt_);
// --------------- Acc & Gryo ---------------------
// Configure accel and gyro sensors in normal mode
bmi.accel_cfg.odr = BMI160_ACCEL_ODR_50HZ;
bmi.accel_cfg.range = BMI160_ACCEL_RANGE_4G;
bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
bmi.gyro_cfg.odr = BMI160_GYRO_ODR_50HZ;
bmi.gyro_cfg.range = BMI160_GYRO_RANGE_125_DPS;
bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
bmi.gyro_cfg.power = BMI160_GYRO_SUSPEND_MODE;
struct bmi160_int_settg bmi_int_config;
// Configure sensor interrupt (Data Ready)
printf("Init:DataReady\r\n");
/* Select the Interrupt channel/pin */
bmi_int_config.int_channel = BMI160_INT_CHANNEL_1;// Interrupt channel/pin 1
/* Select the interrupt channel/pin settings */
bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
bmi_int_config.int_pin_settg.latch_dur =BMI160_LATCH_DUR_NONE;// non-latched output
/* Select the Interrupt type */
bmi_int_config.int_type = BMI160_ACC_GYRO_DATA_RDY_INT;// Choosing Data Ready interrupt
/* Set the Data Ready interrupt */
rslt_ = bmi160_set_int_config(&bmi_int_config, &bmi); /* sensor is an instance of the structure bmi160_dev */
printf("bmi160_set_int_config:%i\r\n", rslt_);
// Configure sensor interrupt (Tap)
printf("Init:Tap\r\n");
/* Select the Interrupt channel/pin */
bmi_int_config.int_channel = BMI160_INT_CHANNEL_2;// Interrupt channel/pin 2
/* Select the interrupt channel/pin settings */
bmi_int_config.int_pin_settg.output_en = BMI160_ENABLE;// Enabling interrupt pins to act as output pin
bmi_int_config.int_pin_settg.output_mode = BMI160_DISABLE;// Choosing push-pull mode for interrupt pin
bmi_int_config.int_pin_settg.output_type = BMI160_ENABLE;// Choosing active High output
bmi_int_config.int_pin_settg.edge_ctrl = BMI160_ENABLE;// Choosing level triggered output
bmi_int_config.int_pin_settg.input_en = BMI160_DISABLE;// Disabling interrupt pin to act as input
bmi_int_config.int_pin_settg.latch_dur = BMI160_LATCH_DUR_NONE;// non-latched output
/* Select the Interrupt type: Tap */
bmi_int_config.int_type = BMI160_ACC_SINGLE_TAP_INT;// Choosing Step Detector interrupt
/* Select the Step Detector interrupt parameters, Kindly use the recommended settings for step detector */
bmi_int_config.int_type_cfg.acc_tap_int.tap_en = BMI160_ENABLE;// 1-enable, 0-disable the detector
bmi_int_config.int_type_cfg.acc_tap_int.tap_data_src=BMI160_ENABLE; // use pre-filter
// bmi_int_config.int_type_cfg.acc_tap_int.tap_dur = 1; // not applicable to single tap
bmi_int_config.int_type_cfg.acc_tap_int.tap_quiet = BMI160_DISABLE; // 30/20ms
bmi_int_config.int_type_cfg.acc_tap_int.tap_shock = BMI160_DISABLE; // 50/75ms
bmi_int_config.int_type_cfg.acc_tap_int.tap_thr = 0b00001; // 125mg/2 = 62.5mg per bit (4g range)
/* Set the Tap Detector interrupt */
rslt_ = bmi160_set_int_config(&bmi_int_config, &bmi); /* sensor is an instance of the structure bmi160_dev */
printf("bmi160_set_int_config:%i\r\n", rslt_);
/* Set the sensor configuration */
rslt_ = bmi160_set_sens_conf(&bmi);
printf("bmi160_set_sens_conf:%i\r\n", rslt_);
/* Set the Power mode */
rslt_ = bmi160_set_power_mode(&bmi);
printf("bmi160_set_power_mode:%i\r\n", rslt_);
Thanks for the help o_o