2012-03-04 48 views
2

我正在研究用Java编写的Arduino记录器。Arduino的Java记录器

我已经利用Arduino的操场示例代码在开始:

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); 
} 

任何建议非常感谢!

回答

1

当您在控制台和文件中编写打印数据时,您不会执行完全相同的操作。您可以在控制台上打印原始数据,所以当您在write()方法中处理数据时,您看不到任何问题,这可能会导致出现一些问题。

问题不在于你的write()方法,而在于你使用它的方式。只要你有一些数据,你打印它。问题是,你可能没有收到所有的数据,所以你打印太早。

这在数据流中很常见:当数据可用时,操作系统会发出警告,但它可能只接收(比方说)Arduino发出警告时发送的5个字节中的3个字节。操作系统本身无法知道您等待5个字节,而不仅仅是3.

因此,您必须存储和连接数据,直到您知道全部收到。两种可能性是:

  • 如果你知道n个字节将被发送,存储数据,直到你收到的n个字节
  • 等待指示数据的最后一个字符标志:我想你使用串口。在Arduino中使用println()方法,这意味着数据的结尾在最后会有“\ r \ n”。顺便说一句,这就是为什么你的打印数据,因为你没有告诉java的,以:-)

的代码创建新的生产线可以更好,但要保持它的简单,因为我不是当有文件中的部分新行确保在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”。它是屏幕上的一种自动连接。

+0

感谢它的完美!我只是想知道什么是“\ r”,我认为“\ n”创建了新的线。 – user1247595 2012-03-04 20:34:19

+0

传统。在旧的机械打字机中,您必须返回到当前行的开头(\ r),然后转到新行(\ n)。在计算机上,新行的编码取决于操作系统:对于windows而言(通常为\“\”\“\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \对于旧的Mac,\ n对于类Unix操作系统。但这是一个惯例。您只能在您的Arduino和电脑之间使用\ n协议,这取决于您。但是默认情况下,使用Serial.println()会添加一个\ r \ n。 – 2012-03-04 21:10:44