04-22-2021 09:03 AM
Hello there,
i connected the BHI160b with my STM32F411RE Mikrocontroller. I implemented the HAL I2C library with the BHI160b library to read out Gyro data continuously. I used the rotation_vector_example on Github and installed the Game_rotation_vector to get quaternions. When the interrupt of the BHI160b fires, i am reading out the data! This works very good! But now i implemented a start Trigger which is between 1-15 hz. So im not reading every data from the fifo, when there is new data available. The problem i face now is that the quaternions are kind of delayed, when i start to move the sensor. How can i configure the BHI160b or change my programm to get the actuall Rotation data wich a frequency of 1-15hz ? The following shows my main loop code!
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* BHY Variable*/
uint8_t *fifoptr = NULL;
uint8_t bytes_left_in_fifo = 0;
uint16_t bytes_remaining = 0;
uint16_t bytes_read = 0;
bhy_data_generic_t fifo_packet;
bhy_data_type_t packet_type;
BHY_RETURN_FUNCTION_TYPE result;
/* the remapping matrix for BHA or BHI here should be configured according to its placement on customer's PCB. */
/* for details, please check 'Application Notes Axes remapping of BHA250(B)/BHI160(B)' document. */
int8_t bhy_mapping_matrix_config[3*3] = {0,1,0,-1,0,0,0,0,1};
/* the remapping matrix for Magnetometer should be configured according to its placement on customer's PCB. */
/* for details, please check 'Application Notes Axes remapping of BHA250(B)/BHI160(B)' document. */
int8_t mag_mapping_matrix_config[3*3] = {0,1,0,1,0,0,0,0,-1};
/* the sic matrix should be calculated for customer platform by logging uncalibrated magnetometer data. */
/* the sic matrix here is only an example array (identity matrix). Customer should generate their own matrix. */
/* This affects magnetometer fusion performance. */
float sic_array[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
/* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
/* to get this information. This feature is only supported for customized firmware. To get this customized */
/* firmware, you need to contact your local FAE of Bosch Sensortec. */
//struct cus_version_t bhy_cus_version;
while (HAL_GPIO_ReadPin(BHI160b_INT_GPIO_Port, BHI160b_INT_Pin) == GPIO_PIN_RESET);
/* init the bhy chip */
if(bhy_driver_init(&bhy1_fw))
{
//DEBUG("Fail to init bhy\n");
}
/* wait for the bhy trigger the interrupt pin go down and up again */
//while (HAL_GPIO_ReadPin(BHI160_INT_GPIO_Port, BHI160_INT_Pin) == GPIO_PIN_SET);
HAL_Delay(100);
while (HAL_GPIO_ReadPin(BHI160b_INT_GPIO_Port, BHI160b_INT_Pin) == GPIO_PIN_RESET);
/* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
/* to get this information. This feature is only supported for customized firmware. To get this customized */
/* firmware, you need to contact your local FAE of Bosch Sensortec. */
//bhy_read_parameter_page(BHY_PAGE_2, PAGE2_CUS_FIRMWARE_VERSION, (uint8_t*)&bhy_cus_version, sizeof(struct cus_version_t));
//DEBUG("cus version base:%d major:%d minor:%d\n", bhy_cus_version.base, bhy_cus_version.major, bhy_cus_version.minor);
/* the remapping matrix for BHI and Magmetometer should be configured here to make sure rotation vector is */
/* calculated in a correct coordinates system. */
//bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_ACC, bhy_mapping_matrix_config);
//bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_MAG, mag_mapping_matrix_config);
bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_GYRO, bhy_mapping_matrix_config);
/* This sic matrix setting affects magnetometer fusion performance. */
bhy_set_sic_matrix(sic_array);
/* install the callback function for parse fifo data */
if(bhy_install_sensor_callback(VS_TYPE_GAME_ROTATION_VECTOR, VS_WAKEUP, sensors_callback_rotation_vector))
{
//DEBUG("Fail to install sensor callback\n");
}
/* enables the virtual sensor */
if(bhy_enable_virtual_sensor(VS_TYPE_GAME_ROTATION_VECTOR, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
{
//DEBUG("Fail to enable sensor id=%d\n", VS_TYPE_ROTATION_VECTOR);
}
/* continuously read and parse the fifo */
while (1)
{
if(HAL_GPIO_ReadPin(IR_Trigger_GPIO_Port, IR_Trigger_Pin)== GPIO_PIN_SET)
{
SPI_send();
/* wait until the interrupt fires */
/* unless we already know there are bytes remaining in the fifo */
while (!HAL_GPIO_ReadPin(BHI160b_INT_GPIO_Port, BHI160b_INT_Pin) && !bytes_remaining);
bhy_read_fifo(fifo + bytes_left_in_fifo, FIFO_SIZE - bytes_left_in_fifo, &bytes_read, &bytes_remaining);
bytes_read += bytes_left_in_fifo;
fifoptr = fifo;
packet_type = BHY_DATA_TYPE_PADDING;
do
{
/* this function will call callbacks that are registered */
result = bhy_parse_next_fifo_packet(&fifoptr, &bytes_read, &fifo_packet, &packet_type);
/* prints all the debug packets */
if (packet_type == BHY_DATA_TYPE_DEBUG)
{
bhy_print_debug_packet(&fifo_packet.data_debug, bhy_printf);
}
/* the logic here is that if doing a partial parsing of the fifo, then we should not parse */
/* the last 18 bytes (max length of a packet) so that we don't try to parse an incomplete */
/* packet */
} while ((result == BHY_SUCCESS) && (bytes_read > (bytes_remaining ? MAX_PACKET_LENGTH : 0)));
bytes_left_in_fifo = 0;
if (bytes_remaining)
{
/* shifts the remaining bytes to the beginning of the buffer */
while (bytes_left_in_fifo < bytes_read)
{
fifo[bytes_left_in_fifo++] = *(fifoptr++);
}
}
}
}
}
/* USER CODE END 3 */
}
04-23-2021 11:01 AM - edited 04-23-2021 11:05 AM
Hi Sir:
Please see the following picture which was from BHI160 datesheet:
In fact, Game_rotation_vector is got via BSX sensor fusion library which has been intergrated into BHI160 rom. When you enable virtual sensor, because the sample rate of enable function is uint type, so 12.5Hz which is for special mode can't be set,the smallest sample rate is 25Hz.
So recommend you to set a higher sample rate and have to read out all fifo data after interrupt trigger, and then select a downsampling way in host to get the data you need.
Meanwhile, the high sample rate will decrease the latency.
04-25-2021 03:27 PM
Hi Sir:
I took some tests to observe the timestamp interval after change Game_rotation_vector sample rate, actually ,the internal 10 /20 /40 /80 /160 /320 /640ms can be got, it means the actual output sample rate is 100 /50 /25 /12.5 /6.25/3.125 /1.562Hz.
If you set sample rate between two actual sample rate, the output frequence is bigger sample rate. For example, set sample rate is 15, it is between 25hz and 12.5hz, the actual output frequence will be 25hz, the interval will be 40ms, and set 10, the actual output frequence will be 12.5hz, the interval will be 80ms.
Recommend you to have a try to see whether to satisfied your requirement.
If not meet, downsampling way need be considered.