Skip to content

Commit 2e9042c

Browse files
authored
Merge pull request jrowberg#354 from jrowberg/develop
Pls try this code ... my freezing problem is been resolved to greater extent...
2 parents 6dd5e46 + d0d3a36 commit 2e9042c

File tree

7 files changed

+97
-38
lines changed

7 files changed

+97
-38
lines changed

Arduino/MPU6050/MPU6050.cpp

+2-10
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,13 @@ THE SOFTWARE.
3636

3737
#include "MPU6050.h"
3838

39-
/** Default constructor, uses default I2C address.
40-
* @see MPU6050_DEFAULT_ADDRESS
41-
*/
42-
MPU6050::MPU6050() {
43-
devAddr = MPU6050_DEFAULT_ADDRESS;
44-
}
45-
4639
/** Specific address constructor.
47-
* @param address I2C address
40+
* @param address I2C address, uses default I2C address if none is specified
4841
* @see MPU6050_DEFAULT_ADDRESS
4942
* @see MPU6050_ADDRESS_AD0_LOW
5043
* @see MPU6050_ADDRESS_AD0_HIGH
5144
*/
52-
MPU6050::MPU6050(uint8_t address) {
53-
devAddr = address;
45+
MPU6050::MPU6050(uint8_t address):devAddr(address) {
5446
}
5547

5648
/** Power on and prepare for general usage.

Arduino/MPU6050/MPU6050.h

+13-14
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,7 @@ THE SOFTWARE.
435435

436436
class MPU6050 {
437437
public:
438-
MPU6050();
439-
MPU6050(uint8_t address);
438+
MPU6050(uint8_t address=MPU6050_DEFAULT_ADDRESS);
440439

441440
void initialize();
442441
bool testConnection();
@@ -459,15 +458,15 @@ class MPU6050 {
459458
uint8_t getFullScaleGyroRange();
460459
void setFullScaleGyroRange(uint8_t range);
461460

462-
// SELF_TEST registers
463-
uint8_t getAccelXSelfTestFactoryTrim();
464-
uint8_t getAccelYSelfTestFactoryTrim();
465-
uint8_t getAccelZSelfTestFactoryTrim();
461+
// SELF_TEST registers
462+
uint8_t getAccelXSelfTestFactoryTrim();
463+
uint8_t getAccelYSelfTestFactoryTrim();
464+
uint8_t getAccelZSelfTestFactoryTrim();
465+
466+
uint8_t getGyroXSelfTestFactoryTrim();
467+
uint8_t getGyroYSelfTestFactoryTrim();
468+
uint8_t getGyroZSelfTestFactoryTrim();
466469

467-
uint8_t getGyroXSelfTestFactoryTrim();
468-
uint8_t getGyroYSelfTestFactoryTrim();
469-
uint8_t getGyroZSelfTestFactoryTrim();
470-
471470
// ACCEL_CONFIG register
472471
bool getAccelXSelfTest();
473472
void setAccelXSelfTest(bool enabled);
@@ -823,8 +822,6 @@ class MPU6050 {
823822

824823
// special methods for MotionApps 2.0 implementation
825824
#ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS20
826-
uint8_t *dmpPacketBuffer;
827-
uint16_t dmpPacketSize;
828825

829826
uint8_t dmpInitialize();
830827
bool dmpPacketAvailable();
@@ -924,8 +921,6 @@ class MPU6050 {
924921

925922
// special methods for MotionApps 4.1 implementation
926923
#ifdef MPU6050_INCLUDE_DMP_MOTIONAPPS41
927-
uint8_t *dmpPacketBuffer;
928-
uint16_t dmpPacketSize;
929924

930925
uint8_t dmpInitialize();
931926
bool dmpPacketAvailable();
@@ -1027,6 +1022,10 @@ class MPU6050 {
10271022
private:
10281023
uint8_t devAddr;
10291024
uint8_t buffer[14];
1025+
#if defined(MPU6050_INCLUDE_DMP_MOTIONAPPS20) or defined(MPU6050_INCLUDE_DMP_MOTIONAPPS41)
1026+
uint8_t *dmpPacketBuffer;
1027+
uint16_t dmpPacketSize;
1028+
#endif
10301029
};
10311030

10321031
#endif /* _MPU6050_H_ */

Arduino/MPU6050/MPU6050_6Axis_MotionApps20.h

+26-2
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
269269
0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF
270270
};
271271

