We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpElectronics,  Serial Library › Sketch freezes when receivig data from Arduino
Page Index Toggle Pages: 1
Sketch freezes when receivig data from Arduino (Read 1187 times)
Sketch freezes when receivig data from Arduino
Oct 13th, 2009, 9:26am
 
Hi all,

I'm trying to read some sensor information from an Arduino board and create a field of points in Processing from which I can create files to pass onto Rhino/Grasshopper. The Arduino part is relatively simple, just read the sensors and print the values. But when Processing gets these values the results can be unreliable with the sketch freezing, running really slowly or working and then freezing when the sensor data changes.

If the sensor values are hardcoded into the sketch and no serial input is used then it works fine, although nothing can be altered.

Here's the Processing code:

import processing.serial.*;
Serial serialPort;
//--------------------------------------------
// These numbers can be manipulated to change
// the size of the datascape produced.
//--------------------------------------------
int xnumber = 23;      // number of vertices on x axis
int xdistance1 = 0;    // first distance between x vertices from sensor
int xdistance2 = 0;    // second distance between x vertices from sensor
int ylevels = 50;      // number of levels of vertices in the y direction
int ydistance = 30;    // distance between each vertex in the y direction
//--------------------------------------------
float rotX = 0;
float rotY = 0;
float xstart = 0;
float xfinish = 0;
float ystart = 0;
float yfinish = 0;
float xdistance = 0;
float xposition = 0;
float yposition = 0;
float zvalue = 0;
float xattractor = 0;
float yattractor = 0;
float zattractor = 0;
float adjustDistance = 0;
boolean yadd = true;
boolean fileoutput = false;
boolean fileopen = false;
int lineFeed = 10;
int readCount = 0;
int readPort = 0;
int [] sensorValue = new int [5];
int sensorArray = sensorValue.length;

String inString;

PrintWriter outputx;
PrintWriter outputy;
PrintWriter outputz;
PrintWriter outputa;
PrintWriter outputb;
PrintWriter outputc;

void setup ()
{ //println ("setup");
 size (800, 800, P3D);
 stroke (204, 102, 0);
 noFill ();
//  noLoop ();
 
 println (Serial.list());

 String portName = Serial.list ()[0];
 serialPort = new Serial (this, portName, 9600);

 serialPort.bufferUntil (lineFeed);
 serialPort.clear ();
 
 if (floor (float (xnumber)/2) == ceil (float (xnumber)/2))
   {xnumber = xnumber++;}
   
 yfinish = ylevels * ydistance;
}

void draw ()
{ //println ("draw");
 // Allow for mouse based rotation of the point field
 if (mousePressed)
 {
   rotX = mouseY/float(width);
   rotY = mouseX/float(height);
 }
 
 translate (height/2,width/2);
 rotateX (PI/3.0 + rotX * PI*-1.5);
 rotateY (PI/3.0 + rotY * PI*-1.5);
 
 // Draw the points only when there is sensor data from the Arduino
 if (readCount == sensorArray)
 {
   background (0);
   
   // Assign the sensor values into the sketch variables
   assignValues ();
   
   adjustDistance = float (xdistance1 - xdistance2) / float (xnumber);
   xdistance = xdistance1;
 
   // Write out the Rhino files only on keypress 'F'
   if (fileoutput)
   {
     openFiles ();
           
     point (xattractor, yattractor, zattractor);
           
     outputa.println (xattractor);
     outputb.println (yattractor);
     outputc.println (zattractor);
   }
 
   // For each row in the Y direction process the sensor data
   for (int i = 0; i < ylevels; i++)
   {
     // Adjust the distance between points so that the shape of the point field
     // can be altered using the sensors
     adjustDist (adjustDistance);
     // make sure that each level of points is mirrored to the first, this
     // ensures that if triangles are drawn and the whole Y distance is used the
     // triangles will be point to point
     if (floor(float(i)/2) != ceil(float(i)/2)) {yadd = true;} else {yadd = false;}
   
       // Work out the positions of the X and Y points
       // float is used so that the distance changes between X points can be
       // varied greater than by an integer increment
       for (float j = xstart; j <= xfinish; j += xdistance)
       {
         xposition = j;
         yposition = i * ydistance;
         
         if (yadd)
         {
           yposition = yposition + (ydistance/2);
           yadd = false;
         }
         else {yadd = true;}
       
         point (xposition, yposition, zvalue);
       
         if (fileopen)
         {
           outputx.println (xposition);
           outputy.println (yposition);
           outputz.println (zvalue);
         }
       }
   }
 
   if (fileopen)
   {
     closeFiles ();
   }
   serialPort.write (lineFeed);
   readCount = 0;
 }
}

