问题
I have implmented JSSC API so I can communicate with the Com Port. I send a command like "N\r\n"
and what i receive in a normal hyperterminal should look like this:
0100071CA79215021803164442180000
0100071C9F5415021803164514520000
0100071CDF5115022106142956600000
NOK
But when i do the same with the JSSC API i receive this (only the first code)
010
0071CA79
2150218
0316444
218
The Problem is that i randomly receive bit parts and at the end of the code i lose some parts. But thats not important i only need the first 12 digits of every code.
The Question is now how do i get the function to only receive the full line and not bitparts?
This is the receiving part of the class class PortReader2 implements SerialPortEventListener {
@Override
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR()&& event.getEventValue() > 2) {
try {
// получение ответа от порта
String receivedData = serialPort.readString();
System.out.println(receivedData.length() + ":" + receivedData);
}
catch (SerialPortException ex) {
System.out.println("Error in receiving response from port: " + ex);
}
}
}
}
This is the sending part
public void sendCodeCommand(SerialPort serialPort) {
// writing string to port
try {
Thread.sleep(3000);
serialPort.writeBytes("N\r\n".getBytes());
} catch (SerialPortException | InterruptedException ex) {
Logger.getLogger(ComPortSendReceive.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("String wrote to port, waiting for response..");
}
回答1:
To fix the stated problem you need to concatenate the strings you receive into another string that accumulates the string fragments you receive from the readString() function, which is in the serialEvent handler. Because it is it's owm thread it gets a certain amount of cpu time to get serial data so it effectively gets partial sequential reads of the serial port input data. So this example puts the partial inputs together to create the "whole" input.
String serialString;
So within the serialEvent handler:
try {
serialStringFragment = serialPort.readString();
serialString.concat(serialStringFragment);
}
Either the string you get from readString() or the accumulation string can be scanned for tokens like eol condition. For Example:
String [] dlLines = serialString.split("\r\n");
will break each line out to an element in the dlLines string array.
However I have found that if I have fixed length output from my target device this works better:
serialPort.readString(int bytecount);
inline with the write serial string, eliminating the serialEvent handler.
This is a bit contrived but In other words:
String expectedStringLength "0100071CA79215021803164442180000";
int serialstrlen = expectedStringLength.length();
So the serialstrlen should obviously become constants for each expected line.
serialPort.writeString("N\r\n");
serialPort.readString(serialstrlen+2); // assuming cr lf
should get you the first line.
Put the readString() in a loop, change serialstrelen argument value according to the expected strings. Check the strings for alternate content for error handling. This has worked for me.
来源:https://stackoverflow.com/questions/28691742/read-complete-line-java-serial-port