How do I fix port busy?

edited November 2016 in Arduino

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.

Answers

  • Everything seems to be fine, except that I get the message that the port is busy. If I clear COM5 and run the MakeBlock sketch, then Processing(Teapot) states that COM5 is busy. If I clear COM5 and run Processing, then the MakeBlock sketch states that COM5 is busy

    Just to clarify, you are running MakeBlock and TeoPot at the same time? Are you running them in Processing? They both have an ino extension so they are arduino.

    Please also format your code properly. To do that, edit your previous post, select your code and hit ctrl+o. Ensure there is an empty line above and below the code.

    Kf

  • You cannot communicate with the Arduino over serial with both the Processing sketch and the Arduino IDE. Are you trying to read Serial data from the Arduino IDE? You'll also need to stop the sketch before uploading an updated version of the code to the Arduino (or tell the Serial object to stop communicating).

  • 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();
        }
    }
    
  • Replace OPENGL with P3D, they're the same now.

    The sketch looks like it requires Toxiclibs. I'm not sure how well that library works with Processing 3. If you run into more problems try running it in Processing 2.2.1.

  • I am using Arduino 1.6.5 and Processing 3.2.3 OPENGL has been replaced with P3D Now I get, in line 68( " println(Serial.list()); " ) "Type String[] of the last argument to method println(Object...)doesn't exactly match the varag parameter type. Cast to Object[] to confirm the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation.

  • edited November 2016

    Processing 3.2.3's OPENGL has been replaced with P3D.

    Actually since Processing 2, the constant OPENGL is simply an alias for constant P3D.
    The old previously non-OpenGL-based renderer P3D represented by it was removed from Processing since! :(
    Same case for P2D: Previously it was a non-OpenGL-based renderer in Processing 1. =((

Sign In or Register to comment.