我正在研究用 Java 编写的 Arduino 记录器。
我已经开始使用来自 Arduino Playground 的示例代码:
http://arduino.cc/playground/Interfacing/Java
我认为我的问题在这里:
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
int available = input.available();
byte chunk[] = new byte[available];
input.read(chunk, 0, available);
// Displayed results are codepage dependent
String print = new String(chunk);
test.write(print);
System.out.print(print);
} catch (Exception e) {
System.err.println(e.toString());
}
我编写了一个将数据写入 csv 文件的类。当它将数据打印到控制台时,它是完美的。当我将它写入文件时,我得到了一些完美的线条,有时还有一些糟糕的线条,例如:
60
4
5
28
我希望它像这样打印:
604
528
我的写法是:
public void write(String print)
{
pw.print(System.currentTimeMillis());
pw.print(",");
pw.println(print);
}
非常感谢任何建议!!
最佳答案
当您在控制台和文件中编写打印数据时,您做的事情并不完全相同。您在控制台上打印原始数据,因此您看不到任何问题,而您在 write() 方法中处理数据时可能会出现一些问题。
问题不在于您的 write() 方法,而在于您使用它的方式。一旦你有了一些数据,你就打印它。问题是,您可能还没有收到所有数据,所以打印得太早了。
这在数据流中很常见:操作系统会在数据可用时警告您,但它可能只收到(比方说)Arduino 在警告您时发送的 5 个字节中的 3 个字节。操作系统自己无法知道您正在等待 5 个字节,而不仅仅是 3 个字节。
因此您必须存储和连接您的数据,直到您知道所有数据都已收到。两种可能性:
- 如果您知道将发送 n 个字节,请存储数据直到您收到 n 个字节
- 等待指示数据结束的字符标志:我想您在 Arduino 中使用了 Serial.println() 方法,这意味着您的数据末尾将有“\r\n”。顺便说一下,这就是为什么在打印数据时你的文件中有一些新行,因为你没有告诉 Jave 创建新行:-)
代码可能会更好,但为了保持简单,因为我不确定你的 Java 水平,为了保持你的代码,你可以做类似的事情(警告,我没有测试它):
// Should be outside of your serialEvent method
StringBuilder buffer = new StringBuilder();
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
int available = input.available();
byte chunk[] = new byte[available];
input.read(chunk, 0, available);
// We store data in a buffer
buffer.append(new String(chunk));
// We check if we received the characters indicating
// the end of your data
int endOfLineIndex = buffer.indexOf("\r\n");
// We don't, so we leave and wait for more data
if (endOfLineIndex == -1) {
return;
}
// The "+2" is to keep the "\r\n"
String print = buffer.substring(0, endOfLineIndex+2);
// Do not forget to remove what was used in the buffer
buffer.delete(0, endOfLineIndex+2);
test.write(print);
System.out.print(print);
} catch (Exception e) {
System.err.println(e.toString());
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
顺便说一句,如果您在控制台中直接打印数据时没有发现任何问题,那是因为换行字符来自 Arduino 而不是 Java 代码。所以你打印了一个完整的数据流,因为你在屏幕上打印的字符之间没有插入任何内容。在您的示例中,您首先收到“60”,然后收到“4\r\n”。它是一种屏幕上的自动连接。
关于Arduino 的 Java 记录器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9551726/