Arduino / Android蓝牙延迟

时间:2018-09-01 16:01:37

标签: android bluetooth arduino 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库(Bluetooth为SPP),并且延迟是相同的...我们使用了另一个控件(ESP8266),延迟仍然是1秒...

3 个答案:

答案 0 :(得分:2)

看起来像这个字符串是个问题:

receveidBuffLen

其中for(int i=0; i < receveidBuffLen;i++) 是32。 尽管一次只能获取一个字节,但是您尝试读取其中的32个字节。当然,如果没有更多字节,则代码将一直停留到超时。

此外,在读取字节之后,您无需检查实际读取了多少字节,而是从下到上扫描整个数组:

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++)
  ...

相反,您必须执行以下操作:

<?=form_radio('filter', 'y', $info['enable_categories'] == 'y' ? true : false, 'id="app" '.APP_NAME == "test" ? '' : 'disabled'.'')?>

答案 1 :(得分:0)

该代码存在一些可能导致延迟的问题:

  1. delay函数在循环结束时-这会减慢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;
        }
    }
}

答案 2 :(得分:0)

我们只是自己找到一些解决方案,并希望与他们分享:

初始情况:1050毫秒为答案。 Alls解决方案是独立的,并已根据初始情况完成了。

  • 删除Serial.flush():1022毫秒。
  • 在Arduino代码中添加一个简单的Serial.setTimeout(100):135毫秒。 (哦,伙计!)
  • 在Android中添加100ms的简单timeout to inputStream:95 ms。

哪种解决方案是最好的,我们不能说,但是现在可以使用...