I was trying to get the data from MPU6050 using the Arduino library mentioned here.
The following code is an edited version of the sample code given in the library folder which seems to be working fine.
#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps_V6_12.h"
#include "Wire.h"
MPU6050 accelgyro;
MPU6050 mpu;
I2Cdev a;
/*
IMU Zero variables
*/
int16_t data_acc[3];
int16_t data_Gyro[3];
/*
IMU initialization variables
*/
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
bool dmpReady = false; // set true if DMP init was successful
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
/*
IMU angle finding variables
*/
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
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
void Initialize()
{
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
Serial.println("tuning Each Dot = 100 readings");
accelgyro.CalibrateAccel(10);
accelgyro.CalibrateGyro(10);
a.readWords(0x68, 0x06, 3, (uint16_t )data_acc);
a.readWords(0x68, 0x13, 3, (uint16_t )data_Gyro);
} // Initialize
void setup() {
Wire.begin();
Serial.begin(115200);
Initialize();
Wire.setClock(400000);
while (!Serial);
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
Serial.println(F("\nSend any character to begin DMP programming and demo: "));
while (Serial.available() && Serial.read()); // empty buffer
while (!Serial.available()); // wait for data
while (Serial.available() && Serial.read()); // empty buffer again
// load and configure the DMP
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(data_Gyro[0]);
mpu.setYGyroOffset(data_Gyro[1]);
mpu.setZGyroOffset(data_Gyro[2]);
mpu.setXAccelOffset(data_acc[0]);
mpu.setYAccelOffset(data_acc[1]);
mpu.setZAccelOffset(data_acc[2]);
if (devStatus == 0) {
// Calibration Time: generate offsets and calibrate our MPU6050
mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);
Serial.println();
mpu.PrintActiveOffsets();
// turn on the DMP, now that it's ready
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
mpuIntStatus = mpu.getIntStatus();
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
Serial.println("-------------- done --------------");
} // setup
void loop()
{
if (!dmpReady) return;
if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial.print("ypr\t");
Serial.print(ypr[0] * 180 / M_PI);
Serial.print("\t");
Serial.print(ypr[1] * 180 / M_PI);
Serial.print("\t");
Serial.print(ypr[2] * 180 / M_PI);
Serial.println();
}
}
Then I have activated the input capture pin to use with the interrupt and the code is as follows
#define printfloatx(Name,Variable,Spaces,Precision,EndTxt) { Serial.print(F(Name)); {char S[(Spaces + Precision + 3)];Serial.print(F(" ")); Serial.print(dtostrf((float)Variable,Spaces,Precision ,S));}Serial.print(F(EndTxt)); }//Name,Variable,Spaces,Precision,EndTxt
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps_V6_12.h"
#include "Wire.h"
MPU6050 accelgyro;
volatile MPU6050 mpu;
I2Cdev a;
/*
IMU Zero variables
*/
int16_t data_acc[3];
int16_t data_Gyro[3];
/*
IMU initialization variables
*/
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
bool dmpReady = false; // set true if DMP init was successful
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
/*
IMU angle finding variables
*/
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
Quaternion q; // [w, x, y, z] quaternion container
VectorFloat gravity; // [x, y, z] gravity vector
volatile float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
void Initialize()
{
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
Serial.println("tuning Each Dot = 100 readings");
accelgyro.CalibrateAccel(10);
accelgyro.CalibrateGyro(10);
a.readWords(0x68, 0x06, 3, (uint16_t )data_acc);
a.readWords(0x68, 0x13, 3, (uint16_t )data_Gyro);
} // Initialize
void timer4_initialization() {
pinMode(49, INPUT);
TCCR4A = 0; TCCR4B = 0; TCCR4C = 0;
TCCR4B = B11000000;
TIFR4 = _BV(ICF4);
TIMSK4 = B00100000;
}
ISR(TIMER4_CAPT_vect) {
if (!dmpReady) return;
if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) {
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
}
}
void setup() {
Wire.begin();
Serial.begin(115200);
Initialize();
Wire.setClock(400000);
while (!Serial);
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
Serial.println(F("\nSend any character to begin DMP programming and demo: "));
while (Serial.available() && Serial.read()); // empty buffer
while (!Serial.available()); // wait for data
while (Serial.available() && Serial.read()); // empty buffer again
// load and configure the DMP
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(data_Gyro[0]);
mpu.setYGyroOffset(data_Gyro[1]);
mpu.setZGyroOffset(data_Gyro[2]);
mpu.setXAccelOffset(data_acc[0]);
mpu.setYAccelOffset(data_acc[1]);
mpu.setZAccelOffset(data_acc[2]);
if (devStatus == 0) {
// Calibration Time: generate offsets and calibrate our MPU6050
mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);
Serial.println();
mpu.PrintActiveOffsets();
// turn on the DMP, now that it's ready
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
mpuIntStatus = mpu.getIntStatus();
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
Serial.println("-------------- done --------------");
delay(2000);
timer4_initialization();
} // setup
void loop()
{
Serial.print("ypr\t");
Serial.print(ypr[0] * 180 / M_PI);
Serial.print("\t");
Serial.print(ypr[1] * 180 / M_PI);
Serial.print("\t");
Serial.print(ypr[2] * 180 / M_PI);
Serial.println();
}
Here when I am using with the interrupt I am not getting anything printed, seems like the program is frozen somewhere in the interrupt -> function call.
What is the mistake I am making here.
How to take the measurement from MPU6050 using ISR routines.