Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

  • Animation from table of angles and time

    Hi everyone! I have a data table with angles on the xyz plane and time recorded from a MPU6050 gyroscope. I was wondering if there's any way of creating an animation from this table of values to visualize the orientation of an aircraft?

    Thank you!

  • Mpu6050 +motion capture on processing ide

    I have got a code for processing ide where the code accepts data from mqtt cloud and inputs roll,yaw,pitch angles from it and designates on a mpu-tea pot(a famous processing example in arduino). Now I just want to represent the same on human head. The circuit is: A gyro/accelometer sensor +wifi module --->giving data to cloud----->getting data from mqtt cloud on processing software. Instead of mputea pot I need to visulise the same onto human head. How can I start? I am also new to this software. Any inputs? here is the processing code: `

         //-------------------------**********code will remain same till here irrespective of whether making a teapot or a human head*************************************************----------------------------------------------//
                import processing.serial.*;
                import processing.opengl.*;
                import toxi.geom.*;
                import toxi.processing.*;
                import org.eclipse.paho.client.mqttv3.*;
                import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    
    
            ToxiclibsSupport gfx;
    
            Serial port;                         // The serial port
            char[] teapotPacket = new char[14];  // InvenSense Teapot packet
            int serialCount = 0;                 // current packet byte position
            int synced = 0;
            int interval = 0;
    
            float[] q = new float[4];
            Quaternion quat = new Quaternion(1, 0, 0, 0);
    
            float[] gravity = new float[3];
            float[] euler = new float[3];
            float[] ypr = new float[3];
            String topic        = "check";
            String content      = "Hello CloudMQTT";
            int qos             = 1;
            String broker       = "tcp://m13.cloudmqtt.com:17673";
            String clientId     = "ClientId";
            MemoryPersistence persistence = new MemoryPersistence();
            MqttMessage message = new MqttMessage(content.getBytes());
    
            MqttClient  mqttClient;
    
            void setup() {
              try {
                println("Entered");
                mqttClient = new MqttClient(broker, clientId, persistence);
                mqttClient.setCallback(new MqttCallback() {
                  public void messageArrived(String topic, MqttMessage msg)
                    throws Exception {
                    interval = millis();
                    println("Received:" + new String(msg.getPayload()));
                    String[] data = new String(msg.getPayload()).split(";");
                    float[] qvalue = new float[data.length];
                    for (int i = 0; i < data.length; ++i) {
                      qvalue[i] = Float.parseFloat(data[i]);
                    }
                    quat.set(qvalue[0], qvalue[1], qvalue[2], qvalue[3]);
                  }
    
                  public void deliveryComplete(IMqttDeliveryToken arg0) {
                    println("Delivery complete");
                  }
    
                  public void connectionLost(Throwable arg0) {
                    // TODO Auto-generated method stub
                  }
                }
                );
                MqttConnectOptions connOpts = new MqttConnectOptions();
                connOpts.setCleanSession(true);
                connOpts.setUserName("crfqbqvi");
                connOpts.setPassword(new char[]{'_', '9', 'n', 'o', 'Z', 'Y', 'P', 'y', 'S', '7', 'D', '9'});
                mqttClient.connect(connOpts);
                message.setQos(qos);     
                mqttClient.subscribe(topic, qos);
                //mqttClient.publish(topic, message);
                // client.unsubscribe("/example");
              }
    
              catch(MqttException me) {
                System.out.println("reason "+me.getReasonCode());
                System.out.println("msg "+me.getMessage());
                System.out.println("loc "+me.getLocalizedMessage());
                System.out.println("cause "+me.getCause());
                System.out.println("excep "+me);
                me.printStackTrace();
              }
              // 300px square viewport using OpenGL rendering
              size(300, 300, OPENGL);
              gfx = new ToxiclibsSupport(this);
    
              // setup lights and antialiasing
              lights();
              smooth();
            }
            //-------------------------**********code will remain same till here irrespective of whether making a teapot or a human head*************************************************----------------------------------------------//
            void draw() 
            {
              //println("Entered");
              if (millis() - interval > 1000) {
                // resend single character to trigger DMP init/start
                // in case the MPU is halted/reset while applet is running
                //port.write('r');
                interval = millis();
              }
    
              // black background
              background(0);
    
              // translate everything to the middle of the viewport
              pushMatrix();
              translate(width / 2, height / 2);
    
              // 3-step rotation from yaw/pitch/roll angles (gimbal lock!)
              // ...and other weirdness I haven't figured out yet
              //rotateY(-ypr[0]);
              //rotateZ(-ypr[1]);
              //rotateX(-ypr[2]);
    
              // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!)
              // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of
              // different coordinate system orientation assumptions between Processing
              // and InvenSense DMP)
              float[] axis = quat.toAxisAngle();
              rotate(axis[0], -axis[1], axis[3], axis[2]);
    
              // draw main body in red
              fill(255, 0, 0, 200);
              box(10, 10, 200);
    
              // draw front-facing tip in blue
              fill(0, 0, 255, 200);
              pushMatrix();
              translate(0, 0, -120);
              rotateX(PI/2);
              drawCylinder(0, 20, 20, 8);
              popMatrix();
    
              // draw wings and tail fin in green
              fill(0, 255, 0, 200);
              beginShape(TRIANGLES);
              vertex(-100, 2, 30); 
              vertex(0, 2, -80); 
              vertex(100, 2, 30);  // wing top layer
              vertex(-100, -2, 30); 
              vertex(0, -2, -80); 
              vertex(100, -2, 30);  // wing bottom layer
              vertex(-2, 0, 98); 
              vertex(-2, -30, 98); 
              vertex(-2, 0, 70);  // tail left layer
              vertex( 2, 0, 98); 
              vertex( 2, -30, 98); 
              vertex( 2, 0, 70);  // tail right layer
              endShape();
              beginShape(QUADS);
              vertex(-100, 2, 30); 
              vertex(-100, -2, 30); 
              vertex(  0, -2, -80); 
              vertex(  0, 2, -80);
              vertex( 100, 2, 30); 
              vertex( 100, -2, 30); 
              vertex(  0, -2, -80); 
              vertex(  0, 2, -80);
              vertex(-100, 2, 30); 
              vertex(-100, -2, 30); 
              vertex(100, -2, 30); 
              vertex(100, 2, 30);
              vertex(-2, 0, 98); 
              vertex(2, 0, 98); 
              vertex(2, -30, 98); 
              vertex(-2, -30, 98);
              vertex(-2, 0, 98); 
              vertex(2, 0, 98); 
              vertex(2, 0, 70); 
              vertex(-2, 0, 70);
              vertex(-2, -30, 98); 
              vertex(2, -30, 98); 
              vertex(2, 0, 70); 
              vertex(-2, 0, 70);
              endShape();
    
              popMatrix();
            }
    
            void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
              float angle = 0;
              float angleIncrement = TWO_PI / sides;
              beginShape(QUAD_STRIP);
              for (int i = 0; i < sides + 1; ++i) {
                vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
                vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
                angle += angleIncrement;
              }
              endShape();
    
              // If it is not a cone, draw the circular top cap
              if (topRadius != 0) {
                angle = 0;
                beginShape(TRIANGLE_FAN);
    
                // Center point
                vertex(0, 0, 0);
                for (int i = 0; i < sides + 1; i++) {
                  vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
                  angle += angleIncrement;
                }
                endShape();
              }
    
              // If it is not a cone, draw the circular bottom cap
              if (bottomRadius != 0) {
                angle = 0;
                beginShape(TRIANGLE_FAN);
    
                // Center point
                vertex(0, tall, 0);
                for (int i = 0; i < sides + 1; i++) {
                  vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
                  angle += angleIncrement;
                }
                endShape();
              }
            }
    

    ` So I have put comments for a paragraph of code that is: it will remain same irrespective of teapot or head. After that code changes (which is presently for teapot) for human head. Can someone give me startup ideas to go ahead with this project..

  • MPU6050 data in RaspberryPi3

    Hi

    Can someone provide me leads on how to use get data from MPU6050 (Using I2C) in Raspberry PI3 please?

    Thanks S

  • network function

    ..think i'm may be not in the right post....??

    i dlike to know if there is an example using raspberry pi connected with an mpu6050, both on network, and processing reading tcp values from...

    may be i must post in raspberry users..

    thanks for yours answers..

    again bruno..

  • running teapot.pde on windows 10

    links please.

    i guess you mean this:

    https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050/examples/MPU6050_DMP6/Processing/MPUTeapot

    which is for arduino and has the following imports

    import processing.serial.*;
    import processing.opengl.*;
    import toxi.geom.*;
    import toxi.processing.*;
    

    so you'll need the various libraries installed. i think the first couple are standard but toxiclibs will need to be downloaded.

  • How do I get Jeff Rowberg's MPU6050 software to run.

    I am trying to get Jeff Rowberg's software for the Invensense MPU6050 to run. (Arduino's MPU6050.ino and Processing's MPUTeapot.ino) But MPU6050.ino and MPUTpot.ino do not talk to each other. MPU6050.ino hangs (malfunctions?) while waiting for an interrupt from MPUTeapot.ino that never happens. I have to break out of his wait loop. I have the Arduino Mega 2560, which should have the correct interrupt pin. (as follows)

      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.
    

    This should be taken care of as follows:

     #define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
    

    But, I have to add a break as follows:

       // 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
                // .
                // .
                // .
                Break;
    

    Do I actually have to add a wire?

    Jeff Rowberg's MPU6050.ino code follows"

    // I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
    // 6/21/2012 by Jeff Rowberg <jeff@rowberg.net>
    // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
    //
    // Changelog:
    //      2013-05-08 - added seamless Fastwire support
    //                 - added note about gyro calibration
    //      2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error
    //      2012-06-20 - improved FIFO overflow handling and simplified read process
    //      2012-06-19 - completely rearranged DMP initialization code and simplification
    //      2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly
    //      2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING
    //      2012-06-05 - add gravity-compensated initial reference frame acceleration output
    //                 - add 3D math helper file to DMP6 example sketch
    //                 - add Euler output and Yaw/Pitch/Roll output formats
    //      2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee)
    //      2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250
    //      2012-05-30 - basic DMP initialization working
    
    /* ============================================
    I2Cdev device library code is placed under the MIT license
    Copyright (c) 2012 Jeff Rowberg
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
    ===============================================
    */
    
    // 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
    
    // 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
     * ========================================================================= */
    
    
    
    // uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
    // quaternion components in a [w, x, y, z] format (not best for parsing
    // on a remote host such as Processing or something though)
    //#define OUTPUT_READABLE_QUATERNION
    
    // uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
    // (in degrees) calculated from the quaternions coming from the FIFO.
    // Note that Euler angles suffer from gimbal lock (for more info, see
    // http://en.wikipedia.org/wiki/Gimbal_lock)
    //#define OUTPUT_READABLE_EULER
    
    // 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
    
    // uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
    // components with gravity removed. This acceleration reference frame is
    // not compensated for orientation, so +X is always +X according to the
    // sensor, just without the effects of gravity. If you want acceleration
    // compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
    //#define OUTPUT_READABLE_REALACCEL
    
    // uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
    // components with gravity removed and adjusted for the world frame of
    // reference (yaw is relative to initial orientation, since no magnetometer
    // is present in this case). Could be quite handy in some cases.
    //#define OUTPUT_READABLE_WORLDACCEL
    
    // uncomment "OUTPUT_TEAPOT" if you want output that matches the
    // format used for the InvenSense teapot demo
    //#define OUTPUT_TEAPOT
    
    
    
    #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' };
    
    
    
    // ================================================================
    // ===               INTERRUPT DETECTION ROUTINE                ===
    // ================================================================
    
    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady() {
        mpuInterrupt = true;
    }
    
    
    
    // ================================================================
    // ===                      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
    
        // 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(115200);
        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();
        pinMode(INTERRUPT_PIN, INPUT);
    
        // 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(digitalPinToInterrupt(INTERRUPT_PIN), 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);
    }
    
    
    
    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================
    
    void loop() {
        // 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_QUATERNION
                // display quaternion values in easy matrix form: w x y z
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                Serial.print("quat\t");
                Serial.print(q.w);
                Serial.print("\t");
                Serial.print(q.x);
                Serial.print("\t");
                Serial.print(q.y);
                Serial.print("\t");
                Serial.println(q.z);
            #endif
    
            #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");
                Serial.print(ypr[0] * 180/M_PI);
                Serial.print("\t");
                Serial.print(ypr[1] * 180/M_PI);
                Serial.print("\t");
                Serial.println(ypr[2] * 180/M_PI);
            #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
                // 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");
                Serial.print(aaWorld.x);
                Serial.print("\t");
                Serial.print(aaWorld.y);
                Serial.print("\t");
                Serial.println(aaWorld.z);
            #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);
        }
    }
    
  • Is Arduino 1.6.13 stable? or Did my MPU6050 just break?

    I have the Makeblock Ultimate 2.0 kit that uses the Arduino Mega2560 board and also have Arduino 1.6.13 The example program for the gyroscopic module is built for the MeOrion(#include "MeOrion.h") so I modified the code to run on my Mega2560("#include MeMegaPi.h"), but noticed that the MeGyro example only works for a few seconds. I question if my MPU6050 broke on the same day that I upgraded the software. Is there a workaround that fixes the problem?

    The Original example code for the MeOrion follows:

    /**
     * \par Copyright (C), 2012-2016, MakeBlock
     * @file    GyroRotation.ino
     * @author  MakeBlock
     * @version V1.0.0
     * @date    2015/09/09
     * @brief   Description: this file is sample code for MeGyro device.
     *
     * Function List:
     * 1. void MeGyro::begin(void)
     * 2. void MeGyro::update(void) 
     * 3. double MeGyro::angleX(void)
     * 4. double MeGyro::angleY(void)
     * 5. double MeGyro::angleZ(void)
     *
     * \par History:
     * <pre>
     * <Author>     <Time>        <Version>      <Descr>
     * Mark Yan     2015/09/09    1.0.0          rebuild the old lib
     * </pre>
     *
     */
    #include "MeOrion.h"
    #include <Wire.h>
    
    MeGyro gyro;
    void setup()
    {
      Serial.begin(115200);
      gyro.begin();
    }
    
    void loop()
    {
      gyro.update();
      Serial.read();
      Serial.print("X:");
      Serial.print(gyro.getAngleX() );
      Serial.print(" Y:");
      Serial.print(gyro.getAngleY() );
      Serial.print(" Z:");
      Serial.println(gyro.getAngleZ() );
      delay(10);
    }
    

    My custimized code for the Mega2560 board ("#include MeMegaPi.h") follows:

    /**
     * \par Copyright (C), 2012-2016, MakeBlock
     * @file    GyroRotation.ino
     * @author  MakeBlock
     * @version V1.0.0
     * @date    2015/09/09
     * @brief   Description: this file is sample code for MeGyro device.
     *
     * Function List:
     * 1. void MeGyro::begin(void)
     * 2. void MeGyro::update(void) 
     * 3. double MeGyro::angleX(void)
     * 4. double MeGyro::angleY(void)
     * 5. double MeGyro::angleZ(void)
     *
     * \par History:
     * <pre>
     * <Author>     <Time>        <Version>      <Descr>
     * Mark Yan     2015/09/09    1.0.0          rebuild the old lib
     * </pre>
     *
     */
    #include "MeMegaPi.h"
    #include <Wire.h>
    
    MeGyro gyro;
    void setup()
    {
      Serial.begin(115200);
      gyro.begin();
    }
    
    void loop()
    {
      gyro.update();
      Serial.read();
      Serial.print("X:");
      Serial.print(gyro.getAngleX() );
      Serial.print(" Y:");
      Serial.print(gyro.getAngleY() );
      Serial.print(" Z:");
      Serial.println(gyro.getAngleZ() );
      delay(10);
    }
    
  • Where is toxi.geom? I can not find it anyware.

    Jef Robergs MPUTeapot runs in Processing. I can not get it run because the library toxi.geom is not found. I have installed the toxiclibs, but toxi.geom is not in there. The program worked yesterday, but they are changing versions on me. Now I can not get the libraries right.

    The code for Jef Robergs MPUTeapot follows:

    // I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output
    // 6/20/2012 by Jeff Rowberg <jeff@rowberg.net>
    // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
    //
    // Changelog:
    //     2012-06-20 - initial release
    
    /** ============================================
    I2Cdev device library code is placed under the MIT license
    Copyright (c) 2012 Jeff Rowberg
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
    ===============================================
    */
    
    import processing.serial.*;
    import processing.opengl.*;
    import toxi.geom.*;
    import toxi.processing.*;
    
    // NOTE: requires ToxicLibs to be installed in order to run properly.
    // 1. Download from http://toxiclibs.org/downloads
    // 2. Extract into [userdir]/Processing/libraries
    //    (location may be different on Mac/Linux)
    // 3. Run and bask in awesomeness
    
    ToxiclibsSupport gfx;
    
    Serial port;                         // The serial port
    char[] teapotPacket = new char[14];  // InvenSense Teapot packet
    int serialCount = 0;                 // current packet byte position
    int synced = 0;
    int interval = 0;
    
    float[] q = new float[4];
    Quaternion quat = new Quaternion(1, 0, 0, 0);
    
    float[] gravity = new float[3];
    float[] euler = new float[3];
    float[] ypr = new float[3];
    
    void setup() {
        // 300px square viewport using OpenGL rendering
        size(300, 300, OPENGL);
        gfx = new ToxiclibsSupport(this);
    
        // setup lights and antialiasing
        lights();
        smooth();
    
        // display serial port list for debugging/clarity
        println(Serial.list());
    
        // get the first available port (use EITHER this OR the specific port code below)
        //String portName = Serial.list()[0];
    
        // get a specific serial port (use EITHER this OR the first-available code above)
        String portName = "COM5";
    
        // open the serial port
        port = new Serial(this, portName, 115200);
    
        // send single character to trigger DMP init/start
        // (expected by MPU6050_DMP6 example Arduino sketch)
        port.write('r');
    }
    
    void draw() {
        if (millis() - interval > 1000) {
            // resend single character to trigger DMP init/start
            // in case the MPU is halted/reset while applet is running
            port.write('r');
            interval = millis();
        }
    
        // black background
        background(0);
    
        // translate everything to the middle of the viewport
        pushMatrix();
        translate(width / 2, height / 2);
    
        // 3-step rotation from yaw/pitch/roll angles (gimbal lock!)
        // ...and other weirdness I haven't figured out yet
        //rotateY(-ypr[0]);
        //rotateZ(-ypr[1]);
        //rotateX(-ypr[2]);
    
        // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!)
        // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of
        // different coordinate system orientation assumptions between Processing
        // and InvenSense DMP)
        float[] axis = quat.toAxisAngle();
        rotate(axis[0], -axis[1], axis[3], axis[2]);
    
        // draw main body in red
        fill(255, 0, 0, 200);
        box(10, 10, 200);
    
        // draw front-facing tip in blue
        fill(0, 0, 255, 200);
        pushMatrix();
        translate(0, 0, -120);
        rotateX(PI/2);
        drawCylinder(0, 20, 20, 8);
        popMatrix();
    
        // draw wings and tail fin in green
        fill(0, 255, 0, 200);
        beginShape(TRIANGLES);
        vertex(-100,  2, 30); vertex(0,  2, -80); vertex(100,  2, 30);  // wing top layer
        vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30);  // wing bottom layer
        vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70);  // tail left layer
        vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70);  // tail right layer
        endShape();
        beginShape(QUADS);
        vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
        vertex( 100, 2, 30); vertex( 100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
        vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2,  30); vertex(100, 2,  30);
        vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
        vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
        vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
        endShape();
    
        popMatrix();
    }
    
    void serialEvent(Serial port) {
        interval = millis();
        while (port.available() > 0) {
            int ch = port.read();
    
            if (synced == 0 && ch != '$') return;   // initial synchronization - also used to resync/realign if needed
            synced = 1;
            print ((char)ch);
    
            if ((serialCount == 1 && ch != 2)
                || (serialCount == 12 && ch != '\r')
                || (serialCount == 13 && ch != '\n'))  {
                serialCount = 0;
                synced = 0;
                return;
            }
    
            if (serialCount > 0 || ch == '$') {
                teapotPacket[serialCount++] = (char)ch;
                if (serialCount == 14) {
                    serialCount = 0; // restart packet byte position
    
                    // get quaternion from data packet
                    q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f;
                    q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f;
                    q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f;
                    q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f;
                    for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i];
    
                    // set our toxilibs quaternion to new data
                    quat.set(q[0], q[1], q[2], q[3]);
    
                    /**
                    // below calculations unnecessary for orientation only using toxilibs
    
                    // calculate gravity vector
                    gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
                    gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
                    gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
    
                    // calculate Euler angles
                    euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                    euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
                    euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);
    
                    // calculate yaw/pitch/roll angles
                    ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                    ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
                    ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
    
                    // output various components for debugging
                    //println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f);
                    //println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI);
                    //println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI);
                    */
                }
            }
        }
    }
    
    void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
        float angle = 0;
        float angleIncrement = TWO_PI / sides;
        beginShape(QUAD_STRIP);
        for (int i = 0; i < sides + 1; ++i) {
            vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
            vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
            angle += angleIncrement;
        }
        endShape();
    
        // If it is not a cone, draw the circular top cap
        if (topRadius != 0) {
            angle = 0;
            beginShape(TRIANGLE_FAN);
    
            // Center point
            vertex(0, 0, 0);
            for (int i = 0; i < sides + 1; i++) {
                vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
                angle += angleIncrement;
            }
            endShape();
        }
    
        // If it is not a cone, draw the circular bottom cap
        if (bottomRadius != 0) {
            angle = 0;
            beginShape(TRIANGLE_FAN);
    
            // Center point
            vertex(0, tall, 0);
            for (int i = 0; i < sides + 1; i++) {
                vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
                angle += angleIncrement;
            }
            endShape();
        }
    }
    
  • Where is toxi.geom? I can not find it anyware.

    I am trying to install Processing for the MPU6050 and MPUTeapot. MPUTeapot uses the library toxi.geom. But I can not even find the library.

  • "The field PConstants.OPENGL is deprecated" -- What does it mean?

    I am trying to get Processing to work with MPUTeapot. I get this error message in line 60. Line 60 is " size(300, 300, OPENGL);"
    I do not to OPENGL so I have no idea what this is. Can someone help? The Processing sketch code follows:

    // I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output
    // 6/20/2012 by Jeff Rowberg <jeff@rowberg.net>
    // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
    //
    // Changelog:
    //     2012-06-20 - initial release
    
    /* ============================================
    I2Cdev device library code is placed under the MIT license
    Copyright (c) 2012 Jeff Rowberg
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
    ===============================================
    */
    
    import processing.serial.*;
    import processing.opengl.*;
    import toxi.geom.*;
    import toxi.processing.*;
    
    // NOTE: requires ToxicLibs to be installed in order to run properly.
    // 1. Download from http://toxiclibs.org/downloads
    // 2. Extract into [userdir]/Processing/libraries
    //    (location may be different on Mac/Linux)
    // 3. Run and bask in awesomeness
    
    ToxiclibsSupport gfx;
    
    Serial port;                         // The serial port
    char[] teapotPacket = new char[14];  // InvenSense Teapot packet
    int serialCount = 0;                 // current packet byte position
    int synced = 0;
    int interval = 0;
    
    float[] q = new float[4];
    Quaternion quat = new Quaternion(1, 0, 0, 0);
    
    float[] gravity = new float[3];
    float[] euler = new float[3];
    float[] ypr = new float[3];
    
    void setup() {
        // 300px square viewport using OpenGL rendering
        size(300, 300, OPENGL);
        gfx = new ToxiclibsSupport(this);
    
        // setup lights and antialiasing
        lights();
        smooth();
    
        // display serial port list for debugging/clarity
        println(Serial.list());
    
        // get the first available port (use EITHER this OR the specific port code below)
          //                    String portName = Serial.list()[0];
    
        // get a specific serial port (use EITHER this OR the first-available code above)
        String portName = "COM5";
    
        // open the serial port
        port = new Serial(this, portName, 115200);
    
        // send single character to trigger DMP init/start
        // (expected by MPU6050_DMP6 example Arduino sketch)
        port.write('r');
    }
    
    void draw() {
        if (millis() - interval > 1000) {
            // resend single character to trigger DMP init/start
            // in case the MPU is halted/reset while applet is running
            port.write('r');
            interval = millis();
        }
    
        // black background
        background(0);
    
        // translate everything to the middle of the viewport
        pushMatrix();
        translate(width / 2, height / 2);
    
        // 3-step rotation from yaw/pitch/roll angles (gimbal lock!)
        // ...and other weirdness I haven't figured out yet
        //rotateY(-ypr[0]);
        //rotateZ(-ypr[1]);
        //rotateX(-ypr[2]);
    
        // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!)
        // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of
        // different coordinate system orientation assumptions between Processing
        // and InvenSense DMP)
        float[] axis = quat.toAxisAngle();
        rotate(axis[0], -axis[1], axis[3], axis[2]);
    
        // draw main body in red
        fill(255, 0, 0, 200);
        box(10, 10, 200);
    
        // draw front-facing tip in blue
        fill(0, 0, 255, 200);
        pushMatrix();
        translate(0, 0, -120);
        rotateX(PI/2);
        drawCylinder(0, 20, 20, 8);
        popMatrix();
    
        // draw wings and tail fin in green
        fill(0, 255, 0, 200);
        beginShape(TRIANGLES);
        vertex(-100,  2, 30); vertex(0,  2, -80); vertex(100,  2, 30);  // wing top layer
        vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30);  // wing bottom layer
        vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70);  // tail left layer
        vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70);  // tail right layer
        endShape();
        beginShape(QUADS);
        vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
        vertex( 100, 2, 30); vertex( 100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
        vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2,  30); vertex(100, 2,  30);
        vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
        vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
        vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
        endShape();
    
        popMatrix();
    }
    
    void serialEvent(Serial port) {
        interval = millis();
        while (port.available() > 0) {
            int ch = port.read();
    
            if (synced == 0 && ch != '$') return;   // initial synchronization - also used to resync/realign if needed
            synced = 1;
            print ((char)ch);
    
            if ((serialCount == 1 && ch != 2)
                || (serialCount == 12 && ch != '\r')
                || (serialCount == 13 && ch != '\n'))  {
                serialCount = 0;
                synced = 0;
                return;
            }
    
            if (serialCount > 0 || ch == '$') {
                teapotPacket[serialCount++] = (char)ch;
                if (serialCount == 14) {
                    serialCount = 0; // restart packet byte position
    
                    // get quaternion from data packet
                    q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f;
                    q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f;
                    q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f;
                    q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f;
                    for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i];
    
                    // set our toxilibs quaternion to new data
                    quat.set(q[0], q[1], q[2], q[3]);
    
                    /*
                    // below calculations unnecessary for orientation only using toxilibs
    
                    // calculate gravity vector
                    gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
                    gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
                    gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
    
                    // calculate Euler angles
                    euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                    euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
                    euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);
    
                    // calculate yaw/pitch/roll angles
                    ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                    ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
                    ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
    
                    // output various components for debugging
                    //println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f);
                    //println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI);
                    //println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI);
                    */
                }
            }
        }
    }
    
    void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
        float angle = 0;
        float angleIncrement = TWO_PI / sides;
        beginShape(QUAD_STRIP);
        for (int i = 0; i < sides + 1; ++i) {
            vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
            vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
            angle += angleIncrement;
        }
        endShape();
    
        // If it is not a cone, draw the circular top cap
        if (topRadius != 0) {
            angle = 0;
            beginShape(TRIANGLE_FAN);
    
            // Center point
            vertex(0, 0, 0);
            for (int i = 0; i < sides + 1; i++) {
                vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
                angle += angleIncrement;
            }
            endShape();
        }
    
        // If it is not a cone, draw the circular bottom cap
        if (bottomRadius != 0) {
            angle = 0;
            beginShape(TRIANGLE_FAN);
    
            // Center point
            vertex(0, tall, 0);
            for (int i = 0; i < sides + 1; i++) {
                vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
                angle += angleIncrement;
            }
            endShape();
        }
    }
    
  • How do I fix port busy?

    Thank You for your response.

    After reading some posts on "arduino port busy", I have come up with a theory. The "Arduino IDE" only loads the sketch onto the board, but does not maintain an open serial connection. So I can not open the Arduino Serial Monitor. If I do open the monitor, it may be necessary to restart the "Arduino IDE". When the Processing sketch executes, it will talk to the Arduino board.

    I think that is what you just said. I just have different words.

    Thank You!

    I have gotten past the "port busy" problem.

    Now I am one step farther.

    The new error is in line 60 of the Processing sketch. The error reads "The field PConstants.OPENGL is deprecated" -- MPUTeapot Line 60 is "size(300, 300, OPENGL);" I do not do OPENGL. So I have no idea what this is.

    The complete Processing sketch code follows:

    // I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output
    // 6/20/2012 by Jeff Rowberg <jeff@rowberg.net>
    // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
    //
    // Changelog:
    //     2012-06-20 - initial release
    
    /* ============================================
    I2Cdev device library code is placed under the MIT license
    Copyright (c) 2012 Jeff Rowberg
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
    ===============================================
    */
    
    import processing.serial.*;
    import processing.opengl.*;
    import toxi.geom.*;
    import toxi.processing.*;
    
    // NOTE: requires ToxicLibs to be installed in order to run properly.
    // 1. Download from http://toxiclibs.org/downloads
    // 2. Extract into [userdir]/Processing/libraries
    //    (location may be different on Mac/Linux)
    // 3. Run and bask in awesomeness
    
    ToxiclibsSupport gfx;
    
    Serial port;                         // The serial port
    char[] teapotPacket = new char[14];  // InvenSense Teapot packet
    int serialCount = 0;                 // current packet byte position
    int synced = 0;
    int interval = 0;
    
    float[] q = new float[4];
    Quaternion quat = new Quaternion(1, 0, 0, 0);
    
    float[] gravity = new float[3];
    float[] euler = new float[3];
    float[] ypr = new float[3];
    
    void setup() {
        // 300px square viewport using OpenGL rendering
        size(300, 300, OPENGL);
        gfx = new ToxiclibsSupport(this);
    
        // setup lights and antialiasing
        lights();
        smooth();
    
        // display serial port list for debugging/clarity
        println(Serial.list());
    
        // get the first available port (use EITHER this OR the specific port code below)
          //                    String portName = Serial.list()[0];
    
        // get a specific serial port (use EITHER this OR the first-available code above)
        String portName = "COM5";
    
        // open the serial port
        port = new Serial(this, portName, 115200);
    
        // send single character to trigger DMP init/start
        // (expected by MPU6050_DMP6 example Arduino sketch)
        port.write('r');
    }
    
    void draw() {
        if (millis() - interval > 1000) {
            // resend single character to trigger DMP init/start
            // in case the MPU is halted/reset while applet is running
            port.write('r');
            interval = millis();
        }
    
        // black background
        background(0);
    
        // translate everything to the middle of the viewport
        pushMatrix();
        translate(width / 2, height / 2);
    
        // 3-step rotation from yaw/pitch/roll angles (gimbal lock!)
        // ...and other weirdness I haven't figured out yet
        //rotateY(-ypr[0]);
        //rotateZ(-ypr[1]);
        //rotateX(-ypr[2]);
    
        // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!)
        // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of
        // different coordinate system orientation assumptions between Processing
        // and InvenSense DMP)
        float[] axis = quat.toAxisAngle();
        rotate(axis[0], -axis[1], axis[3], axis[2]);
    
        // draw main body in red
        fill(255, 0, 0, 200);
        box(10, 10, 200);
    
        // draw front-facing tip in blue
        fill(0, 0, 255, 200);
        pushMatrix();
        translate(0, 0, -120);
        rotateX(PI/2);
        drawCylinder(0, 20, 20, 8);
        popMatrix();
    
        // draw wings and tail fin in green
        fill(0, 255, 0, 200);
        beginShape(TRIANGLES);
        vertex(-100,  2, 30); vertex(0,  2, -80); vertex(100,  2, 30);  // wing top layer
        vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30);  // wing bottom layer
        vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70);  // tail left layer
        vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70);  // tail right layer
        endShape();
        beginShape(QUADS);
        vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
        vertex( 100, 2, 30); vertex( 100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
        vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2,  30); vertex(100, 2,  30);
        vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
        vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
        vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
        endShape();
    
        popMatrix();
    }
    
    void serialEvent(Serial port) {
        interval = millis();
        while (port.available() > 0) {
            int ch = port.read();
    
            if (synced == 0 && ch != '$') return;   // initial synchronization - also used to resync/realign if needed
            synced = 1;
            print ((char)ch);
    
            if ((serialCount == 1 && ch != 2)
                || (serialCount == 12 && ch != '\r')
                || (serialCount == 13 && ch != '\n'))  {
                serialCount = 0;
                synced = 0;
                return;
            }
    
            if (serialCount > 0 || ch == '$') {
                teapotPacket[serialCount++] = (char)ch;
                if (serialCount == 14) {
                    serialCount = 0; // restart packet byte position
    
                    // get quaternion from data packet
                    q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f;
                    q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f;
                    q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f;
                    q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f;
                    for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i];
    
                    // set our toxilibs quaternion to new data
                    quat.set(q[0], q[1], q[2], q[3]);
    
                    /*
                    // below calculations unnecessary for orientation only using toxilibs
    
                    // calculate gravity vector
                    gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
                    gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
                    gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
    
                    // calculate Euler angles
                    euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                    euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
                    euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);
    
                    // calculate yaw/pitch/roll angles
                    ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                    ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
                    ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
    
                    // output various components for debugging
                    //println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f);
                    //println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI);
                    //println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI);
                    */
                }
            }
        }
    }
    
    void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
        float angle = 0;
        float angleIncrement = TWO_PI / sides;
        beginShape(QUAD_STRIP);
        for (int i = 0; i < sides + 1; ++i) {
            vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
            vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
            angle += angleIncrement;
        }
        endShape();
    
        // If it is not a cone, draw the circular top cap
        if (topRadius != 0) {
            angle = 0;
            beginShape(TRIANGLE_FAN);
    
            // Center point
            vertex(0, 0, 0);
            for (int i = 0; i < sides + 1; i++) {
                vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
                angle += angleIncrement;
            }
            endShape();
        }
    
        // If it is not a cone, draw the circular bottom cap
        if (bottomRadius != 0) {
            angle = 0;
            beginShape(TRIANGLE_FAN);
    
            // Center point
            vertex(0, tall, 0);
            for (int i = 0; i < sides + 1; i++) {
                vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
                angle += angleIncrement;
            }
            endShape();
        }
    }
    
  • How do I fix port busy?

    I am trying to install the Processing.org(Processing) code on an Arduino Mega 2560 board with A sample program for the MPU5060("MPU5060_DMP6.ino"). Everything seems to be fine, except that I get the message that the port(COM5) is busy. If I clear COM5 and run MPU5060_DMP6.ino, then Processing("MPUTeapot") states that COM5 is busy. If I clear COM5 and run MPUTeapot, then the MPU5060_DPM6.ino states that COM5 is busy. The sample code is altered as instructed and checked. I can not find a problem. The customized sample code for both MPU5060_DMP6.ino and MPUTeapot are included. Can someone please show me what is wrong.

    The Arduino sketch(MPU5060_DMP6.ino) executes in "Arduino IDE". The Processing.org sketch("MPUTeapot" is also written in Arduino C++ but executes in a separate IDE specifically for Processing.

    "MPU5060_DMP6.ino"

        #include "I2Cdev.h"
    
        #include "MPU6050_6Axis_MotionApps20.h"
        #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
            #include "Wire.h"
        #endif
    
        MPU6050 mpu;
        //MPU6050 mpu(0x69); // <-- use for AD0 high
    
        #define OUTPUT_TEAPOT
    
    
    
        #define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards  --  and Mega 2560
        #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' };
    
        volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
        void dmpDataReady() {
            mpuInterrupt = true;
        }
    
        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
    
            // 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(115200);
            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();
            pinMode(INTERRUPT_PIN, INPUT);
    
            // 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(digitalPinToInterrupt(INTERRUPT_PIN), 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);
        }
    
    
    
        // ================================================================
        // ===                    MAIN PROGRAM LOOP                     ===
        // ================================================================
    
        void loop() {
            // if programming failed, don't try to do anything
            if (!dmpReady) return;
            }
    
            // 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_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);
            }
        }
    

    Following is the code for MPUTeapot

    "MPUTeapot"

        import processing.serial.*;
        import processing.opengl.*;
        import toxi.geom.*;
        import toxi.processing.*;
    
        // NOTE: requires ToxicLibs to be installed in order to run properly.
        // 1. Download from http://toxiclibs.org/downloads
        // 2. Extract into [userdir]/Processing/libraries
        //    (location may be different on Mac/Linux)
        // 3. Run and bask in awesomeness
    
        ToxiclibsSupport gfx;
    
        Serial port;                         // The serial port
        char[] teapotPacket = new char[14];  // InvenSense Teapot packet
        int serialCount = 0;                 // current packet byte position
        int synced = 0;
        int interval = 0;
    
        float[] q = new float[4];
        Quaternion quat = new Quaternion(1, 0, 0, 0);
    
        float[] gravity = new float[3];
        float[] euler = new float[3];
        float[] ypr = new float[3];
    
        void setup() {
            // 300px square viewport using OpenGL rendering
            size(300, 300, OPENGL);
            gfx = new ToxiclibsSupport(this);
    
            // setup lights and antialiasing
            lights();
            smooth();
    
            // display serial port list for debugging/clarity
            println(Serial.list());
    
            // get the first available port (use EITHER this OR the specific port code below)
              //                    String portName = Serial.list()[0];
    
            // get a specific serial port (use EITHER this OR the first-available code above)
            String portName = "COM5";
    
            // open the serial port
            port = new Serial(this, portName, 115200);
    
            // send single character to trigger DMP init/start
            // (expected by MPU6050_DMP6 example Arduino sketch)
            port.write('r');
        }
    
        void draw() {
            if (millis() - interval > 1000) {
                // resend single character to trigger DMP init/start
                // in case the MPU is halted/reset while applet is running
                port.write('r');
                interval = millis();
            }
    
            // black background
            background(0);
    
            // translate everything to the middle of the viewport
            pushMatrix();
            translate(width / 2, height / 2);
            float[] axis = quat.toAxisAngle();
            rotate(axis[0], -axis[1], axis[3], axis[2]);
    
            // draw main body in red
            fill(255, 0, 0, 200);
            box(10, 10, 200);
    
            // draw front-facing tip in blue
            fill(0, 0, 255, 200);
            pushMatrix();
            translate(0, 0, -120);
            rotateX(PI/2);
            drawCylinder(0, 20, 20, 8);
            popMatrix();
    
            // draw wings and tail fin in green
            fill(0, 255, 0, 200);
            beginShape(TRIANGLES);
            vertex(-100,  2, 30); vertex(0,  2, -80); vertex(100,  2, 30);  // wing top layer
            vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30);  // wing bottom layer
            vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70);  // tail left layer
            vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70);  // tail right layer
            endShape();
            beginShape(QUADS);
            vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
            vertex( 100, 2, 30); vertex( 100, -2, 30); vertex(  0, -2, -80); vertex(  0, 2, -80);
            vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2,  30); vertex(100, 2,  30);
            vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2, -30, 98); vertex(-2, -30, 98);
            vertex(-2,   0, 98); vertex(2,   0, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
            vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2,   0, 70); vertex(-2,   0, 70);
            endShape();
    
            popMatrix();
        }
    
        void serialEvent(Serial port) {
            interval = millis();
            while (port.available() > 0) {
                int ch = port.read();
    
                if (synced == 0 && ch != '$') return;   // initial synchronization - also used to resync/realign if needed
                synced = 1;
                print ((char)ch);
    
                if ((serialCount == 1 && ch != 2)
                    || (serialCount == 12 && ch != '\r')
                    || (serialCount == 13 && ch != '\n'))  {
                    serialCount = 0;
                    synced = 0;
                    return;
                }
    
                if (serialCount > 0 || ch == '$') {
                    teapotPacket[serialCount++] = (char)ch;
                    if (serialCount == 14) {
                        serialCount = 0; // restart packet byte position
    
                        // get quaternion from data packet
                        q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f;
                        q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f;
                        q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f;
                        q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f;
                        for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i];
    
                        // set our toxilibs quaternion to new data
                        quat.set(q[0], q[1], q[2], q[3]);
    
                        /*
                        // below calculations unnecessary for orientation only using toxilibs
    
                        // calculate gravity vector
                        gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]);
                        gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
                        gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
    
                        // calculate Euler angles
                        euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                        euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]);
                        euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1);
    
                        // calculate yaw/pitch/roll angles
                        ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1);
                        ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2]));
                        ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2]));
    
                        // output various components for debugging
                        //println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f);
                        //println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI);
                        //println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI);
                        */
                    }
                }
            }
        }
    
        void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) {
            float angle = 0;
            float angleIncrement = TWO_PI / sides;
            beginShape(QUAD_STRIP);
            for (int i = 0; i < sides + 1; ++i) {
                vertex(topRadius*cos(angle), 0, topRadius*sin(angle));
                vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle));
                angle += angleIncrement;
            }
            endShape();
    
            // If it is not a cone, draw the circular top cap
            if (topRadius != 0) {
                angle = 0;
                beginShape(TRIANGLE_FAN);
    
                // Center point
                vertex(0, 0, 0);
                for (int i = 0; i < sides + 1; i++) {
                    vertex(topRadius * cos(angle), 0, topRadius * sin(angle));
                    angle += angleIncrement;
                }
                endShape();
            }
    
            // If it is not a cone, draw the circular bottom cap
            if (bottomRadius != 0) {
                angle = 0;
                beginShape(TRIANGLE_FAN);
    
                // Center point
                vertex(0, tall, 0);
                for (int i = 0; i < sides + 1; i++) {
                    vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle));
                    angle += angleIncrement;
                }
                endShape();
            }
        }
    

    Please and Thank You for solving such a "First Grade"(beginner) problem

    Thank You for the input. This Post has been edited for readability.

  • looking to translate a elipse within a cube ?

    I could be wrong, but I think you aren't going to get enough accuracy from the accelerometer (IMU MPU6050) to do the keep-aligned-with-the-floor-while -looking-away thing that you want. Way, way too much drift.

    You may need some kind of camera marker feedback. You can do them with fiducials, or edge detection, or IR lights like the Wii, or a special depth camera like the Kinect, but you'll need more position data to keep your ellipse on the floor.

    If you don't care about alignment and can let things float about, the IMU should do just fine.

  • looking to translate a elipse within a cube ?

    Hello guys once again im back looking to work out something to work around the whole 3D space while keeping track of your own space, i will break that down cuz i know it does sound weird.

    Well lets say that i will be using the live feed from a webcam and the cam its facing a room (this room is that cube i speak of in the main question) in this room we will have a cylinder or a ellipse flat on what would be the ground now this ellipse will be spinning at a steady pace/rate and basically i need processing to keep track of the direction and spin of the actually object in front of the cam in that room, finally not only keep track as explain above but as we move in about that room/cube we will keep track of where this spinning obj will be in respective to the camera so that at anytime if the cam was to turn back and look back at the direction where this ob was at we will still see the obj just from another perspective if that makes sense ?

    now pretending that we are that cam i speak of and we walk into a festival and we see this carousel spinning as we walk through the festival i know that if i look towards that direction where the carousel was at i know that last time i seen it it was spinning in that direction.

    here is what i think we should use to accomplish this task.

    • Arduino
    • IMU MPU6050 "this should help in keeping track of where the cam is at (in case the cam is not enough to do the trick)
    • USB Webcam

    as far as the imu goes i believe i can send Processing data from the IMU axis on its accel & gyro values and we should be able to setup some sort of variable which will keep the data from the the imu current state PLUS the current frame of the camera and its POS/LOC xy&z respectfully, basically if this current values from IMU are these numbers then those numbers are for this frame and if the gyro offset from what suppose to be the first frame then it means we moved on that direction and a simple for loop should increment its own internal Cartesian system to keep track of where we are in space (kinda like how watch dog works in arduino programming).

    ok now as for the webcam magic, i believe that if we use the following functions from this programs i found i think we can make this program im thinking of.

    1)

    import peasy.*; //peasyCam
    PeasyCam cam; //peasyCam
    
    //set-up
    void setup() {
      size(800, 600, P3D); //screen size and 3D renderer
      cam = new PeasyCam(this, 0, 0, 0, 500); //peasyCam inital lookAt(x,y,x,distance)
      cam.setMinimumDistance(200); //minimum camera distance from subject, constrains zoom
      cam.setMaximumDistance(500);  //maximum camera distance from subject, constrains zoom
    } //end setup()
    
    //begin draw loop
    void draw() {
      background(0); //clears screen
    
      //draw box just for a visual reference in the 3D space
      noFill(); //box fill colour
      stroke(150, 150, 150, 255); //box line colour
      strokeWeight(2); //box line thickness
      box(300, 300, 300); //box size (x,y,z)
    
      float[] rotations = cam.getRotations(); //camera rotations in model space (x,y,z)
      float lookedAt[]=cam.getLookAt(); //lookedAt coordinates in model space (x,y,z)
      float camPos[]=cam.getPosition(); //camera coordinates in model space (x,y,z)
      float distance=dist(lookedAt[0], lookedAt[1], lookedAt[2], camPos[0], camPos[1], camPos[2]); //distance from camera to looked at point
    
      //this finds the position of the mouse in model space
      float[] mousePos=new float[3]; //mouse coordinates in model space (x,y,z)
      pushMatrix();
      rotateX(rotations[0]);
      rotateY(rotations[1]);
      rotateZ(rotations[2]);
      mousePos[0]=modelX(mouseX-width/2, mouseY-height/2, distance);
      mousePos[1]=modelY(mouseX-width/2, mouseY-height/2, distance);
      mousePos[2]=modelZ(mouseX-width/2, mouseY-height/2, distance);
      popMatrix();
    
      //vector from camera position to mouse position in model space
      PVector camToMouse;
      camToMouse=new PVector(mousePos[0]-camPos[0], mousePos[1]-camPos[1], mousePos[2]-camPos[2]);
    
      //vector from camera position to looked at position in model space
      PVector camToLookedAt;
      camToLookedAt=new PVector(lookedAt[0]-camPos[0], lookedAt[1]-camPos[1], lookedAt[2]-camPos[2]);
    
    //line from origin to 'mirrored' mouse position
     line(0,0,0,mousePos[0]+2*camToLookedAt.x,mousePos[1]+2*camToLookedAt.y,mousePos[2]+2*camToLookedAt.z);
     //prints distance from mouse position to mirrored mouse position (just to check!)
     println(dist(mousePos[0],mousePos[1],mousePos[2],mousePos[0]+2*camToLookedAt.x,mousePos[1]+2*camToLookedAt.y,mousePos[2]+2*camToLookedAt.z));
    } //end draw()
    

    2)

    import shapes3d.*;
    import shapes3d.animation.*;
    import shapes3d.utils.*;
    import processing.video.*;
    import gab.opencv.*;
    import processing.video.*;
    
    /*
    mix this with cam3D cube
     */
    //Movie mov;
    
    Capture mov;
    OpenCV opencv;
    
    Shape3D[] shapes; 
    Box box;
    
    int shapesNumTot = 1;
    float angleX, angleY, angleZ;
    
    void setup() {
      size(1000, 750, P3D);
      mov = new Capture(this, 1280/2, 720/2, "Microsoft LifeCam Front");
      opencv = new OpenCV(this, 1280/2, 720/2);
      mov.start();
    
      //  mov = new Movie(this, "Shots.mp4");
      //  mov.loop();
      textureMode(NORMAL);
    
      shapes = new Shape3D[shapesNumTot];
    
      box = new Box(this);
      //box.setTexture(mov, Box.FRONT); // if I try this instead it blocks my PC.
      box.setTexture(mov); // this works as expected..
      box.setSize(200, 200, 200);
      box.drawMode(S3D.TEXTURE); 
      shapes[0] = box;
    }
    
    void draw() {
    
      background(0);
      pushMatrix();
    
      camera(0, 0, 300, 0, 0, 0, 0, 1, 0);
    
      //  camera(70.0, 35.0, 120.0, 50.0, 50.0, 0.0, 
      //  0.0, 1.0, 0.0);
    
      angleX += radians(0.913f);
      angleY += radians(0.799f);
      angleZ += radians(1.213f);
      rotateX(angleX);
      rotateY(angleY);
      rotateZ(angleZ);
      for (int i = 0; i < shapesNumTot; i++) {
        shapes[i].draw();
      }
      popMatrix();
    }
    
    void movieEvent(Movie m) {
      m.read();
    }
    
    void captureEvent(Capture c) {
      c.read();
    }
    

    at this point im not sure what algorithms i should implement or where to tie up the imu varibles coming over serial but i do want to do something similar to how we would use mouseX,mouseY but instead replace those 2 with the variables corresponding to the imu x and y please advise of if anyone knows of a example close to this functions i need that be super!

  • Free code for images websites?

    I am sure I am not using the correct terminology but here goes...

    After reviewing a website that shows how to display a plane rotating in a Processing window I decided I wanted to port this to a BOE Bot car to view in real time as it drives. The plane graphic is controlled by rotating a MPU6050 module and taking the serial output data from the Arduino IDE. I want to change the primitive plane graphic to a car.

    So long story short...is there a website that has free pre-coded images/examples where I can cut and paste into my Processing code and change the plane to a car?

    I have tried to search github but lack the tech vocabulary to search effectively. Is there any other option that offers free 3D images?

  • Need program for 3 axis continuous rotating 3d object

    dear koogs, please check code below for mpu6050. i am trying to understand what values are being sent over serial port and how to get them ? so that i can use mpu6050 with other microcontroller. this is code for mpu6050 teapot demo.

    //////////////////////  mpu6050 teapot demo code//////////////////////////////
    // I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
    // 6/21/2012 by Jeff Rowberg <jeff@rowberg.net>
    // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
    //
    // Changelog:
    //      2013-05-08 - added seamless Fastwire support
    //                 - added note about gyro calibration
    //      2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error
    //      2012-06-20 - improved FIFO overflow handling and simplified read process
    //      2012-06-19 - completely rearranged DMP initialization code and simplification
    //      2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly
    //      2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING
    //      2012-06-05 - add gravity-compensated initial reference frame acceleration output
    //                 - add 3D math helper file to DMP6 example sketch
    //                 - add Euler output and Yaw/Pitch/Roll output formats
    //      2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee)
    //      2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250
    //      2012-05-30 - basic DMP initialization working
    
    /* ============================================
    I2Cdev device library code is placed under the MIT license
    Copyright (c) 2012 Jeff Rowberg
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    THE SOFTWARE.
    ===============================================
    */
    
    // 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
    
    // 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
     * ========================================================================= */
    
    
    
    // uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
    // quaternion components in a [w, x, y, z] format (not best for parsing
    // on a remote host such as Processing or something though)
    //#define OUTPUT_READABLE_QUATERNION
    
    // uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
    // (in degrees) calculated from the quaternions coming from the FIFO.
    // Note that Euler angles suffer from gimbal lock (for more info, see
    // http://en.wikipedia.org/wiki/Gimbal_lock)
    //#define OUTPUT_READABLE_EULER
    
    // 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
    
    // uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
    // components with gravity removed. This acceleration reference frame is
    // not compensated for orientation, so +X is always +X according to the
    // sensor, just without the effects of gravity. If you want acceleration
    // compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
    //#define OUTPUT_READABLE_REALACCEL
    
    // uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
    // components with gravity removed and adjusted for the world frame of
    // reference (yaw is relative to initial orientation, since no magnetometer
    // is present in this case). Could be quite handy in some cases.
    //#define OUTPUT_READABLE_WORLDACCEL
    
    // uncomment "OUTPUT_TEAPOT" if you want output that matches the
    // format used for the InvenSense teapot demo
    //#define OUTPUT_TEAPOT
    
    
    
    #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' };
    
    
    
    // ================================================================
    // ===               INTERRUPT DETECTION ROUTINE                ===
    // ================================================================
    
    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady() {
        mpuInterrupt = true;
    }
    
    
    
    // ================================================================
    // ===                      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
    
        // 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(115200);
        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();
        pinMode(INTERRUPT_PIN, INPUT);
    
        // 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(digitalPinToInterrupt(INTERRUPT_PIN), 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);
    }
    
    
    
    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================
    
    void loop() {
        // 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_QUATERNION
                // display quaternion values in easy matrix form: w x y z
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                Serial.print("quat\t");
                Serial.print(q.w);
                Serial.print("\t");
                Serial.print(q.x);
                Serial.print("\t");
                Serial.print(q.y);
                Serial.print("\t");
                Serial.println(q.z);
            #endif
    
            #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");
                Serial.print(ypr[0] * 180/M_PI);
                Serial.print("\t");
                Serial.print(ypr[1] * 180/M_PI);
                Serial.print("\t");
                Serial.println(ypr[2] * 180/M_PI);
            #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
                // 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");
                    Serial.print(aaWorld.x);
                    Serial.print("\t");
                    Serial.print(aaWorld.y);
                    Serial.print("\t");
                    Serial.println(aaWorld.z);
                #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);
            }
        }
        ////////////code end.//////////////
    
    what values   are in fifobuffer
    
  • Need program for 3 axis continuous rotating 3d object

    dear chrisir,

    Currently i am sending random packets structured as .. uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' }; this packet structure is for invensence mpu6050 accelerometer-gyroscope,but i am sending random values (dummy data bytes frame of 14 bytes ). IS it possible to have 3 axial rotation with these values, if not what values can offer 3 axial rotation.

    /////////////////////////////////////////////////////////////////
    ///arduino code.
    /////////////////////
    
    uint8_t teapotPacket1[14] ={
        '$',0x02,0x23,0x78,
        0xFF,0x79,0xED,0xBB,
        0xCD,0xF6,0x00,0xE8,
        '\r', '\n'
    };
    
    void setup() {
    
      Serial.begin(115200);
    
    }
    
    void loop() {
    
      Serial.write(teapotPacket1,14);
    
    }
    
    //////////////////////////////////////////////////////////////
    ///code end
    //////////////////////////////////////////
    

    i need a processing code that reads continuously coming data from serial port and offer random 3 axial movement. or any other processing program that demonstrates continuous 3 axial rotation.