我正在开发一个Java软件,它必须能够通过串行COM端口读取设备发送的一些数据,通信速度对我来说非常重要,因此波特率设置为921600。 在开始时一切正常(因此它读取设备通过串行端口发送的正确数据)但是一段时间后软件开始读取错误的数据。 看起来软件太慢了,它们进入输入缓冲区时可能会丢失一些数据(可能是第一次完全填充输入缓冲区时)。 为了加快读取操作,我目前正在使用一种读取方法,其中软件每次读取处理尽可能多的字节。 我也尝试使输入缓冲区大小更大(通过使用serialPort.setInputBufferSize(byte)方法,但它没有解决我的问题) 那么有没有人用java进行快速串行通信?我错过了什么吗? 为什么一切都运行良好一段时间然后停止正常工作?
这是我的阅读部分代码(甚至是驱动),请跳过数据转换的部分,这只是因为每个数据实际上都是由2个字节组成的,因此我还必须在将它们写入a之前将它们组合起来。 txt文件。
/**
*
* @param evt
*/
@Override
public void serialEvent(SerialPortEvent evt) {
switch(evt.getEventType()) {
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
System.out.println("THE OUTPUT BUFFER IS EMPTY");
break;
case SerialPortEvent.DATA_AVAILABLE:
try {
while(SerialPortEvent.DATA_AVAILABLE == 1) {
num_bytes = input.available();
array = new byte[num_bytes];
bytes_read = input.read(array, 0, num_bytes);
dato = new short[bytes_read];
datoc = new int[bytes_read/2];
datos = new String[bytes_read/2];
for(j=0;j<bytes_read;j++){
dato[j] = (short) (((byte) array[j]) & 0xff);
}
k = 0;
for(j=0;j<(bytes_read/2);j++){
datoc[j] = dato[k];
datoc[j] = (datoc[j]<<8) + dato[k+1];
datoc[j] = datoc[j] & 0xffffffff;
k = k + 2;
}
for(j=0;j<(bytes_read/2);j++){
System.out.println(datoc[j]);
datos[j] = Integer.toString(datoc[j]);
output1.write(datos[j] + " ");
}
}
} catch(IOException ex) {
logText = "Failed to read data. (" + ex.toString() + ")";
System.out.println(logText);
}
break;
}
答案 0 :(得分:0)
听起来您的程序无法足够快地为传入数据提供服务;它会工作一段时间,因为输入进入缓冲区,当你清空缓冲区时,有更多空间可以输入更多内容。但是如果数据的传输速度比你整体处理的速度要快,那么最终你的缓冲区已经满了,数据仍然存在且无处可去。在串行通信中,这种数据通常被转储到(虚拟)楼层。
通常设置状态指示“缓冲区溢出”。我要检查的第一件事是,您在用于读取串行数据的任何库中是否可以使用此状态,并查看是否/何时设置它。这将验证上述情况正在发生。
要检查的另一件事是,在您的环境中是否合理,是XON / XOFF功能。这是/是某些串行通信的一个特征,允许接收器向发送器指示其缓冲区几乎已满并停止发送(XOFF),直到告知它可以再次开始(XON)。并非所有硬件和软件都支持此功能。
如果由于某种原因无法正常工作,这确实是问题所在,那么您将不得不更好地处理数据或更快地缓存数据。一种简单的暴力方法是在存入字节时将字节写入存储,并在单独的线程中读取它们。例如,如果这是传统的计算机系统,您可以将它们写入磁盘,然后处理磁盘文件,打开它以便在一个线程中读取并在另一个线程中写入(有趣的是!)。
答案 1 :(得分:0)
正在减慢串行通信的是使用System.out.println()
。没有它,数据接收最终得到了很好的