【发布时间】:2015-04-18 15:41:13
【问题描述】:
这将是我的第一篇文章,我会尽量做到简洁明了。我检查了这个论坛上的其他一些帖子,但找不到满意的答案。
我的问题与 JavaFX 和 jSSC(java 简单串行连接)库的使用有关。我设计了一个非常简单的 GUI 应用程序,它将承载四个不同的图表。其中两个图表将显示过去一小时内温度和太阳能传感器的读数,而另外两个则显示较长时间的数据——14 小时。最终,我想让它更灵活,并在读数大致为零(夜间)时将应用程序设置为“睡眠”。
如何流式传输数据以实时显示这些数据?
在参考了几个在线资源和“JavaFX 8 Intro. by Example”之后,我已经能够构建大部分串行连接类。我在处理数据读数时遇到问题,因此它可以显示在图表上。
public class SerialComm implements SerialPortEventListener {
Date time = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("mm");
boolean connected;
StringBuilder sb;
private SerialPort serialPort;
final StringProperty line = new SimpleStringProperty("");
//Not sure this is necessary
private static final String [] PORT_NAMES = {
"/dev/tty.usbmodem1411", // Mac OS X
"COM11", // Windows
};
//Baud rate of communication transfer with serial device
public static final int DATA_RATE = 9600;
//Create a connection with the serial device
public boolean connect() {
String [] ports = SerialPortList.getPortNames();
//First, Find an instance of serial port as set in PORT_NAMES.
for (String port : ports) {
System.out.print("Ports: " + port);
serialPort = new SerialPort(port);
}
if (serialPort == null) {
System.out.println("Could not find device.");
return false;
}
//Operation to perform is port is found
try {
// open serial port
if(serialPort.openPort()) {
System.out.println("Connected");
// set port parameters
serialPort.setParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex); }
}
});
}
} catch (Exception e) {
System.out.println("ErrOr");
e.printStackTrace();
System.err.println(e.toString());
}
return serialPort != null;
}
@Override
public void serialEvent(SerialPortEvent spe) {
throw new UnsupportedOperationException("Not supported yet.");
}
public StringProperty getLine() {
return line;
}
}
在 try 块中,我了解端口参数,但 eventListener 是我遇到困难的地方。 stringbuilder 的意义在于在从设备读取新数据时附加数据。 如何计算两个传感器读数?我是否可以通过创建单独的数据速率来区分来自每个传感器的传入数据?
我希望这很清楚,并且我提供了足够的信息,但不要太多。感谢您提供任何帮助。
-------------------更新--------------- ------------
自从您回复 Jose 以来,我已经开始对我的代码进行补充。在 JavaFX 类中添加侦听器,我遇到了一些问题。我不断收到 NullPointerException,我认为这是 String[]data 没有被 SerialCommunication 类中的任何数据初始化。
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
} catch (Exception e) {
System.err.println(e.toString());
}
我正在将时间添加到正在读取的数据中。正如 Jose 下面提到的,我在 arduino 代码中的数据变量中添加了标签,我正在使用:Serial.print("Solar:"); Serial.println(solarData);
JavaFx 监听器的粗略代码:
serialPort.getLine().addListener((ov, t, t1) -> {
Platform.runLater(()-> {
String [] data = t1.split(":");
try {
//data[0] is the timestamp
//data[1] will contain the label printed by arduino "Solar: data"
switch (data[1]) {
case "Solar":
data[0].replace("Solar:" , "");
solarSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
case "Temperature":
temperatureSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
}
这段代码出现 NullPointerException 的原因是否是 String [] 数据数组未初始化的结果?
异常错误
端口:/dev/tty.usbmodem1411Connected 线程“EventThread /dev/tty.usbmodem1411”中的异常 java.lang.NullPointerException 在 SerialComm.lambda$connect$0(SerialComm.java:61) 在 SerialComm$$Lambda$1/1661773475.serialEvent(未知来源) 在 jssc.SerialPort$LinuxEventThread.run(SerialPort.java:1299)
【问题讨论】:
-
你能显示异常的堆栈跟踪吗?
-
请编辑您的帖子并在此处添加完整的例外情况。
-
完整的堆栈跟踪包含更多信息,这将有助于跟踪错误。 1299 是哪一行?
-
这就是我无法追踪错误的原因——没有第 1299 行。此外,我不确定如何扩展引发的异常。我查看了其他一些关于如何做到这一点的论坛......我会继续寻找。 sry : /
-
SerialPort 来自 jssc 库:
eventListener.serialEvent(new SerialPortEvent(portName, eventType, eventValue));。 SerialComm 是你的课吗? 61号线?你可以在你的connect()方法中添加一些System.out.println()来检查你在哪一行有NPE。