[英]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++)
...
該代碼有幾個問題,可能會導致延遲:
loop()
直到內部TX串行緩沖區為空。 這意味着Arduino被阻止,新的RX數據會堆積起來,從而降低了響應時間。 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解決方案是獨立的,並已根據初始情況完成。
我們不能說哪種解決方案是最好的,但現在可以使用...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.