user11140: I am trying to write a simple Java program to display the analog input fed to an Arduino board upon a stimulus from a user on some physical sensors.
If I use the Arduino program itself and look at the serial monitor, I see the analog read based on user input updated instantly. However, when reading the input from my Java program, there is a significant delay (8-12 seconds) between the physical stimulus and the display of the value.
The code uploaded to Arduino is very simple, just cycle through a bunch of analog ports and print the data:
void setup() {
  Serial.begin(9600);
  pinMode(30, OUTPUT);
}

void loop() 
  digitalWrite(30, HIGH);

  for (int i = 0; i < 10; i++) {
    int sensorValue = analogRead(i);
    Serial.print(String(i) + ":");
    Serial.println(sensorValue);
  }
}

The Java code I am using is almost entirely copied from the example provided here, with the exception that I updated the port name to work for my system (Mac OS X 10.10.3).
Here is the Java code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier; 
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent; 
import gnu.io.SerialPortEventListener; 
import java.util.Enumeration;


public class SerialTest implements SerialPortEventListener {

    SerialPort serialPort;

    /** The port we're normally going to use. */
    private static final String PORT_NAMES[] = { 
            "/dev/cu.usbmodem1411",
            "/dev/cu.usbmodem1451",
    };

    /**
    * A BufferedReader which will be fed by a InputStreamReader 
    * converting the bytes into characters 
    * making the displayed results codepage independent
    */
    private BufferedReader input;

    /** The output stream to the port */
    private OutputStream output;

    /** Milliseconds to block while waiting for port open */
    private static final int TIME_OUT = 2000;

    /** Default bits per second for COM port. */
    private static final int DATA_RATE = 9600;

    public void initialize() {
        CommPortIdentifier portId = null;
        Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

        //First, Find an instance of serial port as set in PORT_NAMES.
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
            for (String portName : PORT_NAMES) {
                if (currPortId.getName().equals(portName)) {
                    portId = currPortId;
                    break;
                }
            }
        }
        if (portId == null) {
            System.out.println("Could not find COM port.");
            return;
        }

        try {
            // open serial port, and use class name for the appName.
            serialPort = (SerialPort) portId.open(this.getClass().getName(),
                    TIME_OUT);

            // set port parameters
            serialPort.setSerialPortParams(DATA_RATE,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);

            // open the streams
            input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
            output = serialPort.getOutputStream();

            // add event listeners
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

    /**
     * This should be called when you stop using the port.
     * This will prevent port locking on platforms like Linux.
     */
    public synchronized void close() {
        if (serialPort != null) {
            serialPort.removeEventListener();
            serialPort.close();
        }
    }

    /**
     * Handle an event on the serial port. Read the data and print it.
     */
    public synchronized void serialEvent(SerialPortEvent oEvent) {
        if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                String inputLine=input.readLine();
                System.out.println(inputLine);
            } catch (Exception e) {
                System.err.println(e.toString());
            }
        }
        // Ignore all the other eventTypes, but you should consider the other ones.
    }

    public static void main(String[] args) throws Exception {
        SerialTest main = new SerialTest();
        main.initialize();
        Thread t=new Thread() {
            public void run() {
                //the following line will keep this app alive for 1000 seconds,
                //waiting for events to occur and responding to them (printing incoming messages to console).
                try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
            }
        };
        t.start();
        System.out.println("Started");
    }
}

All the program does is print out the values of the Arduino serial monitor, yet it takes way longer (8-12 seconds) through Java than it does from the Arduino program itself.
1) Why is this happening?
2) How do I fix it?

