繁体   English   中英

使用RXTX和Java与串行设备继续通信

[英]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的线程完成。

在原始示例中,您会注意到SerialWriterrun()方法中有一段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();
    }
}

读一本关于并发的好书

并发是棘手的。 您将需要在实践中阅读Java并发

当您尝试剪切'n'paste以上代码示例时,您会注意到Condition#await()抛出InterruptedException 确切的处理方法超出了此答案的范围。 :-) while(true)也有点狡猾。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM