Arduino / Android Bluetooth задержка - PullRequest
0 голосов
/ 01 сентября 2018

Мы разрабатываем приложение, которое использует библиотеку Bluetooth для связи с Arduino через Bluetooth через модуль HC-05. Мы создали фиктивную конфигурацию для проверки задержки без каких-либо вычислений от 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 до 115 200): ничего не произошло. Мы поменяли HC05 на другой: ничего не произошло. Мы использовали библиотеку Blue2Serial (Bluetooth как SPP) раньше, и задержка была такой же ... Мы использовали другой контроллер (ESP8266), и задержка все еще составляла 1 секунду ...

Ответы [ 3 ]

0 голосов
/ 02 сентября 2018

Мы сами находим некоторые решения и хотим поделиться ими:

Исходная ситуация: 1050 мс для ответа. Все решения независимы и сделаны с исходной ситуацией.

  • Удалить Serial.flush (): 1022 мс.
  • Добавьте простой Serial.setTimeout (100) в Arduino Code: 135 мс. (О человек!)
  • Добавление простого таймаута для inputStream в 100 мс в Android: 95 мс.

Какое решение лучше, мы не можем сказать, но оно работает сейчас ...

0 голосов
/ 03 сентября 2018

Похоже, эта строка является проблемой:

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++)
  ...
0 голосов
/ 02 сентября 2018

Есть пара проблем с кодом, которые могут вызвать задержки:

  1. задержка функция в конце цикла - Это замедлит обработку, которую Ardunio может поспевать за
  2. Вызов Serial.flush () - Это заблокирует обработку loop(), пока внутренний последовательный буфер TX не опустеет. Это означает, что Arduino заблокирован, и новые данные RX могут накапливаться, замедляя время отклика.
  3. Вызов Serial.readBytes () - Вы должны сосредоточиться на наименьшей единице данных и обрабатывать каждую итерацию loop(). Если вы пытаетесь обработать несколько сообщений в цикле, это замедлит время цикла, что приведет к задержке.

Вы можете попробовать реализовать шаблон SerialEvent на 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;
        }
    }
}
...