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);
}
-
Comments are not for extended discussion; this conversation has been moved to chat.VE7JRO– VE7JRO09/25/2019 05:38:14Commented Sep 25, 2019 at 5:38
1 Answer 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.
-
Deat Filip. Thanks for your help. I tested this and could decrease the delay to 2ms.Abed– Abed09/26/2019 12:59:38Commented Sep 26, 2019 at 12:59