void serialEvent (Serial serialPort)
{ //println ("serialEvent");
 while (serialPort.available () > 0)
 {
   readPort = serialPort.read ();
   println (readPort);
   
   if (readPort == 'A')
   {
     serialPort.write (lineFeed);
     serialPort.clear ();
     readCount = 0;
   }
   else
   {
     if (readPort != lineFeed && readCount < sensorArray)
     {
       sensorValue [readCount] = readPort;
       readCount++;
     }
   }
 }
 serialPort.clear ();
}

void keyPressed ()
{
 if (key == 'f')
 {
   fileoutput = true;
 }
 else
 {
   fileoutput = false;
 }
}

void adjustDist (float adist)
{ //println ("adjustDist");
// Determine the relative position of the 'X' points
 // adjust the distance between points for each row drawn
 xdistance = xdistance - adist;
 // the initial 'X' start position, assumes symetry around 0,0,0
 xstart = floor (float (xnumber)/2) * xdistance * -1.0;
 // the initial 'X' finishing position
 xfinish = xdistance * xnumber + xstart;
}

void assignValues ()
{
 xdistance1 = sensorValue [0];
 xdistance2 = sensorValue [1];
 xattractor = sensorValue [2];
 yattractor = sensorValue [3];
 zattractor = sensorValue [4];
}


I haven't included the open and close file parts as they are fairly standard and wouldn't fit in the post anyway. I'll put the Arduino code in the following post in this thread.

Thanks
Re: Sketch freezes when receivig data from Arduino
Reply #1 - Oct 13th, 2009, 9:29am
 
Ok, here's the Arduino code:

int a1 = 0;
int a2 = 0;
int a3 = 0;
int a4 = 0;
int a5 = 0;
int b1 = 0;
int b2 = 0;
int b3 = 0;
int b4 = 0;
int b5 = 0;

int count = 0;
int lf = 10;

void setup ()
{
Serial.begin (9600);
establishContact ();
}

void loop ()
{
a1 = map(analogRead (0), 0, 1023, 11, 150);
a2 = map(analogRead (1), 0, 1023, 11, 150);
a3 = map(analogRead (2), 0, 1023, 11, 150);
a4 = map(analogRead (3), 0, 1023, 11, 150);
a5 = map(analogRead (4), 0, 1023, 11, 150);

if (Serial.available () > 0
&& (a1 != b1 || a2 != b2 || a3 != b3 || a4 != b4 || a5 != b5))
{
  Serial.print (a1, BYTE);
  Serial.print (a2, BYTE);
  Serial.print (a3, BYTE);
  Serial.print (a4, BYTE);
  Serial.print (a5, BYTE);
  Serial.print (lf, BYTE);
  Serial.flush ();
 
  b1 = a1;
  b2 = a2;
  b3 = a3;
  b4 = a4;
  b5 = a5;
 
//    delay (1000);
}
}

void establishContact ()
{
while (Serial.available () <= 0)
{
  Serial.print ('A', BYTE);
  Serial.print (lf, BYTE);
}
}

Like I said, really basic; read, map and send.

Really hope one of you guys can help me out with this. Would be much appreciated.

Thanks
neillg

PS Originally posted in PROGRAM. One reply said I could use one thread to control the data feed and another for the display of the points. Totally lost on this one...
Re: Sketch freezes when receivig data from Arduino
Reply #2 - Oct 13th, 2009, 9:34am
 
Here's the first reply form the Program section...

PhiLho  wrote on Oct 13th, 2009, 8:59am:
When you have this kind of issue, it might be better to put the code polling the data in a separate thread. Thus, if it is blocked, the display continue to be updated. The difficulty is to find the right way to update the display by using the data got from the other thread.
I don't have Arduino, so I can't help you more, perhaps some knowledgeable people (probably lurking in the Electronics, Serial Library section...) might give better/more precise advices.


Any extra help here would be greatly appreciated.

Thanks
neillg
Page Index Toggle Pages: 1