Closed mjs513 closed 7 years ago
Do you have an examples of using FIFO.
Here it is:
CurieIMU.setFIFOHeaderModeEnabled(true); CurieIMU.setAccelFIFOEnabled(false); CurieIMU.setGyroFIFOEnabled(true); CurieIMU.setGyroRate(100);
CurieIMU.reg_write_bits(BMI160_RA_FIFO_CONFIG_1, 0x1, BMI160_FIFO_TIME_EN_BIT, 1); CurieIMU.resetFIFO(); CurieIMU.attachInterrupt(bmi160_intr); CurieIMU.reg_write(BMI160_RA_FIFO_CONFIG_0, 0x1); // set FIFO water mark level
CurieIMU.reg_write_bits(BMI160_RA_INT_EN_1, 0x1, BMI160_FWM_INT_BIT, 1);
NOTE: You must alter the BMI160.h to access reg_write() and reg_write_bits().
not sure about the interrupt watermarks and the read fifo header data translation.
Did you read the data sheet? (http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf) "2.6.12FIFOInterrupts" describes the watermark and "2.5.1FIFO Frames" explains how you can translate the header.
Thank you for getting back to me so quickly. I have been going the BMI api from bostec and datasheet in detail since last night. The biggest challengs seems to be reading the frames. In the process now of incorporating the code. I didn't see a burst read function specifically in the bmi160.cpp file, I did see a fifo read bytes function though - have to check to see if that is the same thing.
By the way, nice approach on the writing the library, using the same approach as Jeff Rowberg did for his MPU6050 library. Been using that myself for years in my version of the FreeIMU library. Will keep you posted on it goes if you are interested.
Will keep you posted on it goes if you are interested.
https://github.com/mjs513/FreeIMU-Updates looks nice. I will check a bit later!
The biggest challengs seems to be reading the frames.
This did work:
void bmi160_intr(void) { int fifo_cnt; uint8_t data[1024];
fifo_cnt = CurieIMU.getFIFOCount(); fifo_cnt += 4; CurieIMU.getFIFOBytes(data, fifo_cnt); // show_fifo_frames(data, fifo_cnt); }
void setup() { // initialize device CurieIMU.begin(); CurieIMU.setFIFOHeaderModeEnabled(true); CurieIMU.setAccelFIFOEnabled(false); CurieIMU.setGyroFIFOEnabled(true); //CurieIMU.setGyroRate(25); CurieIMU.setGyroRate(1600);
CurieIMU.reg_write_bits(BMI160_RA_FIFO_CONFIG_1, 0x1, BMI160_FIFO_TIME_EN_BIT, 1); CurieIMU.resetFIFO(); CurieIMU.attachInterrupt(bmi160_intr); CurieIMU.reg_write(BMI160_RA_FIFO_CONFIG_0, 0x1); // set FIFO water mark level
CurieIMU.reg_write_bits(BMI160_RA_INT_EN_1, 0x1, BMI160_FWM_INT_BIT, 1); }
void loop() { delay(1000); }
Thanks for the compliment - seems to be never ending maintaining it. Just got it to work with wifi - which was fun.
Just tried the code and it compiled fine on the Arduino 101 board but nothing seems to be coming out: this is what I changed the code to (not sure if its my showfifo routine that is off or something else
#include "CurieIMU.h"
int fifo_cnt;
uint8_t data[1024];
void bmi160_intr(void)
{
fifo_cnt = CurieIMU.getFIFOCount();
fifo_cnt += 4;
CurieIMU.getFIFOBytes(data, fifo_cnt);
show_fifo_frames();
}
void show_fifo_frames(){
Serial.println(fifo_cnt);
for(int i = 0; i < fifo_cnt; i++){
Serial.println(data[i], HEX);
}
}
void setup() {
// initialize device
Serial.begin(9600);
while (!Serial); // wait for the serial port to open
// initialize device
Serial.println("Initializing IMU device...");
CurieIMU.begin();
// verify connection
Serial.println("Testing device connections...");
if (CurieIMU.begin()) {
Serial.println("CurieIMU connection successful");
} else {
Serial.println("CurieIMU connection failed");
}
CurieIMU.setFIFOHeaderModeEnabled(true);
CurieIMU.setAccelFIFOEnabled(false);
CurieIMU.setGyroFIFOEnabled(true);
//CurieIMU.setGyroRate(25);
CurieIMU.setGyroRate(1600);
#define BMI160_FIFO_TIME_EN_BIT 1
CurieIMU.reg_write_bits(BMI160_RA_FIFO_CONFIG_1, 0x1, BMI160_FIFO_TIME_EN_BIT, 1);
CurieIMU.resetFIFO();
CurieIMU.attachInterrupt(bmi160_intr);
CurieIMU.reg_write(BMI160_RA_FIFO_CONFIG_0, 0x1); // set FIFO water mark level
#define BMI160_FWM_INT_BIT 6
CurieIMU.reg_write_bits(BMI160_RA_INT_EN_1, 0x1, BMI160_FWM_INT_BIT, 1);
}
void loop() {
delay(1000);
}
Been playing around with the code and registers and it does not seem like a interrupt is being generated. Going to keep playing.
Update: ok. I used Serial.println(CurieIMU.reg_read(0x1D), HEX);
to see if the interrupt is tripped or not. Starts out as 0 the goes to 1. So I think that part works.
Did you check this fix? https://github.com/hanyazou/BMI160-Arduino/commit/ebf4924c8a5594ec4fd3cbbcc6ed0d44eaa4004f
No. Didn't see it. Going to check the fix. Not sure if this is going to work. I am using the Arduiono 101 board while the library is geared to a separate board. The interrupts my be handled differently. Just ordered a BMI160 breakout board. Won't be here for a week or so to test.
Oh. One more question if you don't mind. When we enable the fifo is that headerless or with header (control frames too)?
No. Didn't see it.
UPDATE: My log says that the interrupt handling worked without the mod on my 101 board. So you don't need that.
the fifo is that headerless or with header (control frames too)?
You can chose that calling "CurieIMU.setFIFOHeaderModeEnabled(true);".
Success at last (99%). Changed one line and did a few thing to code base and got the fifo data. Interesting thing though is with the gx and gy values, ever other dump is -32768, see below:
a/g: -87 49 16345 -1 -2 2 a/g: -87 49 16345 -32768 -32768 2 a/g: 152 52 16466 4 2 0 a/g: 152 52 16466 -32768 -32768 0 a/g: 64 26 16326 2 -3 -2 a/g: 64 26 16326 -32768 -32768 -2 a/g: 55 -48 16282 2 1 -1 a/g: 55 -48 16282 -32768 -32768 -1 a/g: 71 -23 16443 6 1 2
If I do a show data it works (guess its the added delay):
a/g: 11 39 16402 -3 0 -1 253, 255, 0, 0, 255, 255, 11, 0, 39, 0, 18, 64, 252, 255, 252, 255, .................. a/g: -26 96 16300 -2 -5 -2 254, 255, 251, 255, 254, 255, 230, 255, 96, 0, 172, 63, 251, 255, ................... a/g: 108 -11 16370 -1 3 0 255, 255, 3, 0, 0, 0, 108, 0, 245, 255, 242, 63, 253, 255, 254, ....................... a/g: -30 -5 16339 -3 -6 3 253, 255, 250, 255, 3, 0, 226, 255, 251, 255, 211, 63, 1, 0, 255, 255, ................
Here is a copy of the code I put together:
#include "CurieIMU.h"
#include "BMI160.h"
int fifo_cnt;
uint8_t data[1024];
int16_t ax, ay, az; // accelerometer values
int16_t gx, gy, gz; // gyrometer values
void bmi160_intr(void)
{
fifo_cnt = CurieIMU.getFIFOCount();
fifo_cnt += 4;
CurieIMU.getFIFOBytes(data, fifo_cnt);
gx = (((int16_t)data[1]) << 8) | data[0];
ax = (((int16_t)data[7]) << 8) | data[6];
gy = (((int16_t)data[3]) << 8) | data[2];
ay = (((int16_t)data[9]) << 8) | data[8];
gz = (((int16_t)data[5]) << 8) | data[4];
az = (((int16_t)data[11]) << 8) | data[10];
// display tab-separated accel/gyro x/y/z values
Serial.print("a/g:\t");
Serial.print(ax);
Serial.print("\t");
Serial.print(ay);
Serial.print("\t");
Serial.print(az);
Serial.print("\t");
Serial.print(gx);
Serial.print("\t");
Serial.print(gy);
Serial.print("\t");
Serial.println(gz);
show_fifo_frames();
}
void show_fifo_frames(){
//Serial.println(fifo_cnt);
for(int i = 0; i < fifo_cnt; i++){
Serial.print(data[i]); Serial.print(", ");
}
Serial.println("----------------------");
}
void setup() {
// initialize device
Serial.begin(9600); // initialize Serial communication
while (!Serial); // wait for the serial port to open
// initialize device
Serial.println("Initializing IMU device...");
CurieIMU.begin();
// verify connection
Serial.println("Testing device connections...");
if (CurieIMU.begin()) {
Serial.println("CurieIMU connection successful");
} else {
Serial.println("CurieIMU connection failed");
}
//CurieIMU.setGyroRate(25);
CurieIMU.setAccelerometerRange(2);
CurieIMU.setAccelRate(BMI160_ACCEL_RATE_1600HZ);
CurieIMU.setGyroRange(250);
CurieIMU.setGyroRate(BMI160_GYRO_RATE_1600HZ);
Serial.println("About to calibrate. Make sure your board is stable and upright");
delay(5000);
// The board must be resting in a horizontal position for
// the following calibration procedure to work correctly!
Serial.print("Starting Gyroscope calibration and enabling offset compensation...");
CurieIMU.autoCalibrateGyroOffset();
Serial.println(" Done");
Serial.print("Starting Acceleration calibration and enabling offset compensation...");
CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0);
CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
Serial.println(" Done");
Serial.println("Internal sensor offsets AFTER calibration...");
Serial.print(CurieIMU.getAccelerometerOffset(X_AXIS));
Serial.print("\t"); // -76
Serial.print(CurieIMU.getAccelerometerOffset(Y_AXIS));
Serial.print("\t"); // -2359
Serial.print(CurieIMU.getAccelerometerOffset(Z_AXIS));
Serial.print("\t"); // 1688
Serial.print(CurieIMU.getGyroOffset(X_AXIS));
Serial.print("\t"); // 0
Serial.print(CurieIMU.getGyroOffset(Y_AXIS));
Serial.print("\t"); // 0
Serial.println(CurieIMU.getGyroOffset(Z_AXIS));
CurieIMU.setFIFOHeaderModeEnabled(false);
CurieIMU.setAccelFIFOEnabled(true);
CurieIMU.setGyroFIFOEnabled(true);
#define BMI160_FIFO_TIME_EN_BIT 1
CurieIMU.reg_write_bits(BMI160_RA_FIFO_CONFIG_1, 0x1, BMI160_FIFO_TIME_EN_BIT, 1);
CurieIMU.resetFIFO();
CurieIMU.attachInterrupt(bmi160_intr);
CurieIMU.reg_write(BMI160_RA_FIFO_CONFIG_0, 0b00000101); // set FIFO water mark level
#define BMI160_FWM_INT_BIT 6
CurieIMU.reg_write_bits(BMI160_RA_INT_EN_1, 0x1, BMI160_FWM_INT_BIT, 1);
CurieIMU.resetFIFO();
Serial.println(CurieIMU.reg_read(BMI160_RA_FIFO_CONFIG_0), BIN);
Serial.println(CurieIMU.reg_read(BMI160_RA_FIFO_CONFIG_1), BIN);
Serial.println(CurieIMU.reg_read(BMI160_RA_INT_EN_1),BIN);
}
void loop() {
delay(1);
}
Just an update. got everything working by using the second set of data. Believe this is the only line changed:
CurieIMU.reg_write(BMI160_RA_FIFO_CONFIG_0, 0b00001010); // set FIFO water mark level
By the way do you mind me posting this to the arduino101 board forum or would you prefer to do it. It might help someone else.
update: Incorporated the routine into the CurieIMU MadwickAHRS and I am celebrating. It worked. But the visualizer is off.
Congratulations.
By the way do you mind me posting this to the arduino101 board forum or would you prefer to do it. It might help someone else.
I don't mind. Go ahead.
Thanks again taking the time to work on this. Here's the post on the forum page. https://forum.arduino.cc/index.php?topic=462729.0
Do you have an examples of using FIFO. In the sensortec support.c file I found this code:
I can translate most of the changing the gyro and accel settings no problem but not sure about the interrupt watermarks and the read fifo header data translation. Any help would be appreciated.
Thanks Mike