Fazecast / jSerialComm

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

Read from interface incomplete #402

Closed cefi1846 closed 2 years ago

cefi1846 commented 2 years ago

I have a problem reading from the serial port. I was able to reproduce the behavior with two different devices.

Whenever I want to read a response from the device via the DataListener or SerialPortDataListener, the response is always incomplete! Usually the first byte is output in an event and then the rest. But it can also be the first two bytes. That can never be said with certainty.

I'm using a USB serial adapter. But the behavior is also the same on a hardware port.

Logcat: USB Serial Port (COM6) Länge: 1 <--- 39 Länge: 19 <--- 38 38 30 34 37 34 39 33 35 37 34 30 37 31 35 39 38 31 39

Please help and regards

Code:

public void enable() throws IOException {
    comPort = SerialPort.getCommPort("COM6");
    System.out.println(comPort.getDescriptivePortName());
    comPort.openPort();
    comPort.setBaudRate(9600);
    comPort.setNumDataBits(8);
    comPort.setNumStopBits(1);
    comPort.setParity(SerialPort.NO_PARITY);
    //comPort.setComPortTimeouts(1, 0, 0);
    comPort.addDataListener(new SerialPortDataListener() {
        private String messages = "";

        @Override
        public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_RECEIVED; }

        @Override
        public void serialEvent(SerialPortEvent event) {
            byte[] eventData = event.getReceivedData();
            System.out.println("Länge: " + eventData.length);

        }
    });
    in = comPort.getInputStream();
    out = comPort.getOutputStream();
}
hedgecrw commented 2 years ago

The behavior you are describing sounds correct. In raw serial, there is no such thing as a "packet" or a "message", just a series of incoming data bytes. As such, your data listener is getting called as soon as the OS/device driver informs the application that there is data ready that can be read. This could be after 1 byte or after 100.

It sounds like you have a response that itself has some sort of protocol (either a fixed-length response or byte-delimited response). If that is the case, you can use either a "PacketListener" or a "MessageListener" to fully receive your data before invoking the callback. Usage for these can be found on the Wiki under "Fixed-Length Data Packet Received" and "Byte- or Multibyte-Delimited Message Received".

cefi1846 commented 2 years ago

Yes that was it! THANK YOU VERY MUCH, IT WORKS PERFECTLY!!