I am having a weird issue with the Mega 2560 Arduino (two separate versions of it, from two separate manufacturers) that I am not having with an Uno. I am trying to send a serial message to the board and then have it respond, but if I try to do the send-receive loop too quickly then I start just reading in nulls. I'm putting my code (Arduino and Processing) below. On an Uno, the Processing app prints a couple nulls and then starts printing 1000, but on both of my Megas it just prints nulls. Subjectively, when I use the Arduino monitor, there is a fairly long lag between sending a message to the board and a response printing to the monitor. Any idea what could be causing this, or how to fix this? Thanks!
Subjectively, when I use the Arduino monitor, there is a fairly long lag between sending a message to the board and a response printing to the monitor. Any idea what could be causing this, or how to fix this?
Same lag with both Arduinos? Or is the lag only with the Mega?
On the Arduino, loop() is called over and over, as fast as possible.
In Processing, draw() is called over and over, but NOT as fast as possible. The idea is that draw() is drawing stuff, so it need not be called any faster than the desired frame rate. The serialEvent() method, on the other hand, IS called whenever there is serial data.
So, for optimum speed reading and writing serial data from Processing, serial data should not be read/sent in draw(). It should be read in serialEvent(), and sent there if data is to be sent in response to serial input. If data is to be sent in response to key or mouse events, that happens in draw().
Same lag with both the Megas, but not getting it with the Uno. Initially I thought it was a problem with my first Mega's hardware, but then I bought a new one from a different supplier and it's got the same issue.
Thanks for the tip about serialEvent, but I don't think it's as useful here; the Arduino only talk back to the computer when it's queried. In my application (ie not the sample code I'm posting) I'm using the arduino to control some external sensors. The computer tells the arduino the measurement it wants performed, then the arduino changes the sensor a little, performs a measurement, and relays the result to the computer. In my mind it makes sense to include this in the draw function, but I'm a total noob with Processing so I could easily be wrong.
Great observation, but unfortunately that didn't help either. Any chance it could have to do with switching between boards and the port name changing? I know that's a long shot but I'm at my wit's end, unless it's just a shortcoming of the 2560 boards, but I would find that hard to believe.
I'm putting my current code below this message again. Thanks so much for your help!
// Arduino
void setup() {
Serial.begin(9600);
}
char mybuffer[4];
void loop() {
if (Serial.available() ) {
int throw_away1 = Serial.readBytesUntil('\n', mybuffer, 4);
Serial.println(1000);
}
}
// Processing code
import processing.serial.*;
Serial port;
void setup() {
port = new Serial(this, Serial.list()[0], 9600);
}
void draw() {
delay(100); // works when this is 1000 instead
port.write("000\n");
String inString = port.readStringUntil('\n');
println(inString);
}
the cutoff of how much lag is required for the Mega to work is between 830 and 840 millis
the cutoff is about the same for each Mega
when it works near the cutoff, two nulls get printed to the screen and then it's numbers. when I'm far away from the cutoff, a single null gets printed.
following up on some other posts I saw, I tried running the program with the arduino editor closed. It didn't do anything.
I was able to fix it! I google around and found this: Arduino Forum
It sounds like the issue is that the Arduino resets itself very time I start the Processing application, but things get hosed if I start sending data to the Mega too quickly. The workaround is to put a delay into Processing's setup function:
frameCount = 1; // required for the delay to work, since frameCount=0 during setup and the delay function requires frameCount >= 1
delay(850);
Now it seems to be working great. Thank you for your help!
Alternatively, you could have the Arduino send a character when it is ready to receive data. Then, the Processing app would simply wait until is saw data from the Arduino before it started sending.
Interesting find on the frameCount thing. I would have expected delay() to work at all times, not just after the first invocation of draw().