I discovered your manual shortly after posting this and I definitely understand the library better.
Here is my complete code, excuse the mess.
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include <AccelStepper.h>
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 mpu;
//MPU6050 mpu(0x69); // <-- use for AD0 high
/* =========================================================================
NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
depends on the MPU-6050's INT pin being connected to the Arduino's
external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is
digital I/O pin 2.
========================================================================= */
/* =========================================================================
NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error
when using Serial.write(buf, len). The Teapot output uses this method.
The solution requires a modification to the Arduino USBAPI.h file, which
is fortunately simple, but annoying. This will be fixed in the next IDE
release. For more info, see these links:
http://arduino.cc/forum/index.php/topic,109987.0.html http://code.google.com/p/arduino/issues/detail?id=958 ========================================================================= */
#define OUTPUT_READABLE_YAWPITCHROLL
#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;
// MPU control/status vars
bool dmpReady = false; // set true if DMP init was successful
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorInt16 aa; // [x, y, z] accel sensor measurements
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
VectorFloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi] Euler angle container
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };
// Declare variables for PID
float Kp = 100; // (P)roportional Tuning Parameter
float Ki = 0; // (I)ntegral Tuning Parameter
float Kd = 0; // (D)erivative Tuning Parameter
float iTerm = 0; // Used to accumulate error (integral)
float lastTime = 0; // Records the time the function was last called
float maxPID = 1000; // The maximum value that can be output
float oldValue = 0; // The last sensor value
float targetValue = 0;
// Variables for Time Keeper function:
//#define LOOP_TIME 50 // Time in ms (10ms = 100Hz)
unsigned long timerValue = 0;
//
//Stepper motors defined
const int dirPin = 4;
const int stepPin = 5;
//Stepper myStepper(800, 4, 5);
AccelStepper StepperR(1, 5, 4);
AccelStepper StepperL(1, 3, 6);
char inchar = 0;
// ================================================================
// === INTERRUPT DETECTION ROUTINE ===
// ================================================================
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt = true;
}
/****** PID CONTROLLER *****/
float pid(float target, float current) {
// Calculate the time since function was last called
float thisTime = millis();
float dT = thisTime - lastTime;
lastTime = thisTime;
// Calculate error between target and current values
float error = target - current;
// Calculate the integral term
iTerm += error * dT;
// Calculate the derivative term (using the simplification)
float dTerm = (oldValue - current) / dT;
// Set old variable to equal new ones
oldValue = current;
// Multiply each term by its constant, and add it all up
float result = (error * Kp) + (iTerm * Ki) + (dTerm * Kd);
// Limit PID value to maximum values
if (result > maxPID) result = maxPID;
else if (result < -maxPID) result = -maxPID;
return result;
}
// ****************getAngle()*************
float getAngle() {
if (!dmpReady) return 0;
// read a packet from FIFO
if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
return ypr[1] * 180 / M_PI;
#endif
}
}
//**************
//----------speed control
//**************
float wait(float pid) {
return (2000 / pid) + 200;
}
void movemotor(float waittime) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(waittime);
digitalWrite(stepPin, LOW);
delayMicroseconds(waittime);
}
////////////READ SERIAL///////////////////
//////////////////////////////////////////
void readSerial() {
// Initiate all of the variables
// -- -- -- -- -- -- -- -- -- -- -- -- -- --
int changestate = 0; // Which action needs to be taken?
int no_before = 0; // Numbers before decimal point
int no_after = 0; // Numbers after decimal point
bool minus = false; // See if number is negative
inchar = Serial.read(); // Read incoming data
if (inchar == 'P') changestate = 1;
else if (inchar == 'I') changestate = 2;
else if (inchar == 'D') changestate = 3;
// Tell robot to calibrate the Centre of Gravity
//else if (inchar == 'G') calibrateTargets();
// Records all of the incoming data (format: 00.000)
// And converts the chars into a float number
if (changestate > 0){
if (Serial.available() > 0){
// Is the number negative?
inchar = Serial.read();
if(inchar == '-'){
minus = true;
inchar = Serial.read();
}
no_before = inchar - '0';
if (Serial.available() > 0){
inchar = Serial.read();
if (inchar != '.'){
no_before = (no_before * 10) + (inchar - '0');
if (Serial.available() > 0){
inchar = Serial.read();
}
}
if (inchar == '.'){
inchar = Serial.read();
if (inchar != '0'){
no_after = (inchar - '0') * 100;
}
if (Serial.available() > 0){
inchar = Serial.read();
if (inchar != '0'){
no_after = no_after + ((inchar - '0') * 10);
}
if (Serial.available() > 0){
inchar = Serial.read();
if (inchar != '0'){
no_after = no_after + (inchar - '0');
}
}
}
}
}
// Combine the chars into a single float
float answer = float(no_after) / 1000;
answer = answer + no_before;
if (minus) answer = answer * -1;
// Update the PID constants
if (changestate == 1){
Kp = answer;
Serial.print("P - ");
} else if (changestate == 2){
Ki = answer;
Serial.print("I - ");
} else if (changestate == 3){
Kd = answer;
Serial.print("D - ");
}
Serial.print("Constant Set: ");
Serial.println(answer, 3);
} else {
changestate = 0;
}
}
}
// ================================================================
// === INITIAL SETUP ===
// ================================================================
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
Serial.begin(115200);
mpu.initialize();
pinMode(INTERRUPT_PIN, INPUT);
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(7);
mpu.setYGyroOffset(15);
mpu.setZGyroOffset(57);
mpu.setXAccelOffset(943);
mpu.setYAccelOffset(-629);
mpu.setZAccelOffset(1578); // 1688 factory default for my test chip
//Stepper acceleration
// stepper1.setAcceleration(50);
//stepper1.setMaxSpeed(1000);
// make sure it worked (returns 0 if so)
if (devStatus == 0) {
// Calibration Time: generate offsets and calibrate our MPU6050
mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);
mpu.PrintActiveOffsets();
// turn on the DMP, now that it's ready
//Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
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)
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
// configure LED for output
pinMode(LED_PIN, OUTPUT);
//myStepper.setSpeed(4000);
StepperL.setMaxSpeed(10000);
StepperL.setAcceleration(10000);
StepperR.setMaxSpeed(10000);
StepperR.setAcceleration(10000);
//myStepper.setAcceleration(5);
}
float currentValue = 0;
float currentpos = 0;
float prevpos = 0;
// ================================================================
// === MAIN PROGRAM LOOP ===
// ================================================================