Hello.
I try to determine MPU FIFO data count by using interrupt but form unknow reason this couter slowly reise comparing to register value (see plotter).
MPU is connected with arduino ~1m cable. To the INT pin on Gy-521 board I also add 0.1uF capacitor otherwise MPU hang.
I also try to connect INT using as short cable as it possible with same resoult.
So problem is in my code, too long wires, 3.3V MPU logic or something else?
here is some code cutted from my project for demonstrate.
#include <Wire.h>
#define MPU_addr 0x68
void setup() {
Serial.begin(2000000);
Wire.begin();
Wire.setClock(800000L); // TWBR = 2;
MPU_init();
MPU_FifoFlush();
}
volatile uint32_t FifoCnt = 0;
uint16_t cnt, cntInt;
int fPID = 25; // process PID each 25 samples
int pidcnt = 0;
void loop() {
cnt = floor(MPU_GetFifoCount()/2.0);
cntInt = FifoCnt;
if (cnt >= 16)
// if ( ( (pidcnt + cnt) >= fPID ) || (cnt >= 16) ) // look crazy in plotter but it keep smallest deviation of intervals for PID so its more stable
// if ( (pidcnt + cnt) >= fPID )
{
// compare register and interrupt couters
Serial.print(cnt); Serial.print(" ");
Serial.print(cntInt); Serial.print(" ");
Serial.println("");
FifoCnt -= cnt;
while (cnt > 0) {
updateangle(min(cnt, 16));
cnt -= min(cnt, 16);
}
}
}
void updateangle(int cnt) {
MPU_readFIFO(cnt);
for (int i = 0; i < cnt; i++) {
int gx = Wire.read() << 8 | Wire.read();
// some other code
pidcnt++;
if (pidcnt >= fPID) {
// Serial.println(cnt);
pidcnt = 0;
// PID();
}
}
}
void MPUiter() {
FifoCnt++;
}
uint16_t MPU_GetFifoCount() {
Wire.beginTransmission(MPU_addr);
Wire.write(0x72); // FIFO_COUNTH
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr, 2, true);
return Wire.read() << 8 | Wire.read();
}
void MPU_readFIFO(int c) {
Wire.beginTransmission(MPU_addr);
Wire.write(0x74); // FIFO_R_W
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr, c * 2, true);
}
void MPU_FifoFlush(){
Wire.beginTransmission(MPU_addr);
Wire.write(0x6A); // USER_CTRL
Wire.write(0B01000100); // USER_CTRL
Wire.endTransmission(false);
}
void MPU_init() {
// init
Wire.beginTransmission(MPU_addr);
Wire.write(0x6b); // PWR_MGMT_1
Wire.write(0);
Wire.endTransmission(false);
attachInterrupt(0, MPUiter, RISING);
// set full scale range
Wire.beginTransmission(MPU_addr);
Wire.write(0x1B); // GYRO_CONFIG
Wire.write(0B00000000); // FS_SEL
Wire.endTransmission(false);
// DLPF
Wire.beginTransmission(MPU_addr);
Wire.write(0x1A); // CONFIG
Wire.write(0B00000000); // DLPF_CFG - fs=8kHz
Wire.endTransmission(false);
// fs divider
Wire.beginTransmission(MPU_addr);
Wire.write(0x19); // SMPLRT_DIV
Wire.write(3); // SMPLRT_DIV - 3->2kHz
Wire.endTransmission(false);
// enable gyro x axis for FIFO
Wire.beginTransmission(MPU_addr);
Wire.write(0x23); // FIFO_EN
Wire.write(0B01000000); // XG_FIFO_EN
Wire.endTransmission(false);
// active-high / push-pull / 50us
Wire.beginTransmission(MPU_addr);
Wire.write(0x37); // INT_PIN_CFG
Wire.write(0B00000000);
Wire.endTransmission(false);
// interrupt on new data ready
Wire.beginTransmission(MPU_addr);
Wire.write(0x38); // INT_ENABLE
Wire.write(0B00000001); // DATA_RDY_EN
Wire.endTransmission(false);
}