gpt4 book ai didi

java rxtx SerialWriter问题

转载 作者:太空宇宙 更新时间:2023-11-04 07:14:28 25 4
gpt4 key购买 nike

我正在使用 RXTX 在 JAVA 和微 Controller 之间进行通信。

这是打开连接、发送和接收数据的JAVA代码

package app;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class SerialCommunication1 {
private static SerialCommunication1 instance = null;
private static boolean coonected = false;

public static SerialCommunication1 getInstance(){
if(instance == null)
instance = new SerialCommunication1();
return instance;
}

private SerialCommunication1() {
super();
try {
connect("COM4");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SerialCommunication1.coonected = true;
}

void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier
.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
CommPort commPort = portIdentifier.open(this.getClass().getName(),
2000);

if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);

InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();

(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();

} else {
System.out
.println("Error: Only serial ports are handled by this example.");
}
}
}

/** */
public static class SerialReader implements Runnable {
InputStream in;

public SerialReader(InputStream in) {
this.in = in;
}

public void run() {
byte[] buffer = new byte[1024];
int len = -1;
try {
while ((len = this.in.read(buffer)) > -1) {
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

/** */
public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null;

public SerialWriter(OutputStream out) {
this.out = out;
}

public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0){
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

这是事件触发时调用的 Java 代码

SerialCommunication1.getInstance();
if(ledStatus == true) {SerialCommunication1.SerialWriter.str = "4A01";}
else {SerialCommunication1.SerialWriter.str = "4A00";}
stopProcess();

现在问题来了。我需要使用代码 4A01 向我的微 Controller 发送命令,收到答案后,我需要使用代码 4A00 再次调用它。这些调用是由我的 Java 界面中的按钮触发的。问题是第二个调用没有执行(4A00没有发送)。我尝试反转命令代码,效果很好。第一个(4A01)执行后,我的微 Controller 使用react并发送由java读取的响应,并且我的界面被更新。当我发送 invers 命令 (4A00) 时,它恰好停在这一行 SerialCommunication1.SerialWriter.str = "4A00"; 上,甚至没有进入 SerialWriter 的 run() 方法。

您知道为什么会发生这种情况吗?从我的微 Controller 方面来看没有问题,我用工具检查了所有可能性。

我希望我已经说清楚了。

谢谢!

LE:我忘了告诉你它没有抛出任何错误或异常

最佳答案

我不确定,因为我无法测试您的代码,但我认为您的问题出在 SerialWriter 类中:

public static class SerialWriter implements Runnable {
OutputStream out;
static String str = null; // Here str is initialized to null

public SerialWriter(OutputStream out) {
this.out = out;
}

public void run() {
System.out.println("Will try to execute");
try {
if(str.length() > 0) { // this should throw NPE because str is null
this.out.write(str.getBytes());
str = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

由于此方法中没有循环,因此在 SerialCommunication1 的这一行中创建的线程:

(new Thread(new SerialWriter(out))).start();

很可能在发送第一个 str 后完成执行。

老实说,我不明白它是如何发送单个字符串的,因为 str 首先被初始化为 null,并且它应该在 str.length() 行抛出 NullPointerException

我建议您采用这种方法:

  • 建立连接时不触发写入线程,只需在每次发送消息时触发一个新线程。
  • 正确使用单例模式。
  • SerialCommunication1 类中保留对串行端口的引用。

翻译成代码会是这样的:

class SerialWriter implements Runnable {
OutputStream out;
String message;

public SerialWriter(OutputStream out) {
this.out = out;
}

public void setMessage(String msg) {
this.message = msg;
}

public void run() {
try {
if(message != null) {
this.out.write(str.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

然后在SerialCommunication1类中添加这个公共(public)方法:

public void sendMessage(String msg) {
SerialWriter writer = new SerialWriter(serialPort.getOutputStream()); // of course you'll have to keep reference to serialPort when connection is established
writer.setMessage(msg);
(new Thread(writer)).start();
}

最后以这种方式调用这个方法:

SerialCommunication1.getInstance().sendMessage("4A01");

关于java rxtx SerialWriter问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20168274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com