【问题标题】:Serial Communication Errors: IllegalStateException & IOException串行通信错误:IllegalStateException & IOException
【发布时间】:2017-04-21 18:11:10
【问题描述】:

我有一个连接到 USB 设备的程序,USB 设备是一种消费产品,使用他们的软件和 PuttY 可以正常工作,这是一个相当简单的使用字符串的串行通信。 (根据他们的文档)。

我的一些代码有问题,特别是在尝试使用 读取字符串而不只是显示它时 我会尽量弄清楚发生了什么:

  1. 首先,软件会扫描可用的 COM 端口(有效),然后 填充列表
  2. 其次,用户选择一个 COM 端口并连接到它(这可行),打开 COM 端口,并初始化一个侦听器和一个 I/O 流
  3. 第三个事件监听器不断更新用户可见的日志与正在接收的数据(这工作正常 好)

但是!有一个开始执行测试的按钮,该测试启用布尔“testinprogress”,使侦听器对可用数据执行不同的任务,以显示正在读取的内容。

这里是事件监听器的代码:

@Override
public void serialEvent(SerialPortEvent evt) {
    BufferedReader reader = null;

    if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
    {
        if (testProgress == true)
        {
             try
            {
                reader = new BufferedReader(new InputStreamReader(input));
                TemperatureParser parser = new TemperatureParser();
                TemperatureReading reading;
                output.flush();
                reading = parser.parse(reader.readLine());
                readings.add(reading);
                textLog.appendText(reader.readLine() + "\n");
            }
            catch (Exception e)
            {
            statusLabel.setText("@serialEvent.IF Failed to read data. (" + e.toString() + ")");
            System.out.println("@SerialEvent.IF Failed to read data. (" + e.toString() + ")");
            }
        }
        else
        {
            try
        {
            reader = new BufferedReader(new InputStreamReader(input));
                fullLine = reader.readLine();
                textLog.appendText(fullLine + "\n");
        }
        catch (Exception e)
        {
            statusLabel.setText("@serialEvent.ELSE Failed to read data. (" + e.toString() + ")");
            System.out.println("@SerialEvent.ELSE Failed to read data. (" + e.toString() + ")");
        }
        }
    }
}

现在,问题来了,如果我注释掉以下几行,读取然后显示的东西可以正常工作:

            reading = parser.parse(reader.readLine());
            readings.add(reading);

这两行与为该项目创建的特殊类有关(感谢 James_D):

//SPECIAL CLASSES NEEDED
    public class TemperatureReading {
        private final double[] values;
        private final LocalDateTime timeStamp;

        public TemperatureReading(LocalDateTime timeStamp, double... values) {
            this.timeStamp = timeStamp;
            this.values = new double[values.length];
            System.arraycopy(values, 0, this.values, 0, values.length);
        }

        public TemperatureReading(double... values){
            this(LocalDateTime.now(), values);
        }

        public double getValue(int channel) {
            return values[channel];
        }

        public int getNumberOfChannels() {
            return values.length;
        }

        public LocalDateTime getTimestamp(){
            return timeStamp;
        }

        public boolean noneExceed(double max) {
            return DoubleStream.of(values).allMatch(v -> v <= max);
        }
    }

    public class TemperatureParser {
        public TemperatureReading parse (String text) {
            return new TemperatureReading(Stream.of(text.split(SPLIT)).mapToDouble(Double::parseDouble).toArray());
        }
    }

最后,当这些行没有被注释掉时我得到的错误

OLD ERROR MESSAGES. SEE EDIT

另一个可能与此相关或无关的注意事项是,有时缓冲区读取器不会读取整行,这是我得到的一些输出(这些行被注释掉并且没有错误)

Setting testInProgress to true 
 24.552  24.505  24.515  24.413  
24.457  24.435  24.354  24.433  24.510  24.553  24.506  24.515  24.413  
24.458  24.435  24.355  24.433  24.511  24.554  24.507  24.515  24.413  
24.458  24.436  24.355  24.433  24.511  24.554  24.507  24.515  24.413  
Test stopped by user! 
OK

