Parsing values from Arduino to processing.

I'm trying to parse my values which i get from my 6 DOF inertial measurement unit , from arduino to processing. So far, following results have been accomplished.

  1. Sent the float values as string to processing. Converted them back to float in processing and displayed.

Problem : When i tilt my IMU, the values changes accordingly, but these changes are not affected in processing, but it is successfully affected in arduino serial monitor. There is only slight variation in processing, say from 5.8 to 6.2 when i do a 90 degree tilt, whereas the actual should have been like about 5.8 to 70.4 or something.

This is the code fragment from arduino.

 mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetEuler(euler, &q);
            Serial.println(euler[0] * 180/M_PI);
            Serial.println(euler[1] * 180/M_PI);
            Serial.println(euler[2] * 180/M_PI);

And this is my Processing sketch.

import processing.serial.*;
import processing.opengl.*;
Serial myPort;
float[] value=new float[4];
int i=0;
int k=100;
String[] msg=new String[5];


void setup()
{
  size(600,600,OPENGL);
  noStroke();
  String portName="COM4";
  myPort = new Serial(this, portName, 115200);
  frameRate(50);
  background(255);
  fill(246, 225, 65);
  lights();
}

void draw()
{
  if(i>2)
  i=0;
 msg[i] = myPort.readStringUntil(13);
           if(msg[i] != null)
               {
               value[i] = float(msg[i]);
               println(value);
                } 
                ++i;
                

  background(255);
  
 
  
  translate(width/2,0);

 
    fill(0);
   text("Yaw: " + ((float) value[0]), 0, k);
  text("Pitch: " + ((float) value[1]), 100, k);
  text("Roll: " + ((float) value[2]), 200, k);



}

So can you show what gets printed out by processing for a given string sent down the serial line? In fact can you get processing to print out the string version of what it receives as well as the output of the float conversion - this way you'll narrow down where the problem is.

The draw() function in Processing is like the loop() function in Arduino sketches. in that it gets called over and over. It is unlike the loop() function in Arduino sketches, though, in how often it gets called.

The loop() function gets called again immediately after it ends.

The draw() function gets called after the previous function ends, after an interval defined by the frame rate. You can research the default frame rate.

Serial data handling is not meant to be done in draw(). It is meant to be done in a function with the prototype:

void serialEvent(Serial port)
{
}

The port on which data arrived is supplied when Processing calls this method, which it does when serial data arrives. If you use the Serial::bufferUntil() method (in setup()) to define a different trigger event, the the serialEvent() event handler is not called until that trigger happens.

I'd recommend that you make some changes to your Processing sketch, and let us know if that affects your results.

this way you'll narrow down where the problem is.

I think the problem lies in the fact that arduino loops function at way higher speeds compared to processing. So there might be even lag of seconds.

I'd recommend that you make some changes to your Processing sketch, and let us know if that affects your results.

Like you told, i changed my code adding serialEvent to my processing. But I'm getting 0.0 for value[0],value[1],value[2]. I have a feeling the loop is never getting invoked. I tried adding the bufferUntil() in setup, still didn't work. Heres the code.

import processing.serial.*;
Serial port;
float[] value=new float[4];
int i=0;
String mg;

void setup()
{
  size(600,600);
  port=new Serial(this, "COM4",115200);
 // port.bufferUntil(13);
  frameRate(300);
  background(255);
  fill(246,225,65);
}


void draw()
{
  
  background(255);
  translate(width/2,0);
  fill(0);
   
  text("Yaw: " + ((float) value[0]), 0, 100);
  text("Pitch: " + ((float) value[1]), 100, 100);
  text("Roll: " + ((float) value[2]), 200, 100);
  
  
}

void SerialEvent(Serial port)
{
    
  mg=port.readStringUntil(13);
  fill(0);
  
    if(mg!= null)
  {
 float value[] = float(split(mg, ' '));
 println(value);
  }
 
}

Also, i made a slight change in the arduino code..Now i'm sending the string as one line and the values are separated by spaces. Heres the code fragment of the arduino code.

Serial.print(euler[0] * 180/M_PI);
Serial.print(" ");
Serial.print(euler[1] * 180/M_PI);
Serial.print(" ");
Serial.println(euler[2] * 180/M_PI);
  fill(0);

In serialEvent()? I don't think so.

    if(mg!= null)
  {
 float value[] = float(split(mg, ' '));
 println(value);
  }

If you got some
data, why don't you
print out what you
got, to see if
that was reasonable?

Consistent indenting will make your code much easier to read. Consistent spacing, too.

Why is mg global? No other function accesses it.

The local variable (array) in the serialEvent() method, value, is NOT the same variable as the global variable (array), value. You are storing data in one in the serialEvent() method and printing data from the other in draw().

float value[] = float(split(mg, ' '));
 println(value);

Does this even work? How large is value?

Does this even work?

Yes. Processing has overloaded the print() and println() functions to print arrays, too.

How large is value?

Depends on how many comma separated values there were in the serial data read. The split() method returns an array of strings separated by the specified delimiter. The float() function has an overload that takes an array of strings, and returns an array of floats.

float value[] = ...

And the compiler allocates enough memory here for whatever the function returns at run-time? Cool.

Thanks for your replies, guys. :slight_smile:

Consistent indenting will make your code much easier to read. Consistent spacing, too.

Sorry about that. Will do that in my future posts. :slight_smile:

The local variable (array) in the serialEvent() method, value, is NOT the same variable as the global variable (array), value.

That was where the problem was. I thought that was part of the split syntax but i was actually creating a local array also. Thanks for your help.

And, i'll post a video of what i was working on, in a few days. :slight_smile:

MPU 6050 IMU simulation( Using Kalman filtering) - YouTube This is a video of the simulator i was working on. :slight_smile: