[英]continuing communication with serial device using RXTX and Java
我需要修改RXTX“基于事件的双向通信”(请参阅http://rxtx.qbang.org/wiki/index.php/Event_based_two_way_Communication ),以便能够将有关其内容的特定响应写回串行设备上一条消息。
我通过发送第一个命令开始通信。 到目前为止一切正常。 现在我从串行设备得到了答案。 我用另一个命令对答案做出反应。 但是我不能再写了,因为写线程已经结束了。
有人知道如何处理吗? 非常感谢!
public class TwoWaySerialComm {
public TwoWaySerialComm() {
super();
}
public static void main(String[] args) {
try {
// 0. call connect()
(new TwoWaySerialComm()).connect("COM1");
} catch (Exception e) {
e.printStackTrace();
}
}
void connect(String portName) throws Exception {
// 1. get CommPortIdentifier, open etc...
// 2. then do
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
// 4. start writer thread
(new Thread(new SerialWriter(out))).start();
// 5. instantiate SerialReader
serialPort.addEventListener(new SerialReader(in));
serialPort.notifyOnDataAvailable(true);
}
public static class SerialWriter implements Runnable {
OutputStream out;
public SerialWriter(OutputStream out) {
this.out = out;
}
public void run() {
try {
// establish a communication by sending the first command. the serial device will answer!
String toSend = "blablabla";
this.out.write(toSend);
// thread ended???
}
public static class SerialReader implements SerialPortEventListener {
private InputStream in;
public SerialReader(InputStream in) {
this.in = in;
}
public void serialEvent(SerialPortEvent arg0) {
// event occurs beacause device answers after writing.
int data;
try {
StringBuffer sb = new StringBuffer();
String LineOfData=null;
while ((data = in.read()) > -1) {
if (data == '\n') {
break;
}
sb.append(Integer.toHexString(data));
LineOfData = sb.toString();
}
// I store the answer and send it to an EventIterpreter. Regarding the answer, it creates an appropriate response itselves.
EventInterpreter e = new EventInterpreter(LineOfData);
String result = e.getData
HERE >> // Now I want to send this response back to the device. But the thread is already ended.
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
}
在原始示例中,您会注意到SerialWriter
的run()
方法中有一段while (System.in.read() != -1)
。 那很重要 运行它的线程在read()
上阻塞 ,然后,一旦有一些要读取的数据,它将执行一些工作,然后循环回到同一位置,等待更多输入。 这是正常情况下不应该完成的线程。
至关重要的是,编写器的非守护程序线程正在运行这一事实意味着,当您的主线程(JVM用于启动程序的线程)用尽connect()方法中的语句时,JVM不会立即关闭。
当serialPort
调用侦听器的public void serialEvent(SerialPortEvent)
方法时, 它会在自己的线程上执行此操作 。
现在您的任务是尽可能快地摆脱serialPort的线程 。 差不多,读取数据,将其粘贴在缓冲区中,您的另一个线程可以解析并在空闲时对其进行操作,同时让serialPort继续处理通讯。 当它在自己的线程上调用您时,您当然不应该尝试写入串行端口。 它没有等待您的回复,因为它在等待您完成!
您可以通过提供“锁定”对象来进行安排。 既然是现代,请使用:
import java.util.concurrent.locks.*;
// accessible to both reader and writer
...
Lock lock = new ReentrantLock();
Condition dataAvailable = lock.newCondition();
byte[] buffer;
// in the writer
...
public void run() {
while(true) {
lock.lock();
try {
dataAvailable.await(); // writer thread dozes
doStuff(buffer);
} finally {
lock.unlock();
}
}
}
// in the reader
...
public void onEvent() {
lock.lock();
try {
buffer = readData();
dataAvailable.signal(); // writer thread wakes up
} finally {
lock.unlock();
}
}
当您尝试剪切'n'paste以上代码示例时,您会注意到Condition#await()
抛出InterruptedException
。 确切的处理方法超出了此答案的范围。 :-) while(true)
也有点狡猾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.