A
A
antonwx2019-12-06 00:57:24
Java
antonwx, 2019-12-06 00:57:24

How to reduce response time on Arduino COM port in Java?

Using this article on Habré as a basis, I wrote a Java test application for transmitting and receiving data to / from Arduino.
Here is the code in full:

package test;

import com.fazecast.jSerialComm.SerialPort;

import arduino.Arduino;

public class test {

  public static void main(String[] args) throws InterruptedException {
        Arduino arduino = new Arduino("COM5", 9600);

        boolean connected = arduino.openConnection();
        System.out.println("Соединение установлено: " + connected);
        Thread.sleep(2000);

        new Reader(arduino).start();
        
        while (true) {
        	Thread.sleep(10);
        	arduino.serialWrite('1');
        }
  }

}

class Reader extends Thread{
  Arduino a;
  public Reader(Arduino a) {
    this.a = a;
  }
  
  @Override
  public void run() {
    try {
      SerialPort comPort = a.getSerialPort();
       while (true)
       {
         long t = System.currentTimeMillis();
          while (comPort.bytesAvailable() == 0)
             Thread.sleep(20);

          byte[] readBuffer = new byte[comPort.bytesAvailable()];
          comPort.readBytes(readBuffer, readBuffer.length);
          System.out.println(new String(readBuffer) + " ms since last read: "+(System.currentTimeMillis()-t));
       }
    } catch (Exception e) { e.printStackTrace(); }
  }
}

And also the Arduino code:
void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() != 0) {  
    byte b = Serial.read();
    Serial.print("Received byte: ");
    Serial.println(b);
  }
}

In essence, in the loop, the program simply sends data to the arduino as fast as it can while another thread reads data from the port. The problem is that there are very few transfers per second: for some reason, there is a very large delay between calling arduino.serialWrite('1'); and the actual reception of data on the arduino. Moreover, the problem is precisely in the Java software part, since if you open the Serial monitor from the Arduino IDE, then the delay is extremely small, and you can definitely transfer 20 times per second. What is the problem?
5de97d7174b11585409233.png

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
antonwx, 2019-12-06
@antonwx

In general, the category of questions of the level "he asked - he answered."
I found the code responsible for sending data to arduino:

public void serialWrite(char c){
    //writes the entire string at once.
    comPort.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
    try{Thread.sleep(5);} catch(Exception e){}
    PrintWriter pout = new PrintWriter(comPort.getOutputStream());pout.write(c);
    pout.flush();
  }

deleted it and wrote like this:
public void serialWrite(char c){
    byte[] b = {(byte)c};
    comPort.writeBytes(b, b.length);
  }

I don't know if it's correct, but it works as it should. Guru, tell me how true this decision is.

V
vanyamba-electronics, 2019-12-06
@vanyamba-electronics

When outputting data to a terminal via a COM port, caching is applied everywhere, since the computer cannot wait that long, outputting character by character to a slow COM port.
The caching algorithm, in turn, outputs the data line by line. That is, it sends data to the terminal only after receiving the '\n' character.
To send data immediately, you need to call the flush() function.

E
evgeniy_lm, 2019-12-06
@evgeniy_lm

change 9600 to 115200 and you will be happy

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question