272+
#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR
273+
#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x01
274+
#endif
275+
272276
// thanks to Noah Zerkin for piecing this stuff together!
273277
const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = {
274278
// BANK OFFSET LENGTH [DATA]
@@ -302,7 +306,7 @@ const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = {
302306
0x07, 0x46, 0x01, 0x9A, // CFG_GYRO_SOURCE inv_send_gyro
303307
0x07, 0x47, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_9 inv_send_gyro -> inv_construct3_fifo
304308
0x07, 0x6C, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_12 inv_send_accel -> inv_construct3_fifo
305-
0x02, 0x16, 0x02, 0x00, 0x01 // D_0_22 inv_set_fifo_rate
309+
0x02, 0x16, 0x02, 0x00, MPU6050_DMP_FIFO_RATE_DIVISOR // D_0_22 inv_set_fifo_rate
306310

307311
// This very last 0x01 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz,
308312
// 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data.
@@ -395,7 +399,7 @@ uint8_t MPU6050::dmpInitialize() {
395399
setClockSource(MPU6050_CLOCK_PLL_ZGYRO);
396400

397401
DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled..."));
398-
setIntEnabled(0x12);
402+
setIntEnabled(1<<MPU6050_INTERRUPT_FIFO_OFLOW_BIT|1<<MPU6050_INTERRUPT_DMP_INT_BIT);
399403

400404
DEBUG_PRINTLN(F("Setting sample rate to 200Hz..."));
401405
setRate(4); // 1khz / (1 + 4) = 200 Hz
@@ -703,6 +707,8 @@ uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) {
703707
data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi
704708
return 0;
705709
}
710+
711+
#ifdef USE_OLD_DMPGETYAWPITCHROLL
706712
uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
707713
// yaw: (about Z axis)
708714
data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
@@ -712,6 +718,24 @@ uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gra
712718
data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z));
713719
return 0;
714720
}
721+
#else
722+
uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
723+
// yaw: (about Z axis)
724+
data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
725+
// pitch: (nose up/down, about Y axis)
726+
data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
727+
// roll: (tilt left/right, about X axis)
728+
data[2] = atan2(gravity -> y , gravity -> z);
729+
if (gravity -> z < 0) {
730+
if(data[1] > 0) {
731+
data[1] = PI - data[1];
732+
} else {
733+
data[1] = -PI - data[1];
734+
}
735+
}
736+
return 0;
737+
}
738+
#endif
715739

716740
// uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet);
717741
// uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet);

Arduino/MPU6050/MPU6050_9Axis_MotionApps41.h

+27-3
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = {
262262
0xDC, 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF
263263
};
264264

265+
#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR
266+
#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x03
267+
#endif
268+
265269
const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = {
266270
// BANK OFFSET LENGTH [DATA]
267271
0x02, 0xEC, 0x04, 0x00, 0x47, 0x7D, 0x1A, // ?
@@ -302,9 +306,9 @@ const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = {
302306
0x07, 0x67, 0x01, 0x9A, // ?
303307
0x07, 0x68, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_12 inv_send_accel -> inv_construct3_fifo
304308
0x07, 0x8D, 0x04, 0xF1, 0x28, 0x30, 0x38, // ??? CFG_12 inv_send_mag -> inv_construct3_fifo
305-
0x02, 0x16, 0x02, 0x00, 0x03 // D_0_22 inv_set_fifo_rate
309+
0x02, 0x16, 0x02, 0x00, MPU6050_DMP_FIFO_RATE_DIVISOR // D_0_22 inv_set_fifo_rate
306310

307-
// This very last 0x01 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz,
311+
// This very last 0x03 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz,
308312
// 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data.
309313
// DMP output frequency is calculated easily using this equation: (200Hz / (1 + value))
310314

@@ -432,7 +436,7 @@ uint8_t MPU6050::dmpInitialize() {
432436
DEBUG_PRINTLN(F("Success! DMP configuration written and verified."));
433437

434438
DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled..."));
435-
setIntEnabled(0x12);
439+
setIntEnabled(1<<MPU6050_INTERRUPT_FIFO_OFLOW_BIT|1<<MPU6050_INTERRUPT_DMP_INT_BIT);
436440

437441
DEBUG_PRINTLN(F("Setting sample rate to 200Hz..."));
438442
setRate(4); // 1khz / (1 + 4) = 200 Hz
@@ -808,6 +812,8 @@ uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) {
808812
data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi
809813
return 0;
810814
}
815+
816+
#ifdef USE_OLD_DMPGETYAWPITCHROLL
811817
uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
812818
// yaw: (about Z axis)
813819
data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
@@ -817,6 +823,24 @@ uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gra
817823
data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z));
818824
return 0;
819825
}
826+
#else
827+
uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
828+
// yaw: (about Z axis)
829+
data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
830+
// pitch: (nose up/down, about Y axis)
831+
data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
832+
// roll: (tilt left/right, about X axis)
833+
data[2] = atan2(gravity -> y , gravity -> z);
834+
if(gravity->z<0) {
835+
if(data[1]>0) {
836+
data[1] = PI - data[1];
837+
} else {
838+
data[1] = -PI - data[1];
839+
}
840+
}
841+
return 0;
842+
}
843+
#endif
820844

821845
// uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet);
822846
// uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet);

