-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPositionSensors.cpp
125 lines (99 loc) · 3.48 KB
/
PositionSensors.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "Config.h"
#include "PositionSensors.h"
#include "MPU6050_9Axis_MotionApps41.h"
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;
MPU6050 mpu;
// MPU control/status vars
bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];
// Orientation/motion variables
Quaternion q;
VectorFloat gravity;
float euler[3];
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt = true;
// blink LED to indicate activity
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
}
void PositionSensors::init()
{
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
DEBUG.println(F("Initializing I2C devices..."));
mpu.initialize();
DEBUG.println(F("Testing device connections..."));
DEBUG.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
DEBUG.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// make sure it worked (returns 0 if so)
if (devStatus == 0) {
DEBUG.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
DEBUG.println(F("Enabling interrupt detection ..."));
pinMode(14, INPUT);
attachInterrupt(14, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
DEBUG.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
}
else {
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
DEBUG.print(F("DMP Initialization failed (code "));
DEBUG.print(devStatus);
DEBUG.println(F(")"));
}
// configure LED for output
pinMode(LED_PIN, OUTPUT);
}
void PositionSensors::getYawPitchRoll(float* ypr)
{
const float RADIANS_TO_DEGREES = 57.2958; //180/3.14159
if (mpuInterrupt || fifoCount >= packetSize){
// reset interrupt flag and get INT_STATUS byte
mpuInterrupt = false;
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();
DEBUG.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);
// track FIFO count here in case there is > 1 packet available
// (this lets us immediately read more without waiting for an interrupt)
fifoCount -= packetSize;
// Obtain Euler angles from buffer
//mpu.dmpGetQuaternion(&q, fifoBuffer);
//mpu.dmpGetEuler(euler, &q);
// Obtain YPR angles from buffer
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
}
}
}
bool PositionSensors::dmpIsReady()
{
return dmpReady;
}