【问题标题】:Serial Communication between Java RXTX and ArduinoJava RXTX 和 Arduino 之间的串行通信
【发布时间】:2010-01-05 21:21:48
【问题描述】:

我正在尝试使用串行端口在我的 PC(使用 Netbeans 和 RXTX 的 Windows 7)与 Arduino Pro 之间进行通信。 Arduino 实际上是使用 FTDI 电缆连接到 PC 的。

代码基于Java SimpleRead.Java找到here.

目前,Arduino 只是在启动时打印出一个字符串。我的 Java 程序应该打印已读取的字节数,然后打印出内容。 Java 程序可以工作,有点……

如果字符串很长(>10 字节左右),输出将被分解。

所以如果我在 Arduino 上打印

Serial.println("123456789123456789"); //20 bytes including '\r' and '\n'

我的 Java 程序的输出可能类似于:

Number of Bytes: 15   
1234567891234  
Number of Bytes: 5  
56789

Number of Bytes: 12   
1234567891  
Number of Bytes: 8  
23456789

我认为这是一个时间问题,因为当我使用调试器手动检查代码时,结果字符串始终是它应该是的:一个 20 字节的字符串。

我一直在搞砸各种事情,但我无法解决问题。

这是给我带来问题的代码部分:

static int baudrate = 9600,
           dataBits = SerialPort.DATABITS_8,
           stopBits = SerialPort.STOPBITS_1,
           parity   = SerialPort.PARITY_NONE;    

byte[] readBuffer = new byte[128];

...
...

public void serialEvent(SerialPortEvent event)
{
   if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {

    try {
        if (input.available() > 0) { 
            //Read the InputStream and return the number of bytes read
            numBytes = input.read(readBuffer);

            String result  = new String(readBuffer,0,numBytes);
            System.out.println("Number of Bytes: " + numBytes);
            System.out.println(result);
        }
    } catch (IOException e) {
        System.out.println("Data Available Exception");
    }
}

【问题讨论】:

    标签: java serial-port arduino rxtx


    【解决方案1】:

    串行数据只是一个数据流。根据您读取它的时间和正在发生的缓冲,您读取它时可能只有部分数据可用。

    由于您使用的是面向行的数据,您需要做的是缓冲数据,直到您看到行终止符,然后才处理数据。

    【讨论】:

    • 出于某种原因,我假设数据将在单个流中连续发送。在 PC 端,我只需要查看 Serial 输出,所以我认为我不会费心尝试存储完整的输入线路然后显示它。我想我只会在数据进入时逐字节显示数据。所以我将使用 aByte = input.read();而不是 input.read(readBuffer);谢谢
    • @SharpBarb - 无需切换到一次读取一个字节。如果您真的想这样做,我建议您读取一个缓冲区,然后在您的应用程序中单独处理每个字节。
    【解决方案2】:

    我没有使用过 Java RXTX,但我使用过 Arduino 和 Processing,从 Arduino 读取/写入值非常容易。 这是处理附带的读取示例(文件>示例>库>串行> SimpleRead)

    /**
     * Simple Read
     * 
     * Read data from the serial port and change the color of a rectangle
     * when a switch connected to a Wiring or Arduino board is pressed and released.
     * This example works with the Wiring / Arduino program that follows below.
     */
    
    
    import processing.serial.*;
    
    Serial myPort;  // Create object from Serial class
    int val;      // Data received from the serial port
    
    void setup() 
    {
      size(200, 200);
      // I know that the first port in the serial list on my mac
      // is always my  FTDI adaptor, so I open Serial.list()[0].
      // On Windows machines, this generally opens COM1.
      // Open whatever port is the one you're using.
      String portName = Serial.list()[0];
      myPort = new Serial(this, portName, 9600);
    }
    
    void draw()
    {
      if ( myPort.available() > 0) {  // If data is available,
        val = myPort.read();         // read it and store it in val
      }
      background(255);             // Set background to white
      if (val == 0) {              // If the serial value is 0,
        fill(0);                   // set fill to black
      } 
      else {                       // If the serial value is not 0,
        fill(204);                 // set fill to light gray
      }
      rect(50, 50, 100, 100);
    }
    
    
    
    /*
    
    // Wiring / Arduino Code
    // Code for sensing a switch status and writing the value to the serial port.
    
    int switchPin = 4;                       // Switch connected to pin 4
    
    void setup() {
      pinMode(switchPin, INPUT);             // Set pin 0 as an input
      Serial.begin(9600);                    // Start serial communication at 9600 bps
    }
    
    void loop() {
      if (digitalRead(switchPin) == HIGH) {  // If switch is ON,
        Serial.print(1, BYTE);               // send 1 to Processing
      } else {                               // If the switch is not ON,
        Serial.print(0, BYTE);               // send 0 to Processing
      }
      delay(100);                            // Wait 100 milliseconds
    }
    
    */
    

    据我所知,当您实例化 Serial 时,您在 Arduino 中设置的波特率非常重要。比如你用9600发送,你应该用同一个号码来收听。

    另外,以 BYTE 的形式发送您的信息也很重要,否则您会遇到 \r 或 \n 之类的内容。

    短版,试试:

    Serial.println(123456789123456789,BYTE);
    

    越简单越好。

    【讨论】:

    • 您好,没有 Papplet 可以处理吗?因为我尝试与我的 java 代码集成...
    • 感谢您的回复,@geory 假设我想从 arduino 获得模拟输入,每当我向 arduino 发送一些东西时,arduino 都会回复模拟值。根据链接中的代码,它只会打印出东西而不是将其保存在变量中,我如何将块存储到变量中?因为 public synchronized void serialEvent 不能返回值,我认为 ...
    • @wizztjh 这在我的脑海中,但你有这段代码: byte chunk[] = new byte[available]; input.read(chunk, 0, 可用); ...之后,日期以字节存储,您应该能够使块变量对类可见,而不仅仅是该块。如果 new 需要一个字符串,您可以创建一个类变量并将其值设置为 new String(chunk) 在 input.read 部分之后。 HTH
    【解决方案3】:

    我认为您需要使用事件驱动的设计模式来解决这个问题。我强烈建议您访问:http://www.whatisarduino.org/bin/Tutorials/Java+Serial+API+and+Arduino

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多