We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi all,
We are facing timing issue with serial plot in processing. Below are the details.
Description
We are using Processing to plot the incoming serial data. Incoming data is of 'Float' type & there is a value arriving at the serial port once in 4mS.
Expected Behavior
Ideally processing should plot the data immediately without any delay. In this case, data plotting will get completed as soon as the data arrival stops at the serial port.
Current Behavior
Processing is taking time to receive & plot each value from serial port. This delay to read serial data value & plot is around 16mS. Due to this delay, Processing plot will not be real time when compared to incoming serial data.
Steps to Reproduce
Send data at higher rate from to Serial port of PC (At a rate of 250Hz) Verify that the plotting takes higher time to plot compared to incoming data rate Below is the code we are using for the plot. I was unable to attached the code in this post, thus adding the code in the discussion itself.
import processing.serial.*;
String xLabel = "X-axis";
String yLabel = "Y-axis";
String Heading = "Test Plot";
Serial myPort; // The serial port
int xPos = 1; // horizontal position of the graph
float inByte = 0;
float inByte1=0,inByte2=0;
int input=0;
PFont font;
int text_offset=20;
int margin_offset=50;
void setup ()
{
// set the window size: 100 points taken for Margins
size(1300,650);
// List all the available serial ports - For reference
println(Serial.list());
// Select first port
myPort = new Serial(this, Serial.list()[0], 115200);
// Don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
// set inital background:
background(255);
}
void draw ()
{
//Check if the new data is available
if (myPort.available() > 0)
{
String inString = myPort.readStringUntil('\n');
if (inString != null)
{
// convert to an int and map to the screen height:
inByte = float(inString);
// Copy the old data to inByte2 & copy new data to inByte1
inByte2=inByte1;
inByte1=inByte;
// Draw a line between inByte1 & inByte2
line(xPos+margin_offset-1, height-inByte2-margin_offset, xPos+margin_offset, height - inByte1-margin_offset);
// Reset if the edge of the screen is reached
if (xPos >= width)
{
//Reset xPos
xPos = 0;
//Reset background
background(255);
}
else
{
// increment the horizontal position:
xPos++;
}
}
}
}
Environment
Processing version: 3.3.6 Operating System and OS version: Windows 8 Is there any way to decrease this delay so that data can be plotted real time. Looking forward to valuable suggestions.
Thanks, Suresha
Answers
https://Forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text
https://Forum.Processing.org/two/discussion/14534/myport-available-always-0#Item_1
Hi,
Thanks for your response.
I tried using SerialEvent , noLoop & redraw functions. Even though the logic works, the plot is not fast enough to receive all incoming serial data in real time.
Below is the modified code -
If I add frameRate(200) in the setup function, then the plot happens almost 1.75 times faster. But even this is not enough for the serial data to be plotted in real time. Increasing the frameRate beyond 200 doesn't result in any improvements.
Is there any other way to increase the plotting speed ? Looking forward to valuable suggestions.
My understanding is that if your have a input rate 250Hz, processing should be able to handle it or, in better words, you should manage it properly. For this, you need to use the serialEvent() function as shown by @GoToLoop's post.
As you know, Processing is usually running at 30 fps. When you use the serialEvent() function, you are not constrained to the draw's upper limit for frame handling. What you need to do, in case the serial event is not as fast, is that all the input data from the serial stream will be accumulated in the serial's input buffer. When you get a handle of the serialEvent(), you should access and stored all the data from the input buffer. A demonstration is done in:
https://processing.org/reference/libraries/serial/Serial_readString_.html
Notice in the demonstration they use a while() inside the draw() function. My suggestion is to use the serialEvent() but I am guess either one should work.
To plot the data though, you are constrained to the screen's refreshing rate of 30fps. For an initial input rate of 250Hz, every time draw() runs, it will add not one point but about 8 points since 250Hz/30Hz=8 approx. For this concept to wok in your challenge, I will do it this way:
One final recommendation is to use a ring data structure instead of a standard list or array object. I hope this helps,
Kf
Hi ,
Thanks a lot for your suggestions.
I modified the code as below & I am able to plot at 250Hz now.
Really appreciate your help !!
Thanks,
Suresha