【问题标题】:jSerialComm - SerialPortEvent.getReceivedData() returns null when Arduino Message is receivedjSerialComm - SerialPortEvent.getReceivedData() 在收到 Arduino 消息时返回 null
【发布时间】:2019-11-02 08:00:48
【问题描述】:

我正在用 Java 编写一个程序,用于处理从 Arduino Uno 接收的天气数据。它将数据存储在数据库中并发送到不同的api。

我使用jSerialComm library 来获取数据,这些数据是通过串口从 Arduino 发送的。我正在使用SerialPortEvent,它会在 Arduino 发送任何数据后立即触发(我没有使用InputStream,因为程序中的其他一些东西将不再起作用)。

Java代码:

(在程序的main方法中调用enable())

import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;

public class Arduino implements SerialPortDataListener {

    @Override
    public void enable() {
        SerialPort comPort = SerialPort.getCommPort("COM5");
        System.out.println(comPort.getDescriptivePortName());
        comPort.openPort();
        comPort.setBaudRate(9600);
        comPort.addDataListener(this);
    }

    @Override
    public int getListeningEvents() {
        return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
    }

    @Override
    public void serialEvent(SerialPortEvent event) {
        byte[] newData = event.getReceivedData();
        System.out.println(newData);
    }

}

Arduino 程序:

(现在只是一个简单的测试程序)

void setup() {
 Serial.begin(9600);
}

int i = 0;

void loop() {
  Serial.println(i);
  i++;
  delay(1000);
}

但无论我在做什么,SerialPortEvent.getReceivedData() 方法总是返回 null,而不是 byte[]-Object(它每秒打印一次,因为 Arduino 发送它的数据):

控制台输出:

User-Specified Port
null
null
null 
null
...

我的错误在哪里?

【问题讨论】:

    标签: java arduino


    【解决方案1】:

    在稍微弄乱了你的代码之后,我已经让它工作了。首先,您需要通过将 getListeningEvents 方法更新为以下内容,将事件设置为仅在读取数据时触发:

    @Override
    public int getListeningEvents() {
        return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
    }
    

    然后,您需要通过将 serialEvent 方法更改为以下方式来解释作为字符串返回的字节数组:

    @Override
    public void serialEvent(SerialPortEvent event) {
        byte[] newData = event.getReceivedData();
        System.out.print(new String(newData));
    }
    

    这将打印带有换行符的数字,因为 Arduino 已经在每个数字之后发送换行符。

    【讨论】:

    • 干得好@Kwonunn 的答案。它充满了细节,它包含代码示例,还对所提出的解决方案进行了解释。
    【解决方案2】:

    尝试在serialEvent 方法中获取SerialPortEvent 类型,然后将数据作为流读取,以防事件触发数据准备就绪,首先声明该方法应该可以访问的输入流:

    InputStream inputStream = comPort.getInputStream();
    

    那么serialEvent应该是这样的:

    @Override
    public void serialEvent(SerialPortEvent event) {
    switch(event.getEventType())
    {
      case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
         System.out.println("empty");
         break;
      case SerialPortEvent.DATA_AVAILABLE: 
         try
         {
            byte[] readBuffer = new byte[inputStream.available()];
            while(inputStream.available() > 0)
            {
               int numBytes = inputStream.read(readBuffer);
            }
            totalReadBuffer = readBuffer;
            System.out.print(new String(readBuffer));
         }
         catch(IOException e)
         {
         }
         catch(Exception ex)
         {
            ex.printStackTrace();
         }
         break;
      }
    }
    }
    

    您可以查看Link获取完整代码,请注意用于串行通信的类是SerialPortEventListener,您可以尝试一下

    【讨论】:

      猜你喜欢
      • 2018-04-24
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 2016-01-30
      • 1970-01-01
      相关资源
      最近更新 更多