user10794: Timing tests show that the Java code lags something like 25 or more seconds behind the input from the Arduino. This can be fixed by changing in the Java code these lines:
       try {
            String inputLine=input.readLine();
            System.out.println(inputLine);
        } catch (Exception e) {

to:
       try {
            while (input.ready ())
              {
              String inputLine=input.readLine();
              System.out.println(inputLine);
              }
        } catch (Exception e) {

This extra loop "drains" the input buffer of data in the one serialEvent call, rather than relying upon a serialEvent call per line of data.
I found when testing that the output is now highly responsive, even without a delay on the Arduino side.

My other answer of adding a delay call slowed output down enough for the Java app to catch up, but I must admit it isn't the best solution. 

11140: <p>I am trying to write a simple Java program to display the analog input fed to an Arduino board upon a stimulus from a user on some physical sensors.</p>

<p>If I use the Arduino program itself and look at the serial monitor, I see the analog read based on user input updated instantly. However, when reading the input from my Java program, there is a significant delay (8-12 seconds) between the physical stimulus and the display of the value.</p>

<p>The code uploaded to Arduino is very simple, just cycle through a bunch of analog ports and print the data:</p>

<pre><code>void setup() {
  Serial.begin(9600);
  pinMode(30, OUTPUT);
}

void loop() 
  digitalWrite(30, HIGH);

  for (int i = 0; i &lt; 10; i++) {
    int sensorValue = analogRead(i);
    Serial.print(String(i) + ":");
    Serial.println(sensorValue);
  }
}
</code></pre>

<p>The Java code I am using is almost entirely copied from the example provided <a href="http://playground.arduino.cc/Interfacing/Java" rel="nofollow">here</a>, with the exception that I updated the port name to work for my system (Mac OS X 10.10.3).</p>

<p>Here is the Java code:</p>

<pre><code>import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import gnu.io.CommPortIdentifier; 
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent; 
import gnu.io.SerialPortEventListener; 
import java.util.Enumeration;


public class SerialTest implements SerialPortEventListener {

    SerialPort serialPort;

    /** The port we're normally going to use. */
    private static final String PORT_NAMES[] = { 
            "/dev/cu.usbmodem1411",
            "/dev/cu.usbmodem1451",
    };

    /**
    * A BufferedReader which will be fed by a InputStreamReader 
    * converting the bytes into characters 
    * making the displayed results codepage independent
    */
    private BufferedReader input;

    /** The output stream to the port */
    private OutputStream output;

    /** Milliseconds to block while waiting for port open */
    private static final int TIME_OUT = 2000;

    /** Default bits per second for COM port. */
    private static final int DATA_RATE = 9600;

    public void initialize() {
        CommPortIdentifier portId = null;
        Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

        //First, Find an instance of serial port as set in PORT_NAMES.
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
            for (String portName : PORT_NAMES) {
                if (currPortId.getName().equals(portName)) {
                    portId = currPortId;
                    break;
                }
            }
        }
        if (portId == null) {
            System.out.println("Could not find COM port.");
            return;
        }

        try {
            // open serial port, and use class name for the appName.
            serialPort = (SerialPort) portId.open(this.getClass().getName(),
                    TIME_OUT);

            // set port parameters
            serialPort.setSerialPortParams(DATA_RATE,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);

            // open the streams
            input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
            output = serialPort.getOutputStream();

            // add event listeners
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

    /**
     * This should be called when you stop using the port.
     * This will prevent port locking on platforms like Linux.
     */
    public synchronized void close() {
        if (serialPort != null) {
            serialPort.removeEventListener();
            serialPort.close();
        }
    }

    /**
     * Handle an event on the serial port. Read the data and print it.
     */
    public synchronized void serialEvent(SerialPortEvent oEvent) {
        if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                String inputLine=input.readLine();
                System.out.println(inputLine);
            } catch (Exception e) {
                System.err.println(e.toString());
            }
        }
        // Ignore all the other eventTypes, but you should consider the other ones.
    }

    public static void main(String[] args) throws Exception {
        SerialTest main = new SerialTest();
        main.initialize();
        Thread t=new Thread() {
            public void run() {
                //the following line will keep this app alive for 1000 seconds,
                //waiting for events to occur and responding to them (printing incoming messages to console).
                try {Thread.sleep(1000000);} catch (InterruptedException ie) {}
            }
        };
        t.start();
        System.out.println("Started");
    }
}
</code></pre>

<p>All the program does is print out the values of the Arduino serial monitor, yet it takes way longer (8-12 seconds) through Java than it does from the Arduino program itself.</p>

<p>1) Why is this happening?<br>
2) How do I fix it?</p>
 10794: <p>Timing tests show that the Java code lags something like 25 or more seconds behind the input from the Arduino. This can be fixed by changing in the Java code these lines:</p>

<pre><code>       try {
            String inputLine=input.readLine();
            System.out.println(inputLine);
        } catch (Exception e) {
</code></pre>

<p>to:</p>

<pre><code>       try {
            while (input.ready ())
              {
              String inputLine=input.readLine();
              System.out.println(inputLine);
              }
        } catch (Exception e) {
</code></pre>

<p>This extra loop "drains" the input buffer of data in the one serialEvent call, rather than relying upon a serialEvent call per line of data.</p>

<p>I found when testing that the output is now highly responsive, even without a delay on the Arduino side.</p>

<hr>

<p>My other answer of adding a <code>delay</code> call slowed output down enough for the Java app to catch up, but I must admit it isn't the best solution. </p>