现在您看到,在 testInProgress 设置为 true 后,第一行是 INCOMPLETE(应该是 9 个读数)。我只得到了上一行的部分后半部分,我不知道这是否可能是原因,但即便如此,它们仍然应该能够被解析。

编辑
我修改代码如下:

public class TemperatureParser {
    public TemperatureReading parse (String text) {
        System.out.println("String received: " + text);
        if (text != null && text.length() > 0)
        {
        return new TemperatureReading(Stream.of(text.split(SPLIT)).mapToDouble(Double::parseDouble).toArray());
        }
        else
        {
        System.out.println("Null reading");
        return null;
        }
    }
}

这至少让我知道解析器正在获取完整的字符串行并且它正在工作。还对事件监听器进行了如下修改:(添加了对 72 个字符的检查,即 9 个读数)

if (testProgress == true)
            {
                 try
                {
                    reader = new BufferedReader(new InputStreamReader(input));
                    fullLine = reader.readLine();
                    if (fullLine.length() == 72)
                    {
                        textLog.appendText(fullLine + "\n");
                        reading = parser.parse(fullLine);
                        readings.add(reading);

                    }

                }
                catch (Exception e)
                {
                statusLabel.setText("@serialEvent.IF Failed to read data. (" + e.toString() + ")");
                System.out.println("@SerialEvent.IF Failed to read data. (" + e.toString() + ")");
                }

有了这个新代码,我得到的错误更少,所以我认为我在正确的轨道上:

testProgress is True
String received: 25.360  25.371  25.254  25.342  25.545  25.609  25.501  25.527  25.444  
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
    at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
    at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
    at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
    at com.sun.javafx.scene.control.skin.LabelSkin.handleControlPropertyChanged(LabelSkin.java:49)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
    at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
    at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
    at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
    at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
    at javafx.scene.control.Labeled.setText(Labeled.java:145)
    at at.qcresponsetime.FXMLDocumentController.serialEvent(FXMLDocumentController.java:602)
    at gnu.io.RXTXPort.sendEvent(RXTXPort.java:772)
    at gnu.io.RXTXPort.eventLoop(Native Method)
    at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1641)
String received: 25.362  25.371  25.255  25.346  25.547  25.608  25.498  25.527  25.446  
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
String received: 25.363  25.371  25.256  25.350  25.548  25.607  25.495  25.526  25.448  
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
String received: 25.365  25.371  25.257  25.355  25.550  25.607  25.493  25.526  25.450  
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
String received: 25.365  25.371  25.258  25.355  25.550  25.607  25.493  25.526  25.450  
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
String received: 25.365  25.372  25.258  25.355  25.550  25.607  25.493  25.527  25.450  
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
String received: 25.365  25.372  25.258  25.355  25.550  25.607  25.494  25.527  25.450  
@SerialEvent.IF Failed to read data. (java.lang.NumberFormatException: empty String)
testProgress is False
Stop Button pressed!

【问题讨论】:

    标签: java netbeans javafx


    【解决方案1】:

    您正在收到NumberFormatException。这意味着您正在尝试将字符串解析为整数,并且在此过程中存在某种错误。我最好的猜测是变量 fullLine 给你一个空字符串,所以尝试添加一个 if 环绕:

    reading = parser.parse(fullLine);
    readings.add(reading);
    

    检查fullLine 是否为空,除了检查它的长度。 据我所知,错误告诉您字符串为空,因此只需在代码的不同位置测试打印该变量即可。

    【讨论】:

    • 我确实试过了,如果你查看输出代码和源代码,我有一个 System.out.println "String Received: xxxxx" 基本上在那里我检查我是否收到了一个字符串那不是空的,也不是空的。但是由于某种原因,我仍然会收到该错误
    猜你喜欢
    • 2011-07-03
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多