Как уменьшить задержку для конкатенации строк + Arduino Due

В моем проекте мне нужно добавить разделитель между целыми числами. В следующем коде. Я добавляю "," между целыми числами, полученными из входной матрицы. Проблема в том, что объединение этих чисел с помощью команды concat() для матрицы со 100 строками и 9 столбцами занимает 10 мс. Есть ли эффективный способ уменьшить эту задержку?

#include <CStringBuilder.h>

int Max_pack_size = 100;

void setup() {
  SerialUSB.begin(115200);

  while (!SerialUSB) ;

}

void loop() {

  String  datas1;
  String  inputsig[Max_pack_size][9];
  char buff[((8+1)*Max_pack_size+1)*9];
  CStringBuilder sb(buff, ((8+1)*Max_pack_size+1)*9);

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      inputsig[i][j] = 16777215;

    }
  }


  int t0 = micros();

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      //datas1.concat(inputsig[i][j]);
      //данные1.concat(",");
  sb.print(inputsig[i][j]);
  sb.print(F(","));     
    }
  }

 SerialUSB.println(float(micros() - t0));
 delay(1000);

 SerialUSB.println(buff);

}

, 👍0

Обсуждение

Комментарии не для расширенного обсуждения; этот разговор был [перемещен в чат](https://chat.stackexchange.com/rooms/99078/discussion-on-question-by-abed-how-to-decrease-delay-for-string-concatenation)., @VE7JRO


1 ответ


1

У меня нет Arduino Due, но есть Arduino Uno, поэтому мне пришлось настроить код так, чтобы он работал с гораздо меньшей оперативной памятью и использовал стандартный последовательный порт.

Это исходный код, как видите, я могу использовать только Max_pack_size из 5

#include <CStringBuilder.h>

int Max_pack_size = 5;

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

void loop() {

  String inputsig[Max_pack_size][9];
  char buff[((8 + 1)*Max_pack_size + 1) * 9];
  CStringBuilder sb(buff, ((8 + 1)*Max_pack_size + 1) * 9);

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      inputsig[i][j] = 16777215;
    }
  }

  int t0 = micros();

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      sb.print(inputsig[i][j]);
      sb.print(',');
    }
  }

  int t1 = micros();

  Serial.println(float(t1 - t0) / 1000.0);
  delay(1000);

  Serial.println(buff);
}

Таймер отображает значения около 2,08 миллисекунд для приведенного выше кода.

Первой попыткой оптимизации является прекращение использования StringBuilder. Все, что написано, чтобы быть универсальным и простым в использовании, обычно работает медленно.

Обратите внимание, что когда мы генерируем String из long, неявное приведение выделяет char buf[2 + 3 * sizeof(long)];, поэтому максимальная длина такой строки составляет 14 символов. Строка, конечно, заканчивается нулевым символом '\0'

#include <CStringBuilder.h>

int Max_pack_size = 5;

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

void loop() {

  String inputsig[Max_pack_size][9];
  char buff[((8 + 1)*Max_pack_size + 1) * 9];

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      inputsig[i][j] = 16777215;
    }
  }

  int t0 = micros();

  int p = 0;
  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      for (int k = 0 ; k < 14; k++)
      {
        char c = inputsig[i][j][k];

        if (c == 0)
          break;
        else
          buff[p++] = c;
      }

      buff[p++] = ',';
    }
  }

  int t1 = micros();

  Serial.println(float(t1 - t0) / 1000.0);
  delay(1000);

  Serial.println(buff);
}
}

Теперь таймер показывает 0,86 миллисекунды. Намного лучше, но мы можем улучшить еще больше!

Отбросим строку. В любом случае это просто слишком сложная оболочка для массива символов.

#include <CStringBuilder.h>

int Max_pack_size = 5;

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

void loop() {

  char inputsig[Max_pack_size][9][14];
  char buff[((8 + 1)*Max_pack_size + 1) * 9];

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      ltoa(16777215, inputsig[i][j], 10);
    }
  }

  int t0 = micros();

  int p = 0;
  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      for (int k = 0 ; k < 14; k++)
      {
        char c = inputsig[i][j][k];

        if (c == 0)
          break;
        else
          buff[p++] = c;
      }

      buff[p++] = ',';
    }
  }

  int t1 = micros();

  Serial.println(float(t1 - t0) / 1000.0);
  delay(1000);

  Serial.println(buff);
}

Теперь таймер показывает 0,50 миллисекунды. Поэтому мы оптимизировали код, чтобы он работал в 4 раза быстрее.

,

Смерть Филип. Спасибо за вашу помощь. Я проверил это и смог уменьшить задержку до 2 мс., @Abed