Hi!
I'm working on a project where I'm using the MPU6050s roll axis. The MPU is connected to an ESP8266 running Arduino code. The sensor itself is working great, but some times (about every minute) the MPU outputs huge noise spikes even when it's laying flat on the table. This mess up the whole readings. Here's the ESP8266 code:
//#define DEBUG
#include <I2Cdev.h>
#include <MPU6050_6Axis_MotionApps20.h>
#include <Wire.h>
#include <Ticker.h>
Ticker TickerMPU1;
MPU6050 mpu(0x68);
//MPU6050 mpu(0x69); // <-- use for AD0 high
void setup() {
// initialize serial communication
Serial.begin(250000);
pinMode(0, OUTPUT);
digitalWrite(0, LOW);
delay(1000);
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin(4, 12); // (SDA, SCL)
Wire.setClock(400000);
mpuInit(mpu);
delay(15000);
TickerMPU1.attach_ms(20, accelerometer1);
}
void accelerometer1()
{
mpuGetValues(mpu);
}
void loop()
{
yield(); // = delay(0); Needed to prevent Watchdog reset
}
void mpuInit(MPU6050 &MpuObject)
{
uint8_t devStatus;
// initialize serial communication
do
{
// initialize device
MpuObject.initialize();
// verify connection
Serial.println(MpuObject.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
// load and configure the DMP
devStatus = MpuObject.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
MpuObject.setXGyroOffset(220);
MpuObject.setYGyroOffset(76);
MpuObject.setZGyroOffset(-85);
MpuObject.setZAccelOffset(1788); // 1688 factory default for my test chip
// make sure it worked (returns 0 if so)
if (devStatus == 0)
{
// turn on the DMP, now that it's ready
Serial.println("devStatus = 0");
MpuObject.setDMPEnabled(true);
}
else
{
Serial.println("\n\n\n\n\nFault\n\n\n\n\n\n");
digitalWrite(0, HIGH);
delay(200);
digitalWrite(0, LOW);
}
} while (devStatus != 0);
/* Serial.println("MPU6050 delay started (15 sec)");
delay(15000); // Needed for stabilisation
Serial.println("initialization finished"); */
}
void mpuGetValues(MPU6050 &MpuObject)
{
Quaternion q; // [w, x, y, z] quaternion container
VectorFloat gravity; // [x, y, z] gravity vector
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
uint8_t fifoBuffer[64]; // FIFO storage buffer
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
// get INT_STATUS byte
mpuIntStatus = mpu.getIntStatus();
// get current FIFO count
fifoCount = mpu.getFIFOCount();
// check for overflow (this should never happen unless our code is too inefficient)
if ((mpuIntStatus & 0x10) || fifoCount == 1024)
{
// reset so we can continue cleanly
mpu.resetFIFO();
// Serial.println(F("FIFO overflow!"));
// otherwise, check for DMP data ready interrupt (this should happen frequently)
}
else if (mpuIntStatus & 0x02)
{
// wait for correct available data length, should be a VERY short wait
while (fifoCount < packetSize)
fifoCount = mpu.getFIFOCount();
// read a packet from FIFO
mpu.getFIFOBytes(fifoBuffer, packetSize);
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial.println(ypr[2] * 360/M_PI + 180);
}
}
I've copied all the readings into MS Excel, and plotted it. A reading was done every 20 millisecond. I'm not using the interrupt pin. Here's what the noise looks like:
What's wrong and how can I fix this? Thanks