04-22-2021 04:36 PM
Using the BMA456 Sensor API and using both examples "Acceleromter.c" then "motion.c". on a Grove Step Counter that carries a BMA456 via i2C linked up to a Raspberry pi Pico.
The accelerometer example works fine, the motion example sets everythine up fine, prints out "shake the board etc " and nothing else happens.
The code is running the loop, but calling the function bma456_read_int_status always returns zero no matter how hard the board is shaken, if i put it into a loop to read the accelerometer ,and shake it, it is easily pulling 2g in one or two axis.
As this is the bosch sensor api, with me just writing the user I2C read./write and delay, i would have thought it should just work, any suggestions to make it work or further fault finding?
04-23-2021 04:00 AM
Hello pete_waddy,
In motion.c example code, it mapped BMA456_ANY_MOT_INT and to BMA456_NO_MOT_INT to INT1. INT1_IO_CTRL(0x53) default value is 0x00, you could refer the following code to it by calling set bma4_set_int_pin_config().
/* Map the interrupt 1 for any/no-motion */
rslt = bma456_map_interrupt(BMA4_INTR1_MAP, (BMA456_ANY_MOT_INT | BMA456_NO_MOT_INT), BMA4_ENABLE, &bma);
struct bma4_int_pin_config int_pin_config;
rslt = bma4_get_int_pin_config(&int_pin_config, int_line, dev);
int_pin_config.edge_ctrl |= BMA4_LEVEL_TRIGGER;
int_pin_config.lvl = BMA4_ACTIVE_HIGH;//rising edge trigger
int_pin_config.od = BMA4_PUSH_PULL;
int_pin_config.output_en = BMA4_OUTPUT_ENABLE;
rslt = bma4_set_int_pin_config(&int_pin_config, int_line, dev);
Enable_MCU_INT1_Pin();
volatile uint8_t int1_flag = 0;
for(;;)
{
if(int1_flag == 1)
{
int_status = 0;
/* Read interrupt status */
rslt = bma456_read_int_status(&int_status, dev);
/* Filtering only the tap interrupt */
if (rslt == BMA4_OK)
{
if(int_status & BMA456_ANY_MOT_INT)
{
PDEBUG("BMA456_ANY_MOT_INT interrupt occurrer\n");
}
if(int_status & BMA456_NO_MOT_INT)
{
PDEBUG("BMA456_NO_MOT_INT interrupt occurrer\n");
}
}
int1_flag = 0;
}
}
void Enable_MCU_INT1_Pin(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : INT1_Pin */
GPIO_InitStruct.Pin = INT1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(INT1_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_10)//INT1
{
PDEBUG("INT1 Triggered\r\n");
int1_flag = 1;
}
}
04-23-2021 12:52 PM
OK, thanks for the code, I am only interested in using the any motion interrupt, so i have removed the code for the no motion interrupt.
So when the device powers on, the config/acclerometer/any motion are all set up ok.
When I tap the device the INT1 line goes high as expected, but at this stage it stays high, the INT1 is not latched as register 0x55 reads 0.
The only way i can get the INT1 line to then go low is if i read the int_status register.
The wearable document has a picture that shows the interrupt only being high until it drops below the any motion threshold.
The device currently does not behave like this, currently needing a read of the int_status register in order to go low, I am attempting to match the figure on page 15 (section 1.5) of the current wearables document "Application Note - Wearables Feature set Revision 1.2 Jan 2021 Number BST-MAS-AN032-02"
The dcument shows the interupt firing as the threshold/samples have been crossed and then going low after falling below the threshold, thats what I want INT1 line to behave link
05-20-2021 08:28 AM
Hello pete_waddy,
1.You could set none latch interrupt mode;
2.Read interrupt status when host received interrupt signal, then interrupt status will be cleared.
bma4_set_interrupt_mode(BMA4_NON_LATCH_MODE, dev);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_10)//INT1
{
PDEBUG("INT1 Triggered\r\n");
int1_flag = 1;
}
else if(GPIO_Pin == GPIO_PIN_3)//INT2
{
PDEBUG("INT2 Triggered\r\n");
int2_flag = 1;
}
}
void StartBMA456InterruptTask(void const * argument)
{
int8_t rslt = BMA4_OK;
struct bma4_dev *dev;
dev = &bma456accel;
/* Variable to get wrist gesture status */
uint16_t int_status = 0;
for(;;)
{
if(int1_flag == 1)
{
int_status = 0;
/* Read interrupt status */
rslt = bma456_read_int_status(&int_status, dev);
/* Filtering only the tap interrupt */
if (rslt == BMA4_OK)
{
if(int_status & BMA456_DOUBLE_TAP_INT)
{
PDEBUG("Double Tap interrupt occurrer\n");
}
if(int_status & BMA456_ANY_MOT_INT)
{
PDEBUG("Any motion interrupt occurrer\n");
}
}
int1_flag = 0;
}
}
}
11-17-2023 05:09 PM
I have the same problem with my ESP32 kit no problem reading the accelerometer data, but cannot get an "any motion" interrupt to be registered. Were you able to get to the bottom of this issue?