用Java读取串口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/336714/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading serial port in Java
提问by
I'm beginner in Java. I'm reading data from device through serial port. I'm getting data for every one minute, but first reading is coming half, after that data is coming correctly.
我是 Java 初学者。我正在通过串口从设备读取数据。我每一分钟获取一次数据,但在数据正确输入之后,第一次读取就到了一半。
Output I'm getting is:
我得到的输出是:
6050.003120815340006050.003120815350006050.0
6050.003120815340006050.003120815350006050.0
Correct output should be like this:
正确的输出应该是这样的:
03120815340006050.003120815350006050.0
03120815340006050.003120815350006050.0
My code is:
我的代码是:
import java.io.*;
import java.util.*; //import gnu.io.*;
import javax.comm.*;
public class SimpleRead implements Runnable, SerialPortEventListener {
static CommPortIdentifier portId;
static Enumeration portList;
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
byte[] readBuffer;
public static void main(String[] args) {
portList = CommPortIdentifier.getPortIdentifiers();
System.out.println("portList... " + portList);
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
System.out.println("port identified is Serial.. "
+ portId.getPortType());
if (portId.getName().equals("COM2")) {
System.out.println("port identified is COM2.. "
+ portId.getName());
// if (portId.getName().equals("/dev/term/a")) {
SimpleRead reader = new SimpleRead();
} else {
System.out.println("unable to open port");
}
}
}
}
public SimpleRead() {
try {
System.out.println("In SimpleRead() contructor");
serialPort = (SerialPort) portId.open("SimpleReadApp1111",500);
System.out.println(" Serial Port.. " + serialPort);
} catch (PortInUseException e) {
System.out.println("Port in use Exception");
}
try {
inputStream = serialPort.getInputStream();
System.out.println(" Input Stream... " + inputStream);
} catch (IOException e) {
System.out.println("IO Exception");
}
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
System.out.println("Tooo many Listener exception");
}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
// no handshaking or other flow control
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
// timer on any read of the serial port
serialPort.enableReceiveTimeout(500);
System.out.println("................");
} catch (UnsupportedCommOperationException e) {
System.out.println("UnSupported comm operation");
}
readThread = new Thread(this);
readThread.start();
}
public void run() {
try {
System.out.println("In run() function ");
Thread.sleep(500);
// System.out.println();
} catch (InterruptedException e) {
System.out.println("Interrupted Exception in run() method");
}
}
public void serialEvent(SerialPortEvent event) {
// System.out.println("In Serial Event function().. " + event +
// event.getEventType());
switch (event.getEventType()) {
/*
* case SerialPortEvent.BI: case SerialPortEvent.OE: case
* SerialPortEvent.FE: case SerialPortEvent.PE: case SerialPortEvent.CD:
* case SerialPortEvent.CTS: case SerialPortEvent.DSR: case
* SerialPortEvent.RI: case SerialPortEvent.OUTPUT_BUFFER_EMPTY: break;
*/
case SerialPortEvent.DATA_AVAILABLE:
readBuffer = new byte[8];
try {
while (inputStream.available()>0) {
int numBytes = inputStream.read(readBuffer);
// System.out.println("Number of bytes read " + numBytes);
}
System.out.print(new String(readBuffer));
} catch (IOException e) {
System.out.println("IO Exception in SerialEvent()");
}
break;
}
// System.out.println();
/* String one = new String(readBuffer);
char two = one.charAt(0);
System.out.println("Character at three: " + two);*/
}
}
回答by Aaron Digulla
This looks as if you were reading the rest of some message which was sent before you started.
这看起来好像您正在阅读一些在您开始之前发送的消息的其余部分。
Try to read as much data as possible as you start the program to clear any hardware buffers. After that, start your processing.
尝试在启动程序时读取尽可能多的数据以清除所有硬件缓冲区。之后,开始处理。
回答by unwind
Try flushing the input buffer of the port before doing your read. Otherwise, if the sending end has sent data during your program's startup (or closely before, that might be up to the operating system), you will get old buffered data.
在读取之前尝试刷新端口的输入缓冲区。否则,如果发送端在您的程序启动期间(或之前,这可能取决于操作系统)发送了数据,您将获得旧的缓冲数据。
Also, if possible, consider adding message framingto the protocol, so you can detect when you have read something that is not, in fact, a complete message, and discard it. This is often very helpful with these kinds of issues.
此外,如果可能,请考虑将消息帧添加到协议中,这样您就可以检测何时阅读了实际上并非完整消息的内容,并将其丢弃。这通常对此类问题非常有帮助。
回答by kgiannakakis
Use the following:
使用以下内容:
while (inputStream.available()>0) {
int numBytes = inputStream.read(readBuffer);
System.out.print(new String(readBuffer));
}
You are printing the result out of the while loop. However the code inside the loop may run more than once, so chunk of data will be lost.
您正在从 while 循环中打印结果。然而,循环内的代码可能会运行多次,因此会丢失大量数据。