Pages: [1]   Go Down
Author Topic: String += not working  (Read 426 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

could someone please test this code on his arduino. It hangs on mine (Arduino Mega2560 R2).

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

void loop() {

  const String args[3] = {
    "foo", "boo", "baa"    };
  String result = "";
  Serial.println(result);
  result += args[0];
  Serial.println(result);
  result += args[1];
  Serial.println(result);
  result += args[2];
  Serial.println(result);
  Serial.println();
}

That codes hangs after a few seconds. BUT if you replace the
result +=
with
result = result +

everything works fine.
I wonder, as http://arduino.cc/en/Tutorial/StringAppendOperator shows that using += ist OK

regards
Mirko

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried a few more string-things and had strange results. Can someone confirm that code below, or is that a problem of my arduino?
(Uncomment only one of the lines in the source)

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

void loop()
{
  String str = ""; 
  for (int i=0; i<30; i++)
  {
    str = String(str +String(i,DEC));  // works fine
//    str = str +String(i,DEC);  // works fine
//    str = String(str) +String(i,DEC);  // crashes
//    str = String(str+ "-" +String(i,DEC)); // crashes
//    str = String(String(str) +String(i,DEC));  // crashes
//    str = str + "-" +String(i,DEC);  // crashes
    Serial.println(str);
  }
}
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 147
Posts: 6040
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
char outBuf[64];

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

void loop()
{
  for (int i=0; i<30; i++)
  {
      sprintf(outBuf,"This always works: %d",i);
      Serial.println(outBuf);
  }
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, nice workearound, but does not explain why the above crashes or freezes the arduino.
Logged

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 147
Posts: 6040
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One is addition (byte, integer, long). The other is concatenation (string).

It would appear the "+=" does not work with concatenation, only addition.
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you look at WString.cpp in the Arduino core files, you will see that concatenation using += is implemented as concatenation.   

It works by allocating a buffer large enough to contain the old + new string, then cating it.  This appears to lead to memory fragmentation on ATmegas limited memory and stack environment.

Your workaround works or just treating all Strings as character arrays instead.  This results in much lower over head.  It does require you, as the programmer, to determine ahead of time what size the arrays should be.  Which, in such a limited memory environment, is actually a good idea.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After changing my code not to use the String class anymore but use char arrays, i ran into another problem

Code:
void loop()
{
  char tx[100];
  long TestA = 1;
  word TestB = 1;
 
  sprintf (tx, "%d %d %d %d", TestA, 2, 3, 4);
  Serial.println(tx);

  sprintf (tx, "%d %d %d %d", TestB, 2, 3, 4);
  Serial.println(tx);
}

I would have expected the to outputs to be the same, but they are not.
It outputs the following two lines:

1 0 2 3
1 2 3 4

Can anybody explain this to me?
Isn't it possible to use a long or unsigned long with sprintf?

regards
Mirko



Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

%d   is an int
%ld  is a long int

http://www.cplusplus.com/reference/clibrary/cstdio/printf/
« Last Edit: December 07, 2011, 09:35:18 am by James C4S » Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, thanx for that info.
I did not know that as i never needed %ld before ;-)

regards
Mirko
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In that case, you should know that

%u is unsigned int
%lu is unsigned long
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Pages: [1]   Go Up
Jump to: