I have a serious problem with how the PC is receiving serial data from Arduino. I am trying to send a large amount of data from arduino to pc using serial comm. When have the serial port window open, the data steams nicely and there is no lag between sending and receiving. But when I use a Processing program to read this data stream and store it in an array, there is a huge amount of lag. For example, I am streaming data from arduino for 5 seconds and it takes an additional 13 seconds for the processing program to finish recording data into an array. I am reading the data like this on the processing side:
case 2: // write incomming data to large array
if( myPort.available() > 1 ) {
myData = myPort.readStringUntil('\n');
}
if ( myData == null ) {
myState = 3;
break;
} else if ( myData != null ) {
Data[n] = myData;
n++;
myData = null;
}
break;
Someone please tell me what the hell the processing program is doing that it is taking so long to finish this simple task.
Is there a way to make it faster?
Thanks
PS. I know my post is more directed towards processing, but I thought there are more people here too.
You can assume the whole processing program is just reading and storing the data into an array (the code). I tried this myself to narrow down where the lag is occurring. The 13 second lag is because of this section.
The Arduino is sending 6 sensor values every 5 ms for 5 seconds and then it stops.
The code is intellectual property of my company. Thats why...
Let me ask my question another way.
Is there any other way make the comm link between arduino and processing faster (not necessarily serial) ? I need at least 1MB/sec of transfer rate.
case 2: // write incomming data to large array
if( myPort.available() > 1 ) {
myData = myPort.readStringUntil('\n'); // ASCII is not a good transfer medium for lots of data, try a binary encoding, especially if you need 1 MB/s.
}
if ( myData == null ) {
myState = 3;
break; // This is not required, if this 'if' statement is true, then the next code block in the 'else' section will not run anyway.
} else if ( myData != null ) { // This if statement is not required, the 'else' implies the opposite of the original 'if', you don't need to re-check it.
Data[n] = myData;
n++;
myData = null;
}
break;
Is there any other way make the comm link between arduino and processing faster (not necessarily serial) ? I need at least 1MB/sec of transfer rate.
The only link between the Arduino and Processing is the serial port. You do not have to send ASCII data, though. You could send binary data. That's faster for the Arduino AND for Processing. You aren't going to get 1Mb/sec, but that number is meaningless anyway.
I tested another program to measure the speed of the serial data comming in. Here it is: (it is a modification of the example code on processing website)
import processing.serial.*;
Serial myPort; // The serial port
PFont myFont; // The display font
String inString; // Input string from serial port
int lf = 10; // ASCII linefeed
void setup() {
size(400,200);
println(Serial.list());
myPort = new Serial(this, "COM5", 57600);
myPort.bufferUntil(lf);
}
void draw() {
background(0);
text("received: " + inString, 10,50);
}
void serialEvent(Serial p) {
inString = p.readStringUntil('\n');
}
This code displays the data steam as fast as the arduino.
I think the reason that the original code is slow is because of write speed of processing. I am writing the serial data into an array and I think thats why this thing is very slow.
Correct me if I am wrong.
Is there a way to store the data faster into the Data[] array.
Thank you for taking the time to recognize this. You are absolutely right!!! thanks a lot for that.
The fact is that this line is blocking everything: myPort.readStringUntil('\n');
The 'if' statement has nothing to do with it. I commented out the if statement and it still was lagging.
Now, how do I process each character and achieve the same result as I am trying to do, but much faster?
Now, how do I process each character and achieve the same result as I am trying to do, but much faster?
First off, decide whether that blocking is really an issue. If all you are doing is waiting for data, then whether you loop in the draw() function 100 times before the \n arrives, or a 1000 times doesn't matter, does it?
It isn't clear whether your snippet of code is in draw() or in serialEvent(). If it is in draw(), you should move it to serialEvent(). If you don't have a call to myPort.bufferUntil('\n') in setup(), you should have. That way, the serialEvent() method will only be called when the \n arrives.