[java] 緩慢的Arduino串行傳輸


Answers

我找到了解決方案。 在這種情況下,jSSC的writeByte函數效率非常低。 如果我預先在Java中的49字節緩衝區,然後立即傳遞給jSSC我得到一個非常大的速度提升。

    byte[] sendBuffer = new byte[49];
    sendBuffer[0] = 'd';

    for (byte i = 0; i < 48; i++) {
      sendBuffer[i + 1] = i;
    }
    port.writeBytes(sendBuffer);

在Arduino論壇的一個成員建議我波特率345600現在給我〜240包/秒(〜12KB /秒)。

Question

我正在測試我的Arduino UNO的串行傳輸速度。 對於我的要求,我必須從主PC傳輸3KB / s到Arduino。 我寫了一個非常簡單的程序,它回答了Serial.available()的結果,然後在Arduino IDE的串口監視器中對其進行了測試。 我已經開始發送字符,直到達到63字節的最大值。 我很驚訝,因為我在某處讀了Arduino有一個128byte的串行緩衝區。

無論如何,我已經組成了一個非常簡單的協議,它以48字節的數據包(實際上是49字節,因為標題字符)傳輸數據。 主機發送一個d字符,然後發送48個字節的數據。 為了測試傳輸的有效性,我發送了一個簡單的從0到47的字節序列,在Arduino端進行驗證。 如果驗證失敗,則UNO開始閃爍PIN13上的板載LED。 一旦字節被發送,主機等待一個簡單的k字符的確認。 Arduino一旦處理完實際的數據包就發送一次。

主機程序測量傳輸的數據包的數量,並在1秒後顯示。 在波特率為9600的情況下,個人電腦能夠成功發送〜16包/秒(〜800字節/秒),這相當不錯。 我試圖通過將雙方的波特率增加到57600來改善這一點; 但是,發送數據包的數量只增加一點點。 我不知道問題是什麼。 也許我打了USB串口轉換器的某種限制?

這是我的代碼。

PC (Java,我使用jSSC進行串口通信)

  package hu.inagy.tapduino.server;

  import jssc.SerialPort;
  import jssc.SerialPortException;

  /**
   * Test Arduino communication.
   */
  public class App
  {

    private static void testComm(SerialPort port) throws SerialPortException {
      long runningSeconds = 0;
      long time = System.currentTimeMillis();
      long numberOfPackets = 0;
      boolean packetSent = false;
      while (runningSeconds < 10) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - time > 1000) {
          runningSeconds++;
          time = currentTime;
          System.out.println(numberOfPackets + " packets/s");
          numberOfPackets = 0;
        }

        if (!packetSent) {
          packetSent = true;
          port.writeByte((byte) 'd');
          for (int i = 0; i < 48; i++) {
            port.writeByte((byte) i);
          }
        } else {
          byte[] received = port.readBytes();
          if (received != null) {
            if (received.length > 1) {
              throw new IllegalStateException("One byte expected, instead got: " + received.length);
            }

            char cmd = (char) received[0];
            if ('k' != cmd) {
              throw new IllegalStateException("Expected response 'k', instead got: " + cmd);
            }
            packetSent = false;
            numberOfPackets++;
          }
        }

      }
    }

    public static void main(String[] args)
    {
      SerialPort port = new SerialPort("COM7");

      try {
        if (!port.openPort()) {
          throw new IllegalStateException("Failed to open port.");
        }
        port.setParams(57600, 8, 1, 0);
      } catch (SerialPortException e) {
        throw new IllegalStateException("Exception while setting up port.", e);
      }

      try {
        // Wait 1.5sec for Arduino to boot successfully.
        Thread.sleep(1500);
      } catch (InterruptedException e) {
        throw new IllegalStateException("Interrupt while waiting?", e);
      }

      try {
        testComm(port);
      } catch (SerialPortException exc) {
        throw new IllegalStateException("Failure while testing communication.", exc);
      } finally {
        try {
          if (!port.closePort()) {
            throw new IllegalStateException("Failed to close port.");
          }
        } catch (SerialPortException e) {
          throw new IllegalStateException("Exception while closing port.", e);
        }
      }
    }
  }

Arduino的

void setup() {
   pinMode(13, OUTPUT);
   Serial.begin(57600);
}

boolean error = false;

void loop() {
  if (error) {
      digitalWrite(13, HIGH);
      delay(1000);
      digitalWrite(13, LOW);
      delay(1000);
  } else {
    while (Serial.available()<49);
    char cmd = Serial.read();
    if ('d'!=cmd) {
       error=true;
       return;
    }

    for (int i=0; i<48; i++) {
       int r = Serial.read();
       if (r!=i) {
         error=true;
         return;
       } 
    }

    Serial.write('k');
  }

}



最近,我使用這個教程通過電纜將Arduino UNO設備連接到PC: Arduino和Java




Related