Fazecast / jSerialComm

Platform-independent serial port access for Java
GNU Lesser General Public License v3.0
1.35k stars 287 forks source link

performance issue #401

Closed quantrpeter closed 2 years ago

quantrpeter commented 2 years ago

Hi. I got a FPGA and loopback the UART, whatever i send to, it send me back. Now i use java to send and receive bytes. I need 9 seconds to receive 100,000 bytes, which is too slow, any hints?

package hk.quantr.javauart;

import com.fazecast.jSerialComm.SerialPort;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 * @author Peter <peter@quantr.hk>
 */
public class JavaUART {

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.s");

    public static void main(String args[]) {
        SerialPort[] ports = SerialPort.getCommPorts();
        for (SerialPort port : ports) {
            System.out.println(port + ", " + port.getSystemPortName() + ", " + port.getSystemPortPath());
        }

        SerialPort comPort = SerialPort.getCommPorts()[0];
        comPort.setBaudRate(115200);
        comPort.setNumDataBits(8);
        comPort.setParity(SerialPort.NO_PARITY);
        comPort.setNumStopBits(SerialPort.ONE_STOP_BIT);
        comPort.openPort();
//      comPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 100, 0);

        System.out.println(sdf.format(new Date()));

        int count = 0;
        StringBuilder str = new StringBuilder();
        try {
            while (true) {
                byte bytes[] = "Peter".getBytes();
                comPort.writeBytes(bytes, bytes.length);
//              while (comPort.bytesAvailable() == 0) {
//                  System.out.println("sleep");
//                  Thread.sleep(20);
//              }
//              comPort.flushIOBuffers();

                byte[] readBuffer = new byte[comPort.bytesAvailable()];
                int numRead = comPort.readBytes(readBuffer, readBuffer.length);
                //System.out.println("Read " + numRead + " bytes.");//
//              for (byte b : readBuffer) {
//                  System.out.print((char) b);
//              }
//              str.append(new String(readBuffer));
                count += numRead;
                if (count >= 100000) {
                    System.out.println(count);
//                  System.out.println(str);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(sdf.format(new Date()));
        comPort.closePort();
    }
}

thanks

hedgecrw commented 2 years ago

Your port setup looks correct to me. One major problem I see if that you aren't doing a 1-to-1 write-then-read implementation. You are writing the string "Peter" (5 bytes), and then immediately reading however many bytes have already been received back at your device (which could easily be 0 or less than 5 bytes). Regardless of however many bytes you've read, you then send the next 5-byte Peter string immediately and then read whatever has been received. So my guess is that you are writing many many more bytes to the FPGA than are being read, but your stop condition is based solely on how many bytes were read. So you might be transmitting 1,000,000 bytes but only reading 100,000.

I would change your code to be read-blocking with a timeout to make sure you fully read what you have written before re-starting the loop. Ex:

...
comPort.openPort();
comPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 100, 0);
...
byte bytes[] = "Peter".getBytes();
comPort.writeBytes(bytes, bytes.length);
int numRead = comPort.readBytes(bytes, bytes.length);
count += numRead;
if (count >= 100000) {
...
hedgecrw commented 2 years ago

Also, re-reading through your original post, I think that transmitting 100,000 bytes of data at 115200 baud rate should take about 9 seconds.

A baud rate of 115200 for a UART is equivalent to 115200 bits per second. Your settings include 8 data bits, one stop bit, and one start bit = 10 bits per symbol, therefore 10 bits are sent for every byte, making the transmission speed 11,520 bytes per second. Transmitting 100,000 bytes at 11,520 bytes/sec should take 8.68 seconds.

hedgecrw commented 2 years ago

Closing as "not a bug." The timing reported is as expected given the baud rate.

quantrpeter commented 2 years ago

thanks all, @hedgecrw is right