Processing Graph Flicker

I’ve made a sketch in Processing 2 that graphs the output from a linear sensor array. It is very similar to the one in this tutorial. The sketch plots the sensor values on the y-axis as a function of the pixels on the x-axis.

The sketch works, but the graph tends to flicker every couple of frames, which is very annoying. I believe it is because the rect() function is in the “void serialEvent(Serial myPort)” section, rather than the draw() section. The graph could be half-way done rendering when a new serial event happens, causing there to be a half rendered frame. I think I need to keep the drawing part in the draw() section to have it always render completed frames. Here is the entire sketch (look for the comment towards the bottom):

import processing.serial.*;

Serial myPort;
int[] data;
int xPos = 1;

void setup () {
  size(1023, 511);
  colorMode(HSB, 300, 100, 100);
  background(0, 0, 100);

  println(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 115200);
  myPort.bufferUntil('\n');
}

void draw () {
}

void serialEvent(Serial myPort) { 
  String inString = myPort.readStringUntil('\n');  
  background(0, 0, 100);
  inString = trim(inString);
  int[] data = int(split(inString, ","));
  for (int i = 0; i < data.length; i++) {  // <-- Can I move this for loop to the draw() section?
    fill(i, 100, 100);
    stroke(i, 100, 60);
    rect(i*4, height, 3, -data[i]/2);
  }
}

I tried moving the for loop the the draw() section, but I get an error that says “unexpected token: void” on the void serialEvent line. Anybody have any ideas?

(no processing expert but)

Don't do the drawing in the Serial event function. Just set a flag that new data has arrived and do the drawing in the main loop if new data has arrived (flag is set).

robtillaart:
(no processing expert but)

Don’t do the drawing in the Serial event function. Just set a flag that new data has arrived and do the drawing in the main loop if new data has arrived (flag is set).

Yes! You were exactly right robtillaart. Thanks for the input. Here’s what I ended up doing:

import processing.serial.*;

Serial myPort;
int[] data;
int xPos = 1;

void setup () {
  size(1023, 511);
  colorMode(HSB, 300, 100, 100);
  background(0, 0, 100);

  println(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 115200);
  myPort.bufferUntil('\n');
}

void draw () {
  noLoop(); //<-- This function tells processing NOT to draw new frames at 60 FPS 
}

void serialEvent(Serial myPort) { 
  String inString = myPort.readStringUntil('\n');  
  background(0, 0, 100);
  inString = trim(inString);
  int[] data = int(split(inString, ","));
  for (int i = 0; i < data.length; i++) {
    fill(i, 100, 100);
    stroke(i, 100, 60);
    rect(i*4, height, 3, -data[i]/2);
  }
  redraw();  //<--This fuction tells processing to draw a new frame after the new data has become available 
}

I just had to make it draw a new frame ONLY after all of the incoming data has been processed. I did this with the noLoop(); and redraw(); functions.