05-20-2022 03:17 PM - edited 05-21-2022 06:17 AM
I read BMI270 by ESP32 programmed in Arduino IDE so I cannot use the existing API directly, have to correct it substantially. By now reading accelerometer and gyro data directly, sample by sample is no problem but I need to use FIFO to shorten communication time to save the energy consumed.
I use API example file "fifo_full_headerless_mode.c" as a start point. For the beginning, having some difficulties with interrupts, I just want to read the FIFO content each 2 seconds, regardless of overflow. Using a part of the code from the said file which I understand is responsible for it. It reads 168 samples, but strange values (acc and gyro): first 45 samples are constant values , then some random values (not noise). But what puzzles me most is not the values, I understand something with ODR, etc., may be configured wrongly still, but the signals on the communication lines. I understand it should be packets about 2000 bytes long, right? But I observe 9 short bursts, about 2 bytes each, see attachment. But the code reports all bytes received (?!):
15:40:33.904 -> FIFO data bytes available : 2016
15:40:33.904 -> FIFO data bytes requested : 2016
15:40:33.904 -> FIFO accel frames requested : 170
15:40:33.904 -> FIFO accel frames extracted : 168
15:40:33.904 -> FIFO gyro frames requested : 170
15:40:33.938 -> FIFO gyro frames extracted : 168
But such amount of data does NOT go through the line! I have absolutely no clue, may be someone more experienced can give some ideas - where to investigate?
Here are values of registers I consider relevant, read at the end of setup():
15:55:27.068 -> Read 0x49 FIFO_CONFIG_1 HEX = C0 BIN = 11000000
15:55:27.068 -> Read 0x58 INT_MAP_DATA HEX = 41 BIN = 1000001
15:55:27.068 -> Read 0x53 INT1_IO_CTRL HEX = A BIN = 1010
15:55:27.101 -> Read 0x55 INT_LATCH HEX = 0 BIN = 0
- may some others need attention?
Attachment: SDA line of I2C interface. The same each 2 seconds.
Thanks
05-20-2022 03:40 PM
Below is the function called each 2 seconds to read FIFO. I believe it should work the same way as called by an interrupt?
I mean to read the whole FIFO length, no matter owerflow or no overflow the data is?
void readFifo(){
uint8_t index;
// rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev);
rslt = bmi2_get_fifo_length(&fifo_length, &bmi2);
// bmi2_error_codes_print_result(rslt);
//fifo_length = 170;
//Serial.println(fifo_length);
accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT;
gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT;
/* Updating FIFO length to be read based on available length and dummy byte updation */
fifoframe.length = fifo_length + bmi2_dev.dummy_byte;
printf("\nFIFO data bytes available : %d \n", fifo_length);
printf("\nFIFO data bytes requested : %d \n", fifoframe.length);
/* Read FIFO data. */
rslt = bmi2_read_fifo_data(&fifoframe, &bmi2);
// bmi2_error_codes_print_result(rslt);
/* Read FIFO data on interrupt. */
rslt = bmi2_get_int_status(&int_status, &bmi2);
// bmi2_error_codes_print_result(rslt);
if (rslt == BMI2_OK)
{
printf("\nFIFO accel frames requested : %d \n", accel_frame_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */
rslt = bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2);
printf("\nFIFO accel frames extracted : %d \n", accel_frame_length);
printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length);
/* Parse the FIFO data to extract gyro data from the FIFO buffer. */
rslt = bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2);
printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length);
printf("\nExtracted accel frames\n");
/* Print the parsed accelerometer data from the FIFO buffer.
for (index = 0; index < accel_frame_length; index++)
{
printf("ACCEL[%d] X : %d\t Y : %d\t Z : %d\n", index, fifo_accel_data[index].x,
fifo_accel_data[index].y, fifo_accel_data[index].z);
}
printf("\nExtracted gyro frames\n");
for (index = 0; index < gyro_frame_length; index++)
{
printf("GYRO[%d] X : %d\t Y : %d\t Z : %d\n",
index,
fifo_gyro_data[index].x,
fifo_gyro_data[index].y,
fifo_gyro_data[index].z);
}
*/
}
// try++;
}
05-22-2022 09:28 AM
I tried to parse the signal manually, got:
0x68, write, ack, 0x1D (INT_STATUS_1), write, ack
0.9 ms
0x68, read, ack, 0xC1 bin 1100 0001 (?), nack, 0(?)
0.9 ms
0x68, write, ack, 0x24 (FIFO_LENGTH_0), write, ack
0.8 ms
0x68, read, ack, bin 11100000 ack 00000 (?)
2.5 ms
0x68, write, ack, 0x26 (FIFO_DATA), write, ack
2.5 ms
0x68, write??, ack, 0x48 (FIFO_CONFIG_0), write, ack
1.2 ms
0x68, read, ACK, bin 0000 0010 1100 0000 1(nack?) 1110 1000 0 0000 1110 000 (?)
1 ms
0x68, read, ACK, bin 0000 0000 ack 1100 0001 1(nack?) 0(?)
05-24-2022 05:41 PM
Hi Anatol,
1. BMI270 sensor API didn't directly run on Arduino platform, for I2C communication on ESP32 you could refer ESP32 platform's driver code to implement bmi2_i2c_read() and bmi2_i2c_write() function;
2. As you refer example file "fifo_full_headerless_mode.c" and read the FIFO content each 2 seconds, what's ODR you used?
05-25-2022 05:34 PM
Hi BSTRobin.
1. Yes, I edited those functions implementing Arduino "Wire" library into them, it worked well polling separate readings. I guess the main problem is that library has buffer 32 bytes only, but to read fifo I need 2000+ bytes in a burst read. I tried several others I2C libraries but no luck, they either has the buffer length defined as 8 bits variable so limiting to 256 bytes (including Wire lib), or linked to others libraries and doesn't compile without them. If anyone could point out an Arduino solution to read 2000 bytes in burst - it would be appretiated very much.
2. ODR is 50 Hz, so fifo is defenitely overflown.