0

In my project I need to add a delimiter between integer numbers. In the following code. I add a "," between integer numbers obtained from inputsig matrix. The problem is that concatenation of these numbers with concat() command for a Matrix with 100 rows and 9 columns takes 10 ms. Is there any efficient way to decrease this delay?

#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]);
      //datas1.concat(",");
  sb.print(inputsig[i][j]);
  sb.print(F(","));     
    }
  }

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

 SerialUSB.println(buff);

}
1
  • Comments are not for extended discussion; this conversation has been moved to chat. – VE7JRO Sep 25 '19 at 5:38
1

I don't have Arduino Due but I have an Arduino Uno so I had to adjust the code to run with much smaller RAM and use the standard Serial.

This is the original code as you can see i can use only Max_pack_size of 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);
}

The timer displays values around 2.08 milliseconds for the code above.

First optimization attempts is to stop using StringBuilder. Everything that's written to be universal and easy to use is usually slow.

Note that when we generate String from long the implicit cast allocates char buf[2 + 3 * sizeof(long)]; so the max length of such string is 14 characters. String is of course terminated by null character '\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);
}
}

Now the timer displays 0.86 milliseconds. Much better, but we can improve even more!

Let's drop the String. It's just an over complicated wrapper for a char array anyway.

#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);
}

Now the timer shows 0.50 milliseconds. So we optimized the code to the point it runs 4 times as fast.

1
  • Deat Filip. Thanks for your help. I tested this and could decrease the delay to 2ms. – Abed Sep 26 '19 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.