Thursday, 23 February 2017

DMP motion accelerometer WORKING with arduino 9DOF MPU-9150 3 Axis Gyroscope Accelerometer Magnetic Field

used the 9DOF for stability of the robot in the picture
 #include "Wire.h"  
 //#include "MPU9150.h"  
 // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files  
 // for both classes must be in the include path of your project  
 #include "I2Cdev.h"  
 #include "MPU6050_6Axis_MotionApps20.h"  
 //#include "MPU6050.h" // not necessary if using MotionApps include file  
 // 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  
 MPU6050 mpu;  
 // uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/  
 // pitch/roll angles (in degrees) calculated from the quaternions coming  
 // from the FIFO. Note this also requires gravity vector calculations.  
 // Also note that yaw/pitch/roll angles suffer from gimbal lock (for  
 // more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)  
 #define OUTPUT_READABLE_YAWPITCHROLL  
 #define OUTPUT_READABLE_EULER  
 //#define OUTPUT_READABLE_REALACCEL  
 #define OUTPUT_READABLE_WORLDACCEL  
 // uncomment "OUTPUT_TEAPOT" if you want output that matches the  
 // format used for the InvenSense teapot demo  
 //#define OUTPUT_TEAPOT  
 // 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  
 int yaw=0;  
 int pitch=0;  
 int roll=0;  
 int accX=0;  
 int accY=0;  
 int accZ=0;  
 // packet structure for InvenSense teapot demo  
 uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };  
 // ================================================================  
 // ===        INTERRUPT DETECTION ROUTINE        ===  
 // ================================================================  
 volatile bool mpuInterrupt = false;   // indicates whether MPU interrupt pin has gone high  
 void dmpDataReady() {  
   mpuInterrupt = true;  
 }  
 // ================================================================  
 //*******************#include "MPU9150.h"  
 #include "helper_3dmath.h"  
 #include <AFMotor.h>//Motor library provides control to the arduino motor shield   
 //MPU9150 accelGyroMag;  
 int16_t ax, ay, az;  
 int16_t gx, gy, gz;  
 int16_t mx, my, mz;  
 //#define LED_PIN 13  
 bool blinkState = false;  
 int data=0;//Integer variable which will store the data received by bluetooth      
 int* value;  
 AF_DCMotor motor1(1, MOTOR12_64KHZ); // Create access to motor #2, 64KHz pwm  
 AF_DCMotor motor2(2, MOTOR12_64KHZ); // Create access to motor #2, 64KHz pwm  
 AF_DCMotor motor3(3, MOTOR12_64KHZ); // Create access to motor #2, 64KHz pwm  
 AF_DCMotor motor4(4, MOTOR12_64KHZ); // Create access to motor #2, 64KHz pwm  
 void setup()   
 {  
  Wire.begin();  
 // join I2C bus (I2Cdev library doesn't do this automatically)  
   #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE  
     Wire.begin();  
     TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)  
   #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE  
     Fastwire::setup(400, true);  
   #endif  
   // initialize serial communication  
   // (115200 chosen because it is required for Teapot Demo output, but it's  
   // really up to you depending on your project)  
   Serial.begin(9600);  
   while (!Serial); // wait for Leonardo enumeration, others continue immediately  
   // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio  
   // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to  
   // the baud timing being too misaligned with processor ticks. You must use  
   // 38400 or slower in these cases, or use some kind of external separate  
   // crystal solution for the UART timer.  
   // initialize device  
   Serial.println(F("Initializing I2C devices..."));  
   mpu.initialize();  
   // verify connection  
   Serial.println(F("Testing device connections..."));  
   Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));  
   // wait for ready  
   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(220);  
   mpu.setYGyroOffset(76);  
   mpu.setZGyroOffset(-85);  
   mpu.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(F("Enabling DMP..."));  
     mpu.setDMPEnabled(true);  
     // enable Arduino interrupt detection  
     Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));  
     attachInterrupt(0, dmpDataReady, RISING);  
     mpuIntStatus = mpu.getIntStatus();  
     // set our DMP Ready flag so the main loop() function knows it's okay to use it  
     Serial.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)  
     Serial.print(F("DMP Initialization failed (code "));  
     Serial.print(devStatus);  
     Serial.println(F(")"));  
   }  
   // configure LED for output  
   //pinMode(LED_PIN, OUTPUT);  
 }  
 void loop()   
 {  //int *pointer;  
 int a=255;   
         int b=0;  
         int c=180;  
         int d=180;  
  // if programming failed, don't try to do anything  
   if (!dmpReady) return;  
   // wait for MPU interrupt or extra packet(s) available  
   while (!mpuInterrupt && fifoCount < packetSize) {  
     // other program behavior stuff here  
     // .  
     // .  
     // .  
     // if you are really paranoid you can frequently test in between other  
     // stuff to see if mpuInterrupt is true, and if so, "break;" from the  
     // while() loop to immediately process the MPU data  
     // .  
     // .  
     // .  
   }  
   // 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();  
     //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);  
     // track FIFO count here in case there is > 1 packet available  
     // (this lets us immediately read more without waiting for an interrupt)  
     fifoCount -= packetSize;  
     //#ifdef OUTPUT_READABLE_EULER  
       // display Euler angles in degrees  
      // mpu.dmpGetQuaternion(&q, fifoBuffer);  
       //mpu.dmpGetEuler(euler, &q);  
       //Serial.print("euler\t");  
       //Serial.print(euler[0] * 180/M_PI);  
       //Serial.print("\t");  
       //Serial.print(euler[1] * 180/M_PI);  
       //Serial.print("\t");  
       //Serial.println(euler[2] * 180/M_PI);  
     //#endif  
     #ifdef OUTPUT_READABLE_YAWPITCHROLL  
       // display Euler angles in degrees  
       mpu.dmpGetQuaternion(&q, fifoBuffer);  
       mpu.dmpGetGravity(&gravity, &q);  
       mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);  
       //Serial.print("ypr\t");  
        yaw=ypr[0] * 180/M_PI;  
       //Serial.print(ypr[0] * 180/M_PI);  
       //Serial.print("\t");  
        pitch=ypr[1] * 180/M_PI;  
       //Serial.print(ypr[1] * 180/M_PI);  
       //Serial.print("\t");  
        roll=ypr[2] * 180/M_PI;  
       //Serial.println(ypr[2] * 180/M_PI);  
       //delay(1000);  
     #endif  
     /*#ifdef OUTPUT_READABLE_REALACCEL  
       // display real acceleration, adjusted to remove gravity  
       mpu.dmpGetQuaternion(&q, fifoBuffer);  
       mpu.dmpGetAccel(&aa, fifoBuffer);  
       mpu.dmpGetGravity(&gravity, &q);  
       mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);  
       Serial.print("areal\t");  
       Serial.print(aaReal.x);  
       Serial.print("\t");  
       Serial.print(aaReal.y);  
       Serial.print("\t");  
       Serial.println(aaReal.z);  
     #endif*/  
     #ifdef OUTPUT_READABLE_WORLDACCEL//project uses world acceleration  
       // display initial world-frame acceleration, adjusted to remove gravity  
       // and rotated based on known orientation from quaternion  
       mpu.dmpGetQuaternion(&q, fifoBuffer);  
       mpu.dmpGetAccel(&aa, fifoBuffer);  
       mpu.dmpGetGravity(&gravity, &q);  
       mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);  
       mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);  
       Serial.print("aworld\t");  
        accX=aaWorld.x;  
       Serial.print(aaWorld.x);  
       Serial.print("\t");  
        accY=aaWorld.y;  
       Serial.print(aaWorld.y);  
       Serial.print("\t");  
        accZ=aaWorld.z;  
       Serial.println(aaWorld.z);  
       //delay(400);  
     #endif  
     #ifdef OUTPUT_TEAPOT  
        display quaternion values in InvenSense Teapot demo format:  
       teapotPacket[2] = fifoBuffer[0];  
       teapotPacket[3] = fifoBuffer[1];  
       teapotPacket[4] = fifoBuffer[4];  
       teapotPacket[5] = fifoBuffer[5];  
       teapotPacket[6] = fifoBuffer[8];  
       teapotPacket[7] = fifoBuffer[9];  
       teapotPacket[8] = fifoBuffer[12];  
       teapotPacket[9] = fifoBuffer[13];  
       // Serial.write(teapotPacket, 14);  
       teapotPacket[11]++; // packetCount, loops at 0xFF on purpose  
     #endif  
     // blink LED to indicate activity  
     blinkState = !blinkState;  
     //digitalWrite(LED_PIN, blinkState);  
   }  
  //*************************************************************   
   if(Serial.available())  
   {     data=Serial.read();  
         if(data=='a')  
         {   
 motor1.setSpeed(a);   // set the speed to 200/255  
 motor2.setSpeed(a);   // set the speed to 200/255  
 motor3.setSpeed(a);  
 motor4.setSpeed(a);  
          motor1.run(FORWARD);  
          motor4.run(FORWARD);   // turn it on going forward  
         }  
         if(data=='b')  
         {  
 motor1.setSpeed(a);   // set the speed to 200/255  
 motor2.setSpeed(a);   // set the speed to 200/255  
 motor3.setSpeed(a);  
 motor4.setSpeed(a);  
          motor1.run(BACKWARD);  
          motor4.run(BACKWARD);   // the other way  
         }  
         if(data=='c')  
         {  
          motor1.run(RELEASE);  
          motor2.run(RELEASE);   // stopped  
          motor3.run(RELEASE);  
          motor4.run(RELEASE);  
         }  
         if(data=='d')  
         {   
 motor1.setSpeed(a);   // set the speed to 200/255  
 motor2.setSpeed(a);   // set the speed to 200/255  
 motor3.setSpeed(a);  
 motor4.setSpeed(a);  
          motor2.run(FORWARD);  
          motor3.run(FORWARD);   // turn left  
         }  
         if(data=='e')  
         {  
          motor1.setSpeed(a);   // set the speed to 200/255  
 motor2.setSpeed(a);   // set the speed to 200/255  
 motor3.setSpeed(a);  
 motor4.setSpeed(a);  
          motor2.run(BACKWARD);  
          motor3.run(BACKWARD);   // turn right  
         }  
         if(data=='f')  
         {  
          motor1.setSpeed(a);   // set the speed to 200/255  
 motor2.setSpeed(a);   // set the speed to 200/255  
 motor3.setSpeed(a);  
 motor4.setSpeed(a);  
          motor1.run(BACKWARD);  
          motor2.run(FORWARD);   // stopped  
          motor3.run(BACKWARD);  
          motor4.run(FORWARD);  
         }  
         if(data=='g')  
         {  
          motor1.setSpeed(a);   // set the speed to 200/255  
 motor2.setSpeed(a);   // set the speed to 200/255  
 motor3.setSpeed(a);  
 motor4.setSpeed(a);  
          motor1.run(FORWARD);  
          motor2.run(BACKWARD);   // stopped  
          motor3.run(FORWARD);  
          motor4.run(BACKWARD);  
         }  
 }//if serial available end  
 if((data!='a')&&(data!='b')&&(data!='d')&&(data!='e')&&(data!='f')&&(data!='g'))  
 {    
    //if((accZ<4600)&&((roll<10)||(roll>-10)))  
    if(((accX<150)||(accX>-150)||(accZ>4300))&&((roll<10)||(roll>-10)))  
    {  
 //************************PITCH FEEDBACK**********************************      
     if(pitch<-15)  
     {  
       motor1.setSpeed(a);   // set the speed to 200/255  
       motor2.setSpeed(a);   // set the speed to 200/255  
       motor3.setSpeed(a);  
       motor4.setSpeed(a);  
       motor2.run(FORWARD);//forward  
       motor3.run(FORWARD);  
     }//end if to check if the sphere is still moving left  
     else if(pitch>15)  
     {  
       motor1.setSpeed(a);   // set the speed to 200/255  
       motor2.setSpeed(a);   // set the speed to 200/255  
       motor3.setSpeed(a);  
       motor4.setSpeed(a);  
       motor2.run(BACKWARD);  
       motor3.run(BACKWARD);   // backward  
     }//end to check pitch right  
     else if((pitch>=-10)||(pitch<=10))  
     {  
          motor1.run(RELEASE);  
          motor2.run(RELEASE);   // stopped  
          motor3.run(RELEASE);  
          motor4.run(RELEASE);  
     }//end spin right to balance  
    }//end if acceleration in Y  
 //***********************END PITCH FEEDBACK************************************  
 //************************ROLL FEEDBACK**********************************      
    if((accZ<4600)&&((pitch<10)||(pitch>-10)))  
    {  
     if((roll<-15))  
     {  
      motor1.setSpeed(a);   // set the speed to 200/255  
      motor2.setSpeed(a);   // set the speed to 200/255  
      motor3.setSpeed(a);  
      motor4.setSpeed(a);  
      motor1.run(FORWARD);//forward  
      motor4.run(FORWARD);  
      }//end if to check if the sphere is still moving left  
      else if(roll>15)  
      {  
      motor1.setSpeed(a);   // set the speed to 200/255  
      motor2.setSpeed(a);   // set the speed to 200/255  
      motor3.setSpeed(a);  
      motor4.setSpeed(a);      
      motor1.run(BACKWARD);  
      motor4.run(BACKWARD);   // backward  
      }//end to check pitch right  
      else if((roll>=-10)||(roll<=10))  
      {  
               motor1.run(RELEASE);  
          motor2.run(RELEASE);   // stopped  
          motor3.run(RELEASE);  
          motor4.run(RELEASE);  
       }//end spin right to balance  
 //***********************END ROLL FEEDBACK************************************  
      }//end if to check if acceleration is decressing  
  }//end if to check if there is data incomming    
 }  

1 comment:

  1. Very informative and impressive post you have written, this is quite interesting and i have went through it completely, an upgraded information is shared, keep sharing such valuable information. Hoarding Cleanup Media

    ReplyDelete