Arduino/Android蓝牙延迟

Arduino/Android蓝牙延迟,android,bluetooth,arduino,delay,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.

我们正在开发一个应用程序,使用蓝牙库通过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;
                }
            };
        };
h=newhandler(){
public void handleMessage(android.os.Message msg){
开关(msg.what){
案例接收信息://如果接收按摩
字节[]readBuf=(字节[])msg.obj;
for(int i=0;i
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);
}
const int receiveidbufflen=8*4;
无效设置(){
序列号开始(115200);
}
void循环(){
如果(Serial.available()>0)
{
字节buff[receiveidbufflen];
Serial.readBytes(buff,receiveidbufflen);
对于(int i=0;i
有人知道延迟是从哪里来的吗


我们更改了HC05波特率(从9600更改为115200):什么也没发生。我们用另一个换了HC05:什么也没发生。我们以前使用过Blue2串行库(Bluetooth作为SPP),延迟是一样的。。。我们使用了另一个控制器(ESP8266),延迟仍然是1秒…

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

  • 循环结束时的函数-这将减慢Ardunio可以跟上的处理速度
  • 调用-这将阻止处理
    循环()
    ,直到内部TX串行缓冲区为空。这意味着Arduino被阻塞,新的接收数据会堆积起来,从而减慢响应时间
  • 调用-您应该关注每个
    loop()
    迭代所需的最小数据和处理单元。如果您试图处理每个循环的多条消息,那么现在将减慢循环时间,从而导致延迟
  • 您可以尝试在Arduino上实现一个模式。我们一次只从串行缓冲区读取一个字节,将
    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;
            }
        }
    }
    

    代码中有几个问题可能会导致延迟:

  • 循环结束时的函数-这将减慢Ardunio可以跟上的处理速度
  • 调用-这将阻止处理
    循环()
    ,直到内部TX串行缓冲区为空。这意味着Arduino被阻塞,新的接收数据会堆积起来,从而减慢响应时间
  • 调用-您应该关注每个
    loop()
    迭代所需的最小数据和处理单元。如果您试图处理每个循环的多条消息,那么现在将减慢循环时间,从而导致延迟
  • 您可以尝试在Arduino上实现一个模式。我们一次只从串行缓冲区读取一个字节,将
    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毫秒获得答案。所有解决方案都是独立的,都是在初始情况下完成的

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

    哪种解决方案是最好的,我们不能说,但它现在起作用了…

    我们只是自己找到一些解决方案,并想与大家分享:

    初始情况:1050毫秒获得答案。所有解决方案都是独立的,都是在初始情况下完成的

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

    哪种解决方案是最好的,我们不能说,但它现在可以工作了…

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

    Serial.readBytes(buff, receveidBuffLen);
    
    其中,
    receiveidbufflen
    为32。 虽然一次只能读取一个字节,但您试图读取其中的32个字节。当然,如果没有更多的字节,代码将一直保留到超时

    此外,读取字节后,您永远不会检查实际读取了多少字节,而是从下到上扫描整个阵列:

    for(int i=0; i < receveidBuffLen;i++)
    
    for(int i=0;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++)
      ...
    
    int bytesavable=Serial.available();
    如果(字节可用>0)
    {
    字节buff[receiveidbufflen];
    int bytesToRead=(bytesavable
    看起来像这样