Arduino/MPU6050/examples/MPU6050_DMP6/MPU6050_DMP6.ino

+11-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
44
//
55
// Changelog:
6+
// 2016-04-18 - Eliminated a potential infinite loop
67
// 2013-05-08 - added seamless Fastwire support
78
// - added note about gyro calibration
89
// 2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error
@@ -212,7 +213,9 @@ void setup() {
212213
mpu.setDMPEnabled(true);
213214

214215
// enable Arduino interrupt detection
215-
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
216+
Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
217+
Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));
218+
Serial.println(F(")..."));
216219
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
217220
mpuIntStatus = mpu.getIntStatus();
218221

@@ -248,6 +251,10 @@ void loop() {
248251

249252
// wait for MPU interrupt or extra packet(s) available
250253
while (!mpuInterrupt && fifoCount < packetSize) {
254+
if (mpuInterrupt && fifoCount < packetSize) {
255+
// try to get out of the infinite loop
256+
fifoCount = mpu.getFIFOCount();
257+
}
251258
// other program behavior stuff here
252259
// .
253260
// .
@@ -268,13 +275,14 @@ void loop() {
268275
fifoCount = mpu.getFIFOCount();
269276

270277
// check for overflow (this should never happen unless our code is too inefficient)
271-
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
278+
if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
272279
// reset so we can continue cleanly
273280
mpu.resetFIFO();
281+
fifoCount = mpu.getFIFOCount();
274282
Serial.println(F("FIFO overflow!"));
275283

276284
// otherwise, check for DMP data ready interrupt (this should happen frequently)
277-
} else if (mpuIntStatus & 0x02) {
285+
} else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) {
278286
// wait for correct available data length, should be a VERY short wait
279287
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
280288

Arduino/MPU6050/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino

+14-6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
55
//
66
// Changelog:
7+
// 2016-04-18 - Eliminated a potential infinite loop
78
// 2016-02-28 - Cleaned up code to be in line with other example codes
8-
// - Added Ethernet outputs for Quaternion, Euler, RealAccel, WorldAccel
9+
// - Added Ethernet outputs for Quaternion, Euler, RealAccel, WorldAccel
910
// 2016-02-27 - Initial working code compiled
1011
// Bugs:
1112
// - There is still a hangup after some time, though it only occurs when you are reading data from the website.
@@ -218,7 +219,9 @@ void setup() {
218219
mpu.setDMPEnabled(true);
219220

220221
// enable Arduino interrupt detection
221-
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
222+
Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
223+
Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));
224+
Serial.println(F(")..."));
222225
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
223226
mpuIntStatus = mpu.getIntStatus();
224227

@@ -236,7 +239,6 @@ void setup() {
236239
Serial.print(F("DMP Initialization failed (code "));
237240
Serial.print(devStatus);
238241
Serial.println(F(")"));
239-
return;
240242
}
241243

242244
// configure LED for output
@@ -252,9 +254,14 @@ void setup() {
252254
void loop() {
253255
// if programming failed, don't try to do anything
254256
if (!dmpReady) return;
257+
255258
wdt_reset();//Resets the watchdog timer. If the timer is not reset, and the timer expires, a watchdog-initiated device reset will occur.
256259
// wait for MPU interrupt or extra packet(s) available
257260
while (!mpuInterrupt && fifoCount < packetSize) {
261+
if (mpuInterrupt && fifoCount < packetSize) {
262+
// try to get out of the infinite loop
263+
fifoCount = mpu.getFIFOCount();
264+
}
258265
// other program behavior stuff here
259266
// .
260267
// .
@@ -274,13 +281,14 @@ void loop() {
274281
fifoCount = mpu.getFIFOCount();
275282

276283
// check for overflow (this should never happen unless our code is too inefficient)
277-
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
284+
if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {
278285
// reset so we can continue cleanly
279286
mpu.resetFIFO();
287+
fifoCount = mpu.getFIFOCount();
280288
Serial.println(F("FIFO overflow!"));
281289

282290
// otherwise, check for DMP data ready interrupt (this should happen frequently)
283-
} else if (mpuIntStatus & 0x02) {
291+
} else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) {
284292
// wait for correct available data length, should be a VERY short wait
285293
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
286294

@@ -534,4 +542,4 @@ void GetAjaxData(EthernetClient cl)
534542
cl.print("\t");
535543
cl.println("</p>");
536544
#endif
537-
}
545+
}

RaspberryPi_bcm2835/I2Cdev/I2Cdev.h

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ THE SOFTWARE.
3030
#ifndef _I2CDEV_H_
3131
#define _I2CDEV_H_
3232

33+
#ifndef __cplusplus
34+
#error A C++ compiler is required!
35+
#endif
36+
3337
#include <bcm2835.h>
3438
#include <math.h> // required for BMP180
3539
#include <stdlib.h> // required for MPU6060

0 commit comments

Comments
 (0)