Reducing lag between the arduino and a processing sketch on my computer

As already pointed out, your Arduino is saying too much too fast. Adding delay() will slow it down, but still it keeps yelling at Processing. Ideally, you want Processing to ask for the value when it's convenient, and then receive one answer from your Arduino.

Enter SerialEvent().

As opposed to loop() on your Arduino and draw() in Processing, everything inside serialEvent() only excutes when there is something new in the serial buffer. So instead of Processing asking questions as fast as possible and your Arduino yelling back even faster, they can have a nice, polite (asynchronous) conversation.

Both Processing and Arduino have a serialEvent. This is serialEvent() on the Arduino and this is serialEvent() in Processing. Using serialEvent on both sides, this is what would happen:

  1. Processing sends a character to the serial connection. This could be any character, but if we predetermine one we can filter out any unwanted requests caused by e.g. a noisy signal. For this example, let's send a V every time we want a new reading of your potmeter. After the character is sent, we continue our business as usual. Not waiting around for an answer here!

  2. On the Arduino side nothing is happening, until it receives data in the serial buffer. It checks whether the incoming character is a V, and lucky us, it is. The Arduino reads the potmeter's value once, outputs that value to serial once, and goes back to chilling out, maxing relaxing all cool. Protip: terminate the value with a character (* in our case). This will help you in the next step.

  3. Processing is doing its regular interfacey pixel business when all of a sudden there's a disturbance in the force new data in the serial buffer. It switches to serialEvent(), and starts reading the serial data, until our terminating * is encountered. Knowing for sure this was the last character worth reading, we can now store the incoming value in a variable that stores the Arduino's reading.

  4. That's it. Processing now knows the new sensor value and carries on with whatever we tell it to do. Meanwhile, your Arduino is enjoying the weather or contemplating its existence until there is incoming serial data.


You're outputting a reading every time round the Arduino loop(), so it seems likely that your Processing program isn't running fast enough to keep up with it. Try putting a delay into the loop() in your Arduino code to slow it down, e.g.:

void loop(){
    Serial.write(analogRead(A0)/4);
    delay(50);
}

As far as I know, Processing aims to run at a consistent framerate, which you can modify using the frameRate() function. By default, it's 60 frames per second, although it may run slower on older systems (or where you're running an intensive program). You can check how fast it's running by reading the frameRate variable.

Introducing a 50 millisecond delay into the Arduino loop means it will be updating a little under 20 times per second. That means it should be fast enough for user interface purposes, but should also be well within the capabilities of your Processing program.

As far as the baud rate (communication speed) is concerned, adjusting it by arbitrary amounts is likely to have unpredictable results. That's because the hardware will only support specific speeds, and trying to use anything else can result in the data appearing garbled on the other end. The Serial.begin() documentation has some more information about supported baud rates.


Your polling loop runs at full speed of your processor, and writes to the serial port in each round.

This way, you're writing way more often to the serial port than it can handle.

The port writes out data as fast as you configured it, and buffer data that is comming in from your program too fast, to write it out as soon as possible. It the buffer is full, it just drops new data.

What's important here is that it will keep the order of the values: It is a FIFO buffer, working in First In/First Out order.

What happens is:
The loop fills the port buffer, and keeps it 100% full.
If you turn the potentiometer, the changed value get's written to the end of the buffer, the port works as fast as it can to write out all elements in the buffer, that have still the old value.

And finally the value you are interested in. The most current value we wanted to see immediately was at the end of the FIFO, and first in/ first out also means last in/last out. The opposite of what we want.

The maximum frequency it makes sense to read your data, is the frequency you can write it out, so you should use at least a delay that is long enough to write out the bytes at the current port speed.


As another, independent measure to prevent this kind of delay in general,
you could additionally set the write buffer of the port to a minimum.

That would cause data to be dropped much earlier, instead of buffering a lot first.

Of course, in many applications that is not what you need; With bad luck, it could work anyway in the beginning, and get unstable in some situations when the timing changes based on things like processor load, and there are only some random data samples that get dropped. A large buffer generally behaves much more deterministic, so do use a large buffer by default.