簡體   English   中英

Arduino / Android藍牙延遲

[英]Arduino/Android Bluetooth delay

我們正在開發一個應用程序,該應用程序使用藍牙庫通過HC-05模塊與藍牙中的Arduino通信。 我們進行了一個虛擬配置來測試延遲,而無需從Arduino或應用程序進行任何計算,並且在請求和答案之間存在大約1秒的巨大延遲...

協議看起來很簡單:Android發送字節-2,如果接收到的字節為-2,則Arduino發送-6,-9,Android一次又一次地回答。

Android代碼:

h = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case RECIEVE_MESSAGE:                                                   // if receive massage
                        byte[] readBuf = (byte[]) msg.obj;

                        for(int i=0;i < readBuf.length;i++)
                        {
                            if((int) readBuf[i] != 0) {
                                txtArduino.append(String.valueOf((int) readBuf[i]) + ", ");
                            }
                        }
                        byte[] msg = {-2};
                        mConnectedThread.writeByte(msg);
                        break;
                }
            };
        };

Arduino代碼:

const int receveidBuffLen = 8*4;


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

void loop() {
    if (Serial.available() > 0) 
    {
      byte buff[receveidBuffLen];
      Serial.readBytes(buff, receveidBuffLen);

      for(int i=0; i < receveidBuffLen;i++)
      {
        if(buff[i] == (byte) -2) // 254
        {
            byte message[2] = {(byte) -6, (byte) -9};
            Serial.write(message, 2);
            Serial.flush();
        }
      }
    }
    delay(3);
}

有人知道延遲的來源嗎?

我們將HC05波特率從9600更改為115200:什么也沒發生。 我們用另一個替換了HC05:什么也沒發生。 之前我們使用Blue2Serial庫(藍牙為SPP),並且延遲相同...我們使用了另一個控制器(ESP8266),延遲仍然為1秒...

看起來這個字符串是一個問題:

Serial.readBytes(buff, receveidBuffLen);

其中receveidBuffLen為32。盡管您一次只能獲得一個字節,但是您嘗試讀取其中的32個字節。 當然,如果沒有更多字節,則代碼將一直停留到超時。

此外,在讀取字節之后,您無需檢查實際讀取了多少字節,而是從下至上掃描整個數組:

for(int i=0; i < receveidBuffLen;i++)

相反,您必須執行以下操作:

int bytesAvailable = Serial.available();
if (bytesAvailable > 0)
{
  byte buff[receveidBuffLen];
  int bytesToRead = (bytesAvailable < receveidBuffLen) ? bytesAvailable : receveidBuffLen;
  // Read no more than the buffer size, but not more than available

  int bytesActuallyRead = Serial.readBytes(buff, bytesToRead);

  for(int i=0; i < bytesActuallyRead;i++)
  ...

該代碼有幾個問題,可能會導致延遲:

  1. 循環結束時的延遲功能-這會減慢Ardunio可以跟上的處理速度
  2. 調用Serial.flush() -這將阻塞處理loop()直到內部TX串行緩沖區為空。 這意味着Arduino被阻止,新的RX數據會堆積起來,從而降低了響應時間。
  3. 調用Serial.readBytes() -您應該專注於最小的數據單元並處理每個loop()迭代。 如果您試圖在每個循環中處理多個消息,那么這將減慢循環時間,從而導致延遲。

您可以嘗試在Arduino上實現SerialEvent模式。 我們一次只會從串行緩沖區讀取一個字節,從而將loop()函數必須執行的處理保持在最低限度。 如果我們收到-2字節,我們將標記一個標志。 如果標記了該標志,則loop()函數將調用Serial.write()函數,但不會阻止數據傳輸。 這是一個簡單的例子。

bool sendMessage = false;
byte message[2] = {(byte) -6, (byte) -9};

void loop()
{
    if (sendMessage == true)
    {
        Serial.write(message, 2);
        sendMessage = false;
    }
}


/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent()
{
    while (Serial.available())
    {
        // get the new byte:
        byte inChar = ((byte) Serial.read());

        if (inChar == ((byte) -2))
        {
            sendMessage = true;
        }
    }
}

我們只是自己找到一些解決方案,並希望與他們分享:

初始情況:1050毫秒為答案。 Alls解決方案是獨立的,並已根據初始情況完成。

  • 刪除Serial.flush():1022 ms。
  • 在Arduino代碼中添加一個簡單的Serial.setTimeout(100):135毫秒。 (天啊!)
  • 在Android中的100ms的inputStream中添加一個簡單的超時 :95 ms。

我們不能說哪種解決方案是最好的,但現在可以使